test - Add umtx1 code
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 27 Jul 2016 18:22:56 +0000 (11:22 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 27 Jul 2016 18:22:56 +0000 (11:22 -0700)
* Add umtx1 code - fast context switch tests

* Make blib.c thread-safe.

test/sysperf/Makefile
test/sysperf/blib.c
test/sysperf/umtx1.c [new file with mode: 0644]

index eae531a..7ebf953 100644 (file)
@@ -2,7 +2,8 @@ TARGETS=/tmp/sc1 /tmp/sc2 /tmp/sc3 /tmp/sc4 /tmp/sc5 /tmp/sc6 /tmp/sc7 \
        /tmp/loop1 /tmp/loop2 /tmp/loop3 /tmp/loop4 \
        /tmp/call1 /tmp/call2 /tmp/call3 /tmp/cmp \
        /tmp/mt2 /tmp/mt3 /tmp/mt4 \
-       /tmp/fork1 /tmp/pipe1 /tmp/pipe2 \
+       /tmp/fork1 /tmp/pipe1 /tmp/pipe2 /tmp/pipe3 \
+       /tmp/umtx1 \
        /tmp/sp1 \
        /tmp/sw1 /tmp/sw2 /tmp/sw3 \
        /tmp/mbw1 \
@@ -53,6 +54,12 @@ all: $(TARGETS)
 /tmp/pipe2: pipe2.c blib.c
        $(CC) $(CFLAGS) pipe2.c blib.c -o /tmp/pipe2
 
+/tmp/pipe3: pipe3.c blib.c
+       $(CC) $(CFLAGS) pipe3.c blib.c -pthread -o /tmp/pipe3
+
+/tmp/umtx1: umtx1.c blib.c
+       $(CC) $(CFLAGS) umtx1.c blib.c -pthread -o /tmp/umtx1
+
 /tmp/sp1: socketpair.c blib.c
        $(CC) $(CFLAGS) socketpair.c blib.c -o /tmp/sp1
 
index 99ff282..6539ecc 100644 (file)
@@ -12,9 +12,9 @@
 #include <stdlib.h>
 #include <stdarg.h>
 
-static struct timeval tv1;
-static struct timeval tv2;
-static long long last_us;
+static __thread struct timeval tv1;
+static __thread struct timeval tv2;
+static __thread long long last_us;
 
 void
 start_timing(void)
diff --git a/test/sysperf/umtx1.c b/test/sysperf/umtx1.c
new file mode 100644 (file)
index 0000000..7869547
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * umtx1.c
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/errno.h>
+#include <pthread.h>
+#include <machine/cpufunc.h>
+#include <machine/atomic.h>
+#include "blib.h"
+
+static void *do_child(void *arg);
+static void *do_parent(void *arg);
+
+u_int mtx;
+u_long total;
+
+int
+main(int ac, char **av)
+{
+       pthread_t td1;
+       pthread_t td2;
+       int n;
+       int k;
+       int status;
+
+       printf("tests umtx hand-off loop\n");
+       for (n = 1; n; --n) {
+               if (fork() == 0) {
+                       start_timing();
+                       for (k = 0; k < 10; ++k) {
+                               pthread_create(&td1, NULL, do_child, NULL);
+                               pthread_create(&td2, NULL, do_parent, NULL);
+                               pthread_join(td2, NULL);
+                               pthread_join(td1, NULL);
+                       }
+                       stop_timing(total, "total");
+                       _exit(0);
+               }
+       }
+       while (wait3(&status, 0, NULL) <= 0 || errno == EINTR)
+               ;
+
+       return 0;
+}
+
+static
+void *
+do_child(void *arg __unused)
+{
+       for (;;) {
+               while (mtx == 0)
+                       umtx_sleep(&mtx, 0, 0);
+               if (atomic_swap_int(&mtx, 0) == 2) {
+                       umtx_wakeup(&mtx, 0);
+                       pthread_yield();
+                       break;
+               }
+               umtx_wakeup(&mtx, 0);
+       }
+       return NULL;
+}
+
+static
+void *
+do_parent(void *arg __unused)
+{
+       int j;
+       int loops;
+
+       for (j = 0; j < 1000000; ++j) {
+               atomic_swap_int(&mtx, 1);
+               umtx_wakeup(&mtx, 0);
+               pthread_yield();
+               while (mtx == 1)
+                       umtx_sleep(&mtx, 1, 0);
+       }
+       start_timing();
+       for (j = 0; j < 1000000; ++j) {
+               atomic_swap_int(&mtx, 1);
+               umtx_wakeup(&mtx, 0);
+               while (mtx == 1)
+                       umtx_sleep(&mtx, 1, 0);
+       }
+       stop_timing(j, "mtx1");
+       atomic_add_long(&total, j * 2);
+
+       atomic_swap_int(&mtx, 2);
+       umtx_wakeup(&mtx, 0);
+       while (mtx == 2)
+               umtx_sleep(&mtx, 2, 0);
+
+       return NULL;
+}