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();
 }

Reply via email to