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 } 96