1#include "threads_impl.h"
2#include "time_conversion.h"
3#include <errno.h>
4#include <zircon/syscalls.h>
5#include <time.h>
6
7int __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, 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