Skip to content

Add monotonic time support with np pthread_cond_timedwait for Android and Apple #412

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 30 additions & 9 deletions include/boost/thread/detail/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,17 +424,32 @@
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
#define BOOST_THREAD_HAS_MONO_CLOCK
#define BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
#elif defined(BOOST_THREAD_CHRONO_MAC_API)
#define BOOST_THREAD_HAS_MONO_CLOCK
#elif defined(__ANDROID__)
#define BOOST_THREAD_HAS_MONO_CLOCK
#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21
#define BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
#endif
#else
#include <time.h> // check for CLOCK_MONOTONIC
#if defined(CLOCK_MONOTONIC)
#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ < 21
#ifndef BOOST_PTHREAD_HAS_COND_TIMEDWAIT_MONOTONIC_NP
#define BOOST_PTHREAD_HAS_COND_TIMEDWAIT_MONOTONIC_NP
#endif
#endif
#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ < 21 \
|| (defined(__APPLE__) && defined(__MACH__) \
&& ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1040) \
|| (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 20000)))
#ifndef BOOST_PTHREAD_HAS_COND_TIMEDWAIT_RELATIVE_NP
#define BOOST_PTHREAD_HAS_COND_TIMEDWAIT_RELATIVE_NP
#endif
#endif
#if defined(BOOST_THREAD_CHRONO_MAC_API)
#define BOOST_THREAD_HAS_MONO_CLOCK
#else
#include <time.h> // check for CLOCK_MONOTONIC
#if defined(CLOCK_MONOTONIC)
#define BOOST_THREAD_HAS_MONO_CLOCK
#endif
#endif
#if (defined(BOOST_THREAD_HAS_MONO_CLOCK) \
&& (defined(BOOST_PTHREAD_HAS_COND_TIMEDWAIT_MONOTONIC_NP) \
|| defined(CLOCK_MONOTONIC))) \
|| defined(BOOST_PTHREAD_HAS_COND_TIMEDWAIT_RELATIVE_NP)
#define BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
#endif
#endif
Expand All @@ -447,6 +462,12 @@
|| (defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21)
#define BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
#endif
#else
#if defined(BOOST_PTHREAD_HAS_COND_TIMEDWAIT_MONOTONIC_NP)
#define BOOST_THREAD_USES_PTHREAD_COND_TIMEDWAIT_MONOTONIC_NP
#elif defined(BOOST_PTHREAD_HAS_COND_TIMEDWAIT_RELATIVE_NP)
#define BOOST_THREAD_USES_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
#endif
#endif

// provided for backwards compatibility, since this
Expand Down
43 changes: 40 additions & 3 deletions include/boost/thread/pthread/pthread_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
// http://www.boost.org/LICENSE_1_0.txt)

#include <boost/thread/detail/config.hpp>
#ifdef BOOST_THREAD_USES_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
#include <boost/thread/detail/platform_time.hpp>
#endif
#include <boost/throw_exception.hpp>
#include <pthread.h>
#include <errno.h>
Expand All @@ -18,10 +21,42 @@
#define BOOST_THREAD_HAS_EINTR_BUG
#endif

#ifdef __ANDROID__
#if defined(BOOST_THREAD_USES_PTHREAD_COND_TIMEDWAIT_MONOTONIC_NP)
extern "C" int
pthread_cond_timedwait_monotonic_np(pthread_cond_t *cond,
pthread_mutex_t *mutex,
const struct timespec *abstime);
#elif defined(BOOST_THREAD_USES_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP)
extern "C" int
pthread_cond_timedwait_relative_np(pthread_cond_t *cond,
pthread_mutex_t *mutex,
const struct timespec *reltime);
#endif
#endif

namespace boost
{
namespace posix
{
namespace posix_detail
{
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_timedwait(pthread_cond_t* c, pthread_mutex_t* m, const struct timespec* t)
{
#if defined(BOOST_THREAD_USES_PTHREAD_COND_TIMEDWAIT_MONOTONIC_NP)
return ::pthread_cond_timedwait_monotonic_np(c, m, t);
#elif defined(BOOST_THREAD_USES_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP)
using namespace boost;

const detail::internal_platform_timepoint ts(*t);
const detail::platform_duration d(ts - detail::internal_platform_clock::now());
return ::pthread_cond_timedwait_relative_np(c, m, &d.getTs());
#else
return ::pthread_cond_timedwait(c, m, t);
#endif
}
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_init(pthread_mutex_t* m, const pthread_mutexattr_t* attr = NULL)
{
Expand All @@ -31,7 +66,9 @@ namespace boost
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_init(pthread_cond_t* c)
{
#ifdef BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
#if defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO) \
&& !(defined(BOOST_THREAD_USES_PTHREAD_COND_TIMEDWAIT_MONOTONIC_NP) \
|| defined(BOOST_THREAD_USES_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP))
pthread_condattr_t attr;
int res = pthread_condattr_init(&attr);
if (res)
Expand Down Expand Up @@ -120,7 +157,7 @@ namespace boost
int ret;
do
{
ret = ::pthread_cond_timedwait(c, m, t);
ret = posix_detail::pthread_cond_timedwait(c, m, t);
} while (ret == EINTR);
return ret;
}
Expand Down Expand Up @@ -164,7 +201,7 @@ namespace boost
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_timedwait(pthread_cond_t* c, pthread_mutex_t* m, const struct timespec* t)
{
return ::pthread_cond_timedwait(c, m, t);
return posix_detail::pthread_cond_timedwait(c, m, t);
}
#endif

Expand Down