From: macrule <562520+macrule@users.noreply.github.com> Date: Wed, 29 Nov 2017 17:18:53 +0000 (+0100) Subject: wrappers: Implemented correctly for Darwin. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2952888216c89599290c2e9050a4498c7bd66787;p=thirdparty%2Ftvheadend.git wrappers: Implemented correctly for Darwin. pthread_cond_timedwait() is not usable on Darwin, because it cannot be configured to use the monotonic clock. So instead the relative pthread_cond_timedwait_relative_np() is used with a relative time to wait for. Only tvhthread_renice() is missing, but there seems to be currently no way on Darwin or FreeBSD to implement per-thread prioritization. The #warning is good, but it breaks with the default -Werror compile flag. --- diff --git a/src/wrappers.c b/src/wrappers.c index b621e2417..36b434337 100644 --- a/src/wrappers.c +++ b/src/wrappers.c @@ -199,6 +199,10 @@ tvhthread_renice(int value) pid_t tid; tid = gettid(); ret = setpriority(PRIO_PROCESS, tid, value); +#elif defined(PLATFORM_DARWIN) + /* Currently not possible */ +#elif defined(PLATFORM_FREEBSD) + /* Currently not possible */ #else #warning "Implement renice for your platform!" #endif @@ -234,11 +238,20 @@ tvh_cond_init pthread_condattr_t attr; pthread_condattr_init(&attr); +#if defined(PLATFORM_DARWIN) + /* + * pthread_condattr_setclock() not supported on platform Darwin. + * We use pthread_cond_timedwait_relative_np() which doesn't + * need it. + */ + r = 0; +#else r = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); if (r) { fprintf(stderr, "Unable to set monotonic clocks for conditions! (%d)", r); abort(); } +#endif return pthread_cond_init(&cond->cond, &attr); } @@ -270,11 +283,24 @@ int tvh_cond_timedwait ( tvh_cond_t *cond, pthread_mutex_t *mutex, int64_t monoclock ) { +#if defined(PLATFORM_DARWIN) + /* Use a relative timedwait implementation */ + int64_t now = getmonoclock(); + int64_t relative = monoclock - now; + + struct timespec ts; + ts.tv_sec = relative / MONOCLOCK_RESOLUTION; + ts.tv_nsec = (relative % MONOCLOCK_RESOLUTION) * + (1000000000ULL/MONOCLOCK_RESOLUTION); + + return pthread_cond_timedwait_relative_np(&cond->cond, mutex, &ts); +#else struct timespec ts; ts.tv_sec = monoclock / MONOCLOCK_RESOLUTION; ts.tv_nsec = (monoclock % MONOCLOCK_RESOLUTION) * (1000000000ULL/MONOCLOCK_RESOLUTION); return pthread_cond_timedwait(&cond->cond, mutex, &ts); +#endif } /* @@ -301,6 +327,9 @@ tvh_safe_usleep(int64_t us) int64_t tvh_usleep(int64_t us) { +#if defined(PLATFORM_DARWIN) + return usleep(us); +#else struct timespec ts; int64_t val; int r; @@ -313,11 +342,18 @@ tvh_usleep(int64_t us) if (ERRNO_AGAIN(r)) return val; return r ? -r : 0; +#endif } int64_t tvh_usleep_abs(int64_t us) { +#if defined(PLATFORM_DARWIN) + /* Convert to relative wait */ + int64_t now = getmonoclock(); + int64_t relative = us - now; + return tvh_usleep(relative); +#else struct timespec ts; int64_t val; int r; @@ -330,6 +366,7 @@ tvh_usleep_abs(int64_t us) if (ERRNO_AGAIN(r)) return val; return r ? -r : 0; +#endif } /*