xref: /dflybsd-src/test/sysperf/umtx1.c (revision a33ac1617acc4c9c84d2014abcf9a1a7f05a34c9)
1*a33ac161SMatthew Dillon /*
2*a33ac161SMatthew Dillon  * umtx1.c
3*a33ac161SMatthew Dillon  */
4*a33ac161SMatthew Dillon 
5*a33ac161SMatthew Dillon #include <sys/types.h>
6*a33ac161SMatthew Dillon #include <sys/wait.h>
7*a33ac161SMatthew Dillon #include <sys/errno.h>
8*a33ac161SMatthew Dillon #include <pthread.h>
9*a33ac161SMatthew Dillon #include <machine/cpufunc.h>
10*a33ac161SMatthew Dillon #include <machine/atomic.h>
11*a33ac161SMatthew Dillon #include "blib.h"
12*a33ac161SMatthew Dillon 
13*a33ac161SMatthew Dillon static void *do_child(void *arg);
14*a33ac161SMatthew Dillon static void *do_parent(void *arg);
15*a33ac161SMatthew Dillon 
16*a33ac161SMatthew Dillon u_int mtx;
17*a33ac161SMatthew Dillon u_long total;
18*a33ac161SMatthew Dillon 
19*a33ac161SMatthew Dillon int
main(int ac,char ** av)20*a33ac161SMatthew Dillon main(int ac, char **av)
21*a33ac161SMatthew Dillon {
22*a33ac161SMatthew Dillon 	pthread_t td1;
23*a33ac161SMatthew Dillon 	pthread_t td2;
24*a33ac161SMatthew Dillon 	int n;
25*a33ac161SMatthew Dillon 	int k;
26*a33ac161SMatthew Dillon 	int status;
27*a33ac161SMatthew Dillon 
28*a33ac161SMatthew Dillon 	printf("tests umtx hand-off loop\n");
29*a33ac161SMatthew Dillon 	for (n = 1; n; --n) {
30*a33ac161SMatthew Dillon 		if (fork() == 0) {
31*a33ac161SMatthew Dillon 			start_timing();
32*a33ac161SMatthew Dillon 			for (k = 0; k < 10; ++k) {
33*a33ac161SMatthew Dillon 				pthread_create(&td1, NULL, do_child, NULL);
34*a33ac161SMatthew Dillon 				pthread_create(&td2, NULL, do_parent, NULL);
35*a33ac161SMatthew Dillon 				pthread_join(td2, NULL);
36*a33ac161SMatthew Dillon 				pthread_join(td1, NULL);
37*a33ac161SMatthew Dillon 			}
38*a33ac161SMatthew Dillon 			stop_timing(total, "total");
39*a33ac161SMatthew Dillon 			_exit(0);
40*a33ac161SMatthew Dillon 		}
41*a33ac161SMatthew Dillon 	}
42*a33ac161SMatthew Dillon 	while (wait3(&status, 0, NULL) <= 0 || errno == EINTR)
43*a33ac161SMatthew Dillon 		;
44*a33ac161SMatthew Dillon 
45*a33ac161SMatthew Dillon 	return 0;
46*a33ac161SMatthew Dillon }
47*a33ac161SMatthew Dillon 
48*a33ac161SMatthew Dillon static
49*a33ac161SMatthew Dillon void *
do_child(void * arg __unused)50*a33ac161SMatthew Dillon do_child(void *arg __unused)
51*a33ac161SMatthew Dillon {
52*a33ac161SMatthew Dillon 	for (;;) {
53*a33ac161SMatthew Dillon 		while (mtx == 0)
54*a33ac161SMatthew Dillon 			umtx_sleep(&mtx, 0, 0);
55*a33ac161SMatthew Dillon 		if (atomic_swap_int(&mtx, 0) == 2) {
56*a33ac161SMatthew Dillon 			umtx_wakeup(&mtx, 0);
57*a33ac161SMatthew Dillon 			pthread_yield();
58*a33ac161SMatthew Dillon 			break;
59*a33ac161SMatthew Dillon 		}
60*a33ac161SMatthew Dillon 		umtx_wakeup(&mtx, 0);
61*a33ac161SMatthew Dillon 	}
62*a33ac161SMatthew Dillon 	return NULL;
63*a33ac161SMatthew Dillon }
64*a33ac161SMatthew Dillon 
65*a33ac161SMatthew Dillon static
66*a33ac161SMatthew Dillon void *
do_parent(void * arg __unused)67*a33ac161SMatthew Dillon do_parent(void *arg __unused)
68*a33ac161SMatthew Dillon {
69*a33ac161SMatthew Dillon 	int j;
70*a33ac161SMatthew Dillon 	int loops;
71*a33ac161SMatthew Dillon 
72*a33ac161SMatthew Dillon 	for (j = 0; j < 1000000; ++j) {
73*a33ac161SMatthew Dillon 		atomic_swap_int(&mtx, 1);
74*a33ac161SMatthew Dillon 		umtx_wakeup(&mtx, 0);
75*a33ac161SMatthew Dillon 		pthread_yield();
76*a33ac161SMatthew Dillon 		while (mtx == 1)
77*a33ac161SMatthew Dillon 			umtx_sleep(&mtx, 1, 0);
78*a33ac161SMatthew Dillon 	}
79*a33ac161SMatthew Dillon 	start_timing();
80*a33ac161SMatthew Dillon 	for (j = 0; j < 1000000; ++j) {
81*a33ac161SMatthew Dillon 		atomic_swap_int(&mtx, 1);
82*a33ac161SMatthew Dillon 		umtx_wakeup(&mtx, 0);
83*a33ac161SMatthew Dillon 		while (mtx == 1)
84*a33ac161SMatthew Dillon 			umtx_sleep(&mtx, 1, 0);
85*a33ac161SMatthew Dillon 	}
86*a33ac161SMatthew Dillon 	stop_timing(j, "mtx1");
87*a33ac161SMatthew Dillon 	atomic_add_long(&total, j * 2);
88*a33ac161SMatthew Dillon 
89*a33ac161SMatthew Dillon 	atomic_swap_int(&mtx, 2);
90*a33ac161SMatthew Dillon 	umtx_wakeup(&mtx, 0);
91*a33ac161SMatthew Dillon 	while (mtx == 2)
92*a33ac161SMatthew Dillon 		umtx_sleep(&mtx, 2, 0);
93*a33ac161SMatthew Dillon 
94*a33ac161SMatthew Dillon 	return NULL;
95*a33ac161SMatthew Dillon }
96