void _Thrd_sleep(const xtime *xt) { /* suspend thread until time xt */ xtime now; xtime_get(&now, TIME_UTC); do { /* sleep and check time */ Sleep(_Xtime_diff_to_millis2(xt, &now)); xtime_get(&now, TIME_UTC); } while (now.sec < xt->sec || now.sec == xt->sec && now.nsec < xt->nsec); }
long _Xtime_diff_to_millis(const xtime *xt) { /* convert time to milliseconds */ xtime now; xtime_get(&now, TIME_UTC); return (_Xtime_diff_to_millis2(xt, &now)); }
static int mtx_do_lock(_Mtx_t mtx, const xtime *target) { /* lock mutex */ if ((mtx->type & ~_Mtx_recursive) == _Mtx_plain) { /* set the lock */ if (mtx->thread_id != static_cast<long>(GetCurrentThreadId())) { /* not current thread, do lock */ mtx->_get_cs()->lock(); mtx->thread_id = static_cast<long>(GetCurrentThreadId()); } ++mtx->count; return (_Thrd_success); } else { /* handle timed or recursive mutex */ int res = WAIT_TIMEOUT; if (target == 0) { /* no target --> plain wait (i.e. infinite timeout) */ if (mtx->thread_id != static_cast<long>(GetCurrentThreadId())) mtx->_get_cs()->lock(); res = WAIT_OBJECT_0; } else if (target->sec < 0 || target->sec == 0 && target->nsec <= 0) { /* target time <= 0 --> plain trylock or timed wait for */ /* time that has passed; try to lock with 0 timeout */ if (mtx->thread_id != static_cast<long>(GetCurrentThreadId())) { /* not this thread, lock it */ if (mtx->_get_cs()->try_lock()) res = WAIT_OBJECT_0; else res = WAIT_TIMEOUT; } else res = WAIT_OBJECT_0; } else { /* check timeout */ xtime now; xtime_get(&now, TIME_UTC); while (now.sec < target->sec || now.sec == target->sec && now.nsec < target->nsec) { /* time has not expired */ if (mtx->thread_id == static_cast<long>(GetCurrentThreadId()) || mtx->_get_cs()->try_lock_for( _Xtime_diff_to_millis2(target, &now))) { /* stop waiting */ res = WAIT_OBJECT_0; break; } else res = WAIT_TIMEOUT; xtime_get(&now, TIME_UTC); } } if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) ; else if (1 < ++mtx->count) { /* check count */ if ((mtx->type & _Mtx_recursive) != _Mtx_recursive) { /* not recursive, fixup count */ --mtx->count; res = WAIT_TIMEOUT; } } else mtx->thread_id = static_cast<long>(GetCurrentThreadId()); switch (res) { case WAIT_OBJECT_0: case WAIT_ABANDONED: return (_Thrd_success); case WAIT_TIMEOUT: if (target == 0 || (target->sec == 0 && target->nsec == 0)) return (_Thrd_busy); else return (_Thrd_timedout); default: return (_Thrd_error); } } }