mm_timeval_t mm_clock_gettime(mm_clock_t clock) { if (clock == MM_CLOCK_REALTIME) return mm_clock_gettime_realtime(); else return mm_clock_gettime_monotonic(); }
mm_event_listener_timedwait(struct mm_event_listener *listener, mm_ring_seqno_t stamp, mm_timeout_t timeout) { ENTER(); #if ENABLE_LINUX_FUTEX struct timespec ts; ts.tv_sec = (timeout / 1000000); ts.tv_nsec = (timeout % 1000000) * 1000; // Publish the log before a sleep. mm_log_relay(); int rc = mm_syscall_4(SYS_futex, mm_event_listener_futex(listener), FUTEX_WAIT_PRIVATE, stamp, (uintptr_t) &ts); if (rc != 0 && errno != EWOULDBLOCK && errno != ETIMEDOUT) mm_fatal(errno, "futex"); #elif ENABLE_MACH_SEMAPHORE (void) stamp; mach_timespec_t ts; ts.tv_sec = (timeout / 1000000); ts.tv_nsec = (timeout % 1000000) * 1000; // Publish the log before a sleep. mm_log_relay(); kern_return_t r = semaphore_timedwait(listener->semaphore, ts); if (r != KERN_SUCCESS && unlikely(r != KERN_OPERATION_TIMED_OUT)) mm_fatal(0, "semaphore_timedwait"); #else mm_timeval_t time = mm_clock_gettime_realtime() + timeout; mm_thread_monitor_lock(&listener->monitor); #if ENABLE_NOTIFY_STAMP if (stamp == mm_event_listener_enqueue_stamp(listener)) mm_thread_monitor_timedwait(&listener->monitor, time); #else if (listener->notify_stamp == stamp) mm_thread_monitor_timedwait(&listener->monitor, time); #endif mm_thread_monitor_unlock(&listener->monitor); #endif LEAVE(); }