1 #include "threads_impl.h"
2 #include "time_conversion.h"
3 #include <errno.h>
4 #include <zircon/syscalls.h>
5 #include <time.h>
6
__timedwait(atomic_int * futex,int val,clockid_t clk,const struct timespec * at)7 int __timedwait(atomic_int* futex, int val, clockid_t clk, const struct timespec* at) {
8 zx_time_t deadline = ZX_TIME_INFINITE;
9
10 if (at) {
11 int ret = __timespec_to_deadline(at, clk, &deadline);
12 if (ret)
13 return ret;
14 }
15
16 // zx_futex_wait will return ZX_ERR_BAD_STATE if someone modifying *addr
17 // races with this call. But this is indistinguishable from
18 // otherwise being woken up just before someone else changes the
19 // value. Therefore this functions returns 0 in that case.
20 switch (_zx_futex_wait(futex, val, ZX_HANDLE_INVALID, deadline)) {
21 case ZX_OK:
22 case ZX_ERR_BAD_STATE:
23 return 0;
24 case ZX_ERR_TIMED_OUT:
25 return ETIMEDOUT;
26 case ZX_ERR_INVALID_ARGS:
27 default:
28 __builtin_trap();
29 }
30 }
31