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