Module Name: src
Committed By: thorpej
Date: Mon May 4 15:09:34 UTC 2020
Modified Files:
src/tests/lib/libc/sys: t_futex_ops.c
Log Message:
Add a test case for PR kern/55230. It is currently marked as expect-fail.
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/tests/lib/libc/sys/t_futex_ops.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/tests/lib/libc/sys/t_futex_ops.c
diff -u src/tests/lib/libc/sys/t_futex_ops.c:1.3 src/tests/lib/libc/sys/t_futex_ops.c:1.4
--- src/tests/lib/libc/sys/t_futex_ops.c:1.3 Thu Apr 30 04:18:07 2020
+++ src/tests/lib/libc/sys/t_futex_ops.c Mon May 4 15:09:34 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: t_futex_ops.c,v 1.3 2020/04/30 04:18:07 thorpej Exp $ */
+/* $NetBSD: t_futex_ops.c,v 1.4 2020/05/04 15:09:34 thorpej Exp $ */
/*-
* Copyright (c) 2019, 2020 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
#include <sys/cdefs.h>
__COPYRIGHT("@(#) Copyright (c) 2019, 2020\
The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: t_futex_ops.c,v 1.3 2020/04/30 04:18:07 thorpej Exp $");
+__RCSID("$NetBSD: t_futex_ops.c,v 1.4 2020/05/04 15:09:34 thorpej Exp $");
#include <sys/fcntl.h>
#include <sys/mman.h>
@@ -42,6 +42,7 @@ __RCSID("$NetBSD: t_futex_ops.c,v 1.3 20
#include <signal.h>
#include <time.h>
#include <limits.h>
+#include <sched.h>
#include <unistd.h>
#include <atf-c.h>
@@ -1334,6 +1335,152 @@ ATF_TC_CLEANUP(futex_wait_evil_unmapped_
/*****************************************************************************/
+static int pri_min;
+static int pri_max;
+
+static void
+lowpri_simple_test_waiter_lwp(void *arg)
+{
+ struct lwp_data *d = arg;
+ struct sched_param sp;
+ int policy;
+
+ d->threadid = _lwp_self();
+
+ ATF_REQUIRE(_sched_getparam(getpid(), d->threadid, &policy, &sp) == 0);
+ policy = SCHED_RR;
+ sp.sched_priority = pri_min;
+ ATF_REQUIRE(_sched_setparam(getpid(), d->threadid, policy, &sp) == 0);
+
+ simple_test_waiter_lwp(arg);
+}
+
+static void
+highpri_simple_test_waiter_lwp(void *arg)
+{
+ struct lwp_data *d = arg;
+ struct sched_param sp;
+ int policy;
+
+ d->threadid = _lwp_self();
+
+ ATF_REQUIRE(_sched_getparam(getpid(), d->threadid, &policy, &sp) == 0);
+ policy = SCHED_RR;
+ sp.sched_priority = pri_max;
+ ATF_REQUIRE(_sched_setparam(getpid(), d->threadid, policy, &sp) == 0);
+
+ simple_test_waiter_lwp(arg);
+}
+
+static void
+do_test_wake_highest_pri(void)
+{
+ lwpid_t waiter;
+ int tries;
+ long pri;
+
+ ATF_REQUIRE((pri = sysconf(_SC_SCHED_PRI_MIN)) != -1);
+ pri_min = (int)pri;
+ ATF_REQUIRE((pri = sysconf(_SC_SCHED_PRI_MAX)) != -1);
+ pri_max = (int)pri;
+
+ futex_word = 0;
+ membar_sync();
+
+ setup_lwp_context(&lwp_data[0], lowpri_simple_test_waiter_lwp);
+ lwp_data[0].op_flags = FUTEX_PRIVATE_FLAG;
+ lwp_data[0].futex_error = -1;
+ lwp_data[0].futex_ptr = &futex_word;
+ lwp_data[0].block_val = 0;
+ lwp_data[0].bitset = 0;
+ lwp_data[0].wait_op = FUTEX_WAIT;
+ ATF_REQUIRE(_lwp_create(&lwp_data[0].context, 0,
+ &lwp_data[0].lwpid) == 0);
+
+ for (tries = 0; tries < 5; tries++) {
+ membar_sync();
+ if (nlwps_running == 1)
+ break;
+ sleep(1);
+ }
+ membar_sync();
+ ATF_REQUIRE_EQ_MSG(nlwps_running, 1, "lowpri waiter failed to start");
+
+ /* Ensure it's blocked. */
+ ATF_REQUIRE(lwp_data[0].futex_error == -1);
+
+ setup_lwp_context(&lwp_data[1], highpri_simple_test_waiter_lwp);
+ lwp_data[1].op_flags = FUTEX_PRIVATE_FLAG;
+ lwp_data[1].futex_error = -1;
+ lwp_data[1].futex_ptr = &futex_word;
+ lwp_data[1].block_val = 0;
+ lwp_data[1].bitset = 0;
+ lwp_data[1].wait_op = FUTEX_WAIT;
+ ATF_REQUIRE(_lwp_create(&lwp_data[0].context, 0,
+ &lwp_data[0].lwpid) == 0);
+
+ for (tries = 0; tries < 5; tries++) {
+ membar_sync();
+ if (nlwps_running == 2)
+ break;
+ sleep(1);
+ }
+ membar_sync();
+ ATF_REQUIRE_EQ_MSG(nlwps_running, 2, "highpri waiter failed to start");
+
+ /* Ensure it's blocked. */
+ ATF_REQUIRE(lwp_data[1].futex_error == -1);
+
+ /* Wake the first LWP. We should get the highpri thread. */
+ ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE | FUTEX_PRIVATE_FLAG,
+ 1, NULL, NULL, 0, 0) == 1);
+ sleep(1);
+ for (tries = 0; tries < 5; tries++) {
+ membar_sync();
+ if (nlwps_running == 1)
+ break;
+ sleep(1);
+ }
+ membar_sync();
+ ATF_REQUIRE(nlwps_running == 1);
+ ATF_REQUIRE(_lwp_wait(0, &waiter) == 0);
+ ATF_REQUIRE(waiter == lwp_data[1].threadid);
+
+ /* Wake the second LWP. We should get the lowpri thread. */
+ ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE | FUTEX_PRIVATE_FLAG,
+ 1, NULL, NULL, 0, 0) == 1);
+ sleep(1);
+ for (tries = 0; tries < 5; tries++) {
+ membar_sync();
+ if (nlwps_running == 0)
+ break;
+ sleep(1);
+ }
+ membar_sync();
+ ATF_REQUIRE(nlwps_running == 0);
+ ATF_REQUIRE(_lwp_wait(0, &waiter) == 0);
+ ATF_REQUIRE(waiter == lwp_data[0].threadid);
+}
+
+ATF_TC_WITH_CLEANUP(futex_wake_highest_pri);
+ATF_TC_HEAD(futex_wake_highest_pri, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "tests that futex WAKE wakes the highest priority waiter");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(futex_wake_highest_pri, tc)
+{
+ atf_tc_expect_fail("PR kern/55230");
+ do_test_wake_highest_pri();
+}
+ATF_TC_CLEANUP(futex_wake_highest_pri, tc)
+{
+ do_cleanup();
+}
+
+/*****************************************************************************/
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, futex_basic_wait_wake_private);
@@ -1364,5 +1511,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, futex_wake_op_op);
ATF_TP_ADD_TC(tp, futex_wake_op_cmp);
+ ATF_TP_ADD_TC(tp, futex_wake_highest_pri);
+
return atf_no_error();
}