#include "pthread_impl.h" #include void __pthread_testcancel(void); int __clock_gettime(clockid_t clk, struct timespec *ts); int __thrd_wait(volatile int *addr, int val, const struct timespec *at); static int __cnd_timedwait(__cnd_t *restrict c, __mtx_t *restrict mut, const struct timespec *restrict ts) { int e, r; __mtx_unlock(mut); do { e = 0; /* get a token if some is available */ for (int token = c->tok; token > 0;) { int prev = a_cas(&c->tok, token, token - 1); if (prev == token) { goto RELOCK; } token = prev; } e = __thrd_wait(&c->tok, 0, ts); } while (!e || e == EINTR || e == EWOULDBLOCK); if (e != ETIMEDOUT) return thrd_error; RELOCK: if ((r=__mtx_lock(mut))) return r; switch (e) { case 0: return thrd_success; case ETIMEDOUT: return thrd_timedout; default: return thrd_error; } } int cnd_timedwait(cnd_t *restrict cond, mtx_t *restrict mut, const struct timespec *restrict ts) { int ret = thrd_error; __mtx_t * m = __mtx_getref(mut); if (m) { __cnd_t * c = __cnd_getref(cond, m); if (c) { ret = __cnd_timedwait(c, m, ts); __cnd_unref(c); } __mtx_unref(m); } return ret; }