rc: Move stop_boot() from rc.d/fsck to rc.subr and improve it
[dragonfly.git] / test / sysperf / umtx1.c
1 /*
2  * umtx1.c
3  */
4
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"
12
13 static void *do_child(void *arg);
14 static void *do_parent(void *arg);
15
16 u_int mtx;
17 u_long total;
18
19 int
20 main(int ac, char **av)
21 {
22         pthread_t td1;
23         pthread_t td2;
24         int n;
25         int k;
26         int status;
27
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);
37                         }
38                         stop_timing(total, "total");
39                         _exit(0);
40                 }
41         }
42         while (wait3(&status, 0, NULL) <= 0 || errno == EINTR)
43                 ;
44
45         return 0;
46 }
47
48 static
49 void *
50 do_child(void *arg __unused)
51 {
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;
59                 }
60                 umtx_wakeup(&mtx, 0);
61         }
62         return NULL;
63 }
64
65 static
66 void *
67 do_parent(void *arg __unused)
68 {
69         int j;
70         int loops;
71
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);
78         }
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);
85         }
86         stop_timing(j, "mtx1");
87         atomic_add_long(&total, j * 2);
88
89         atomic_swap_int(&mtx, 2);
90         umtx_wakeup(&mtx, 0);
91         while (mtx == 2)
92                 umtx_sleep(&mtx, 2, 0);
93
94         return NULL;
95 }