Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/thorpej-futex]: src/tests/lib/libc/sys - Re-factor the code that sets up...
details: https://anonhg.NetBSD.org/src/rev/e3343ca04f38
branches: thorpej-futex
changeset: 961118:e3343ca04f38
user: thorpej <thorpej%NetBSD.org@localhost>
date: Sun Nov 01 15:22:58 2020 +0000
description:
- Re-factor the code that sets up real-time LWPs for various tests.
- Add tests for the RW_HANDOFF operations.
diffstat:
tests/lib/libc/sys/t_futex_ops.c | 919 ++++++++++++++++++++++++++++++++++++--
1 files changed, 870 insertions(+), 49 deletions(-)
diffs (truncated from 1012 to 300 lines):
diff -r dfde61bc09aa -r e3343ca04f38 tests/lib/libc/sys/t_futex_ops.c
--- a/tests/lib/libc/sys/t_futex_ops.c Sun Nov 01 15:16:43 2020 +0000
+++ b/tests/lib/libc/sys/t_futex_ops.c Sun Nov 01 15:22:58 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: t_futex_ops.c,v 1.5 2020/05/06 05:14:27 thorpej Exp $ */
+/* $NetBSD: t_futex_ops.c,v 1.5.2.1 2020/11/01 15:22:58 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.5 2020/05/06 05:14:27 thorpej Exp $");
+__RCSID("$NetBSD: t_futex_ops.c,v 1.5.2.1 2020/11/01 15:22:58 thorpej Exp $");
#include <sys/fcntl.h>
#include <sys/mman.h>
@@ -78,6 +78,7 @@
volatile int *futex_ptr;
volatile int *error_ptr;
int block_val;
+ pri_t rt_prio;
void (*exit_func)(void);
@@ -101,6 +102,20 @@
static void *bs_verify_buffer = NULL;
static long bs_pagesize;
+static int pri_min;
+static int pri_max;
+
+static void
+setup_rt_params(void)
+{
+ 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;
+}
+
static void
create_lwp_waiter(struct lwp_data *d)
{
@@ -188,6 +203,23 @@
_lwp_exit();
}
+static void
+rt_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 = d->rt_prio;
+ ATF_REQUIRE(_sched_setparam(getpid(), d->threadid, policy, &sp) == 0);
+
+ simple_test_waiter_lwp(arg);
+}
+
static bool
verify_zero_bs(void)
{
@@ -826,7 +858,7 @@
/* Move all waiters from 0 to 1. */
ATF_REQUIRE(__futex(&futex_word, op | flags,
- 0, NULL, &futex_word1, INT_MAX, good_val3) == 0);
+ 0, NULL, &futex_word1, INT_MAX, good_val3) == 4);
/*
* FUTEX 0: 0 LWPs
@@ -847,7 +879,7 @@
/* Wake one waiter on 1, move one waiter to 0. */
ATF_REQUIRE(__futex(&futex_word1, op | flags,
- 1, NULL, &futex_word, 1, good_val3) == 1);
+ 1, NULL, &futex_word, 1, good_val3) == 2);
/*
* FUTEX 0: 1 LWP
@@ -1335,59 +1367,19 @@
/*****************************************************************************/
-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;
+ setup_rt_params();
futex_word = 0;
membar_sync();
- setup_lwp_context(&lwp_data[0], lowpri_simple_test_waiter_lwp);
+ setup_lwp_context(&lwp_data[0], rt_simple_test_waiter_lwp);
+ lwp_data[0].rt_prio = pri_min;
lwp_data[0].op_flags = FUTEX_PRIVATE_FLAG;
lwp_data[0].futex_error = -1;
lwp_data[0].futex_ptr = &futex_word;
@@ -1409,7 +1401,8 @@
/* Ensure it's blocked. */
ATF_REQUIRE(lwp_data[0].futex_error == -1);
- setup_lwp_context(&lwp_data[1], highpri_simple_test_waiter_lwp);
+ setup_lwp_context(&lwp_data[1], rt_simple_test_waiter_lwp);
+ lwp_data[1].rt_prio = pri_max;
lwp_data[1].op_flags = FUTEX_PRIVATE_FLAG;
lwp_data[1].futex_error = -1;
lwp_data[1].futex_ptr = &futex_word;
@@ -1471,7 +1464,6 @@
}
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)
@@ -1481,6 +1473,828 @@
/*****************************************************************************/
+static void
+do_test_rw_handoff_read(void)
+{
+ int i, tries;
+ int rv;
+
+ futex_word = FUTEX_WAITERS;
+ membar_sync();
+
+ for (i = 0; i < 3; i++) {
+ setup_lwp_context(&lwp_data[i], simple_test_waiter_lwp);
+ lwp_data[i].op_flags = FUTEX_PRIVATE_FLAG;
+ lwp_data[i].futex_error = -1;
+ lwp_data[i].futex_ptr = &futex_word;
+ lwp_data[i].block_val = futex_word;
+ lwp_data[i].bitset = FUTEX_RW_READER;
+ lwp_data[i].wait_op = FUTEX_NETBSD_RW_WAIT;
+ ATF_REQUIRE(_lwp_create(&lwp_data[i].context, 0,
+ &lwp_data[i].lwpid) == 0);
+ }
+
+ for (tries = 0; tries < 5; tries++) {
+ membar_sync();
+ if (nlwps_running == 3)
+ break;
+ sleep(1);
+ }
+ membar_sync();
+
+ ATF_REQUIRE_EQ_MSG(nlwps_running, 3, "read-waiters failed to start");
+
+ /* Ensure they're all blocked. */
+ ATF_REQUIRE(lwp_data[0].futex_error == -1);
+ ATF_REQUIRE(lwp_data[1].futex_error == -1);
+ ATF_REQUIRE(lwp_data[2].futex_error == -1);
+
+ /* Ensure a regular wake errors out. */
+ rv = __futex(&futex_word,
+ FUTEX_WAKE | FUTEX_PRIVATE_FLAG, INT_MAX, NULL,
+ NULL, 0, 0);
+ ATF_REQUIRE(rv == -1 && errno == EINVAL);
+
+ /*
+ * Issue a hand-off. It should wake all 3 readers and update
+ * the futex word.
+ */
+ ATF_REQUIRE(__futex(&futex_word,
+ FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
+ FUTEX_WAITERS, NULL, NULL, 0, 0) == 3);
+ ATF_REQUIRE(futex_word == 3);
+
+ for (tries = 0; tries < 5; tries++) {
+ membar_sync();
+ if (nlwps_running == 0)
+ break;
+ sleep(1);
+ }
+ membar_sync();
+ ATF_REQUIRE_EQ_MSG(nlwps_running, 0, "read-waiters failed to exit");
+
+ /* Ensure they all exited error-free. */
+ ATF_REQUIRE(lwp_data[0].futex_error == 0);
+ reap_lwp_waiter(&lwp_data[0]);
+
+ ATF_REQUIRE(lwp_data[1].futex_error == 0);
+ reap_lwp_waiter(&lwp_data[1]);
+
+ ATF_REQUIRE(lwp_data[2].futex_error == 0);
+ reap_lwp_waiter(&lwp_data[2]);
+}
+
+ATF_TC_WITH_CLEANUP(futex_rw_handoff_read);
+ATF_TC_HEAD(futex_rw_handoff_read, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "tests rwlock direct hand-off to readers");
+}
+ATF_TC_BODY(futex_rw_handoff_read, tc)
+{
+ atf_tc_skip("futex_rw_handoff is currently broken");
+ do_test_rw_handoff_read();
+}
+ATF_TC_CLEANUP(futex_rw_handoff_read, tc)
+{
+ do_cleanup();
+}
+
+/*****************************************************************************/
+
+static void
+do_test_rw_handoff_write(void)
+{
+ unsigned int i, tries;
+ lwpid_t lid;
+
+ /*
+ * The kernel should not care about the WRITE_WANTED bit, and
+ * should use the contents of the sleepqs as the truth.
+ */
+ futex_word = FUTEX_WAITERS;
+ membar_sync();
+
+ for (i = 0; i < 3; i++) {
+ setup_lwp_context(&lwp_data[i], simple_test_waiter_lwp);
+ lwp_data[i].op_flags = FUTEX_PRIVATE_FLAG;
+ lwp_data[i].futex_error = -1;
+ lwp_data[i].futex_ptr = &futex_word;
+ lwp_data[i].block_val = futex_word;
+ lwp_data[i].bitset = FUTEX_RW_WRITER;
+ lwp_data[i].wait_op = FUTEX_NETBSD_RW_WAIT;
+ ATF_REQUIRE(_lwp_create(&lwp_data[i].context, 0,
+ &lwp_data[i].lwpid) == 0);
+
+ /*
+ * Wait for each one to start in-turn, because we want
+ * to know the order in which the LWPs block on the futex.
+ */
+ for (tries = 0; tries < 5; tries++) {
+ membar_sync();
+ if (nlwps_running == i + 1)
+ break;
+ sleep(1);
+ }
+ membar_sync();
+ }
+
Home |
Main Index |
Thread Index |
Old Index