kernel - Fix races created by a comedy of circumstansces (3)
[dragonfly.git] / test / sysperf / umtx1.c
blob786954754a6fede3756984cf8750477786a628d0
1 /*
2 * umtx1.c
3 */
5 #include <sys/types.h>
6 #include <sys/wait.h>
7 #include <sys/errno.h>
8 #include <pthread.h>
9 #include <machine/cpufunc.h>
10 #include <machine/atomic.h>
11 #include "blib.h"
13 static void *do_child(void *arg);
14 static void *do_parent(void *arg);
16 u_int mtx;
17 u_long total;
19 int
20 main(int ac, char **av)
22 pthread_t td1;
23 pthread_t td2;
24 int n;
25 int k;
26 int status;
28 printf("tests umtx hand-off loop\n");
29 for (n = 1; n; --n) {
30 if (fork() == 0) {
31 start_timing();
32 for (k = 0; k < 10; ++k) {
33 pthread_create(&td1, NULL, do_child, NULL);
34 pthread_create(&td2, NULL, do_parent, NULL);
35 pthread_join(td2, NULL);
36 pthread_join(td1, NULL);
38 stop_timing(total, "total");
39 _exit(0);
42 while (wait3(&status, 0, NULL) <= 0 || errno == EINTR)
45 return 0;
48 static
49 void *
50 do_child(void *arg __unused)
52 for (;;) {
53 while (mtx == 0)
54 umtx_sleep(&mtx, 0, 0);
55 if (atomic_swap_int(&mtx, 0) == 2) {
56 umtx_wakeup(&mtx, 0);
57 pthread_yield();
58 break;
60 umtx_wakeup(&mtx, 0);
62 return NULL;
65 static
66 void *
67 do_parent(void *arg __unused)
69 int j;
70 int loops;
72 for (j = 0; j < 1000000; ++j) {
73 atomic_swap_int(&mtx, 1);
74 umtx_wakeup(&mtx, 0);
75 pthread_yield();
76 while (mtx == 1)
77 umtx_sleep(&mtx, 1, 0);
79 start_timing();
80 for (j = 0; j < 1000000; ++j) {
81 atomic_swap_int(&mtx, 1);
82 umtx_wakeup(&mtx, 0);
83 while (mtx == 1)
84 umtx_sleep(&mtx, 1, 0);
86 stop_timing(j, "mtx1");
87 atomic_add_long(&total, j * 2);
89 atomic_swap_int(&mtx, 2);
90 umtx_wakeup(&mtx, 0);
91 while (mtx == 2)
92 umtx_sleep(&mtx, 2, 0);
94 return NULL;