--- ports/unix/sys_arch.c 2016-05-17 13:51:25.000000000 -0700 +++ ports/unix/sys_arch_darwin.c 2016-05-19 15:59:09.000000000 -0700 @@ -53,6 +53,11 @@ #include #include +#ifndef CLOCK_MONOTONIC +#include +#include +#endif + #include "lwip/sys.h" #include "lwip/opt.h" #include "lwip/stats.h" @@ -102,6 +107,22 @@ static u32_t cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex, u32_t timeout); +static void get_monotonic_time(struct timespec *ts) { +#ifdef CLOCK_MONOTONIC + clock_gettime(CLOCK_MONOTONIC, ts); +#else + // darwin impl (no CLOCK_MONOTONIC) + uint64_t t = mach_absolute_time(); + mach_timebase_info_data_t timebase_info = {0, 0}; + mach_timebase_info(&timebase_info); + uint64_t nano = (t * timebase_info.numer) / (timebase_info.denom); + uint64_t sec = nano/1000000000L; + nano -= sec * 1000000000L; + ts->tv_sec = sec; + ts->tv_nsec = nano; +#endif +} + /*-----------------------------------------------------------------------------------*/ static struct sys_thread * introduce_thread(pthread_t id) @@ -352,7 +373,9 @@ if (sem != NULL) { sem->c = count; pthread_condattr_init(&(sem->condattr)); +#ifdef CLOCK_MONOTONIC pthread_condattr_setclock(&(sem->condattr), CLOCK_MONOTONIC); +#endif pthread_cond_init(&(sem->cond), &(sem->condattr)); pthread_mutex_init(&(sem->mutex), NULL); } @@ -382,7 +405,8 @@ } /* Get a timestamp and add the timeout value. */ - clock_gettime(CLOCK_MONOTONIC, &rtime1); + get_monotonic_time(&rtime1); +#ifdef CLOCK_MONOTONIC ts.tv_sec = rtime1.tv_sec + timeout / 1000L; ts.tv_nsec = rtime1.tv_nsec + (timeout % 1000L) * 1000000L; if (ts.tv_nsec >= 1000000000L) { @@ -391,12 +415,17 @@ } ret = pthread_cond_timedwait(cond, mutex, &ts); +#else + ts.tv_sec = timeout / 1000L; + ts.tv_nsec = (timeout % 1000L) * 1000000L; + ret = pthread_cond_timedwait_relative_np(cond, mutex, &ts); +#endif if (ret == ETIMEDOUT) { return SYS_ARCH_TIMEOUT; } /* Calculate for how long we waited for the cond. */ - clock_gettime(CLOCK_MONOTONIC, &rtime2); + get_monotonic_time(&rtime2); ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec; ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec; if (ts.tv_nsec < 0) { @@ -476,7 +505,7 @@ { struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); + get_monotonic_time(&ts); return ts.tv_sec * 1000L + ts.tv_nsec / 1000000L; } /*-----------------------------------------------------------------------------------*/ @@ -547,6 +576,6 @@ { struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); + get_monotonic_time(&ts); return ts.tv_sec * 1000000000L + ts.tv_nsec; }