1#include <threads.h>
2
3#include <assert.h>
4#include <zircon/syscalls.h>
5
6#include "time_conversion.h"
7
8int thrd_sleep(const struct timespec* req, struct timespec* rem) {
9    zx_time_t deadline = ZX_TIME_INFINITE;
10    int ret = __timespec_to_deadline(req, CLOCK_REALTIME, &deadline);
11    if (ret) {
12        // According to the API, failures not due to signals should return a
13        // negative value other than -1. So return -2 if we didn't timeout.
14        return ret == ETIMEDOUT ? 0 : -2;
15    }
16
17    // For now, Zircon only provides an uninterruptible nanosleep. If
18    // we ever introduce an asynchronous mechanism that would require
19    // some EINTR-like logic, then we will also want a nanosleep call
20    // which reports back how much time is remaining. Until then,
21    // always report back 0 timeout remaining.
22
23    ret = _zx_nanosleep(deadline);
24    assert(ret == 0);
25    if (rem) {
26        *rem = (struct timespec){
27            .tv_sec = 0,
28            .tv_nsec = 0,
29        };
30    }
31    return 0;
32}
33