| | |
| | | { |
| | | int s; |
| | | |
| | | sigset_t mask_all, pre; |
| | | sigfillset(&mask_all); |
| | | /* __sync_bool_compare_and_swap(ptr, oldval, newval) is a gcc |
| | | built-in function. It atomically performs the equivalent of: |
| | | |
| | |
| | | |
| | | /* Is the futex available? */ |
| | | |
| | | if (__sync_bool_compare_and_swap(futexp, 1, 0)) |
| | | if (__sync_bool_compare_and_swap(futexp, 1, 0)) { |
| | | sigprocmask(SIG_BLOCK, &mask_all, &pre); |
| | | break; /* Yes */ |
| | | } |
| | | |
| | | /* Futex is not available; wait */ |
| | | |
| | | s = futex(futexp, FUTEX_WAIT, 0, NULL, NULL, 0); |
| | | if (s == -1 && errno != EAGAIN) |
| | | errExit("futex-FUTEX_WAIT"); |
| | |
| | | fpost(int *futexp) |
| | | { |
| | | int s; |
| | | |
| | | sigset_t mask; |
| | | sigemptyset(&mask); |
| | | /* __sync_bool_compare_and_swap() was described in comments above */ |
| | | |
| | | if (__sync_bool_compare_and_swap(futexp, 0, 1)) { |
| | | |
| | | s = futex(futexp, FUTEX_WAKE, 1, NULL, NULL, 0); |
| | | sigprocmask(SIG_SETMASK, &mask, NULL); |
| | | if (s == -1) |
| | | errExit("futex-FUTEX_WAKE"); |
| | | } |