/* * umtx1.c */ #include #include #include #include #include #include #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; }