diff --git a/headers/posix/pthread.h b/headers/posix/pthread.h index ac84d62315..76d3cce2d7 100644 --- a/headers/posix/pthread.h +++ b/headers/posix/pthread.h @@ -131,6 +131,10 @@ extern int pthread_condattr_getpshared(const pthread_condattr_t *condAttr, int *processShared); extern int pthread_condattr_setpshared(pthread_condattr_t *condAttr, int processShared); +extern int pthread_condattr_getclock(const pthread_condattr_t *condAttr, + clockid_t *clockID); +extern int pthread_condattr_setclock(pthread_condattr_t *condAttr, + clockid_t clockID); /* rwlock functions */ extern int pthread_rwlock_init(pthread_rwlock_t *lock, diff --git a/headers/private/libroot/pthread_private.h b/headers/private/libroot/pthread_private.h index 659ac7b832..169bc8d9bf 100644 --- a/headers/private/libroot/pthread_private.h +++ b/headers/private/libroot/pthread_private.h @@ -29,6 +29,7 @@ struct thread_creation_attributes; typedef struct _pthread_condattr { bool process_shared; + clockid_t clock_id; } pthread_condattr; typedef struct _pthread_mutexattr { diff --git a/src/libs/posix_error_mapper/pthread_condattr.cpp b/src/libs/posix_error_mapper/pthread_condattr.cpp index 8e4c848810..9d6a827e41 100644 --- a/src/libs/posix_error_mapper/pthread_condattr.cpp +++ b/src/libs/posix_error_mapper/pthread_condattr.cpp @@ -32,3 +32,17 @@ WRAPPER_FUNCTION(int, pthread_condattr_setpshared, return B_TO_POSITIVE_ERROR(sReal_pthread_condattr_setpshared(condAttr, processShared)); ) + + +WRAPPER_FUNCTION(int, pthread_condattr_getclock, + (const pthread_condattr_t *condAttr, clockid_t *clockID), + return B_TO_POSITIVE_ERROR(sReal_pthread_condattr_getclock(condAttr, + clockID)); +) + + +WRAPPER_FUNCTION(int, pthread_condattr_setclock, + (pthread_condattr_t *condAttr, clockid_t clockID), + return B_TO_POSITIVE_ERROR(sReal_pthread_condattr_setclock(condAttr, + clockID)); +) diff --git a/src/system/libroot/posix/pthread/pthread_cond.cpp b/src/system/libroot/posix/pthread/pthread_cond.cpp index 4938090027..258fbab3cf 100644 --- a/src/system/libroot/posix/pthread/pthread_cond.cpp +++ b/src/system/libroot/posix/pthread/pthread_cond.cpp @@ -19,10 +19,12 @@ #define COND_FLAG_SHARED 0x01 +#define COND_FLAG_MONOTONIC 0x02 static const pthread_condattr pthread_condattr_default = { - false + false, + CLOCK_REALTIME }; @@ -36,6 +38,9 @@ pthread_cond_init(pthread_cond_t* cond, const pthread_condattr_t* _attr) if (attr->process_shared) cond->flags |= COND_FLAG_SHARED; + if (attr->clock_id == CLOCK_MONOTONIC) + cond->flags |= COND_FLAG_MONOTONIC; + cond->mutex = NULL; cond->waiter_count = 0; cond->lock = 0; @@ -74,10 +79,12 @@ cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex, bigtime_t timeout) mutex->owner = -1; mutex->owner_count = 0; + int32 flags = (cond->flags & COND_FLAG_MONOTONIC) != 0 ? B_ABSOLUTE_TIMEOUT + : B_ABSOLUTE_REAL_TIME_TIMEOUT; + status_t status = _kern_mutex_switch_lock((int32*)&mutex->lock, (int32*)&cond->lock, "pthread condition", - timeout == B_INFINITE_TIMEOUT ? 0 : B_ABSOLUTE_REAL_TIME_TIMEOUT, - timeout); + timeout == B_INFINITE_TIMEOUT ? 0 : flags, timeout); if (status == B_INTERRUPTED) { // EINTR is not an allowed return value. We either have to restart diff --git a/src/system/libroot/posix/pthread/pthread_condattr.c b/src/system/libroot/posix/pthread/pthread_condattr.c index 24634a41a1..34addb92b0 100644 --- a/src/system/libroot/posix/pthread/pthread_condattr.c +++ b/src/system/libroot/posix/pthread/pthread_condattr.c @@ -23,6 +23,7 @@ pthread_condattr_init(pthread_condattr_t *_condAttr) return B_NO_MEMORY; attr->process_shared = false; + attr->clock_id = CLOCK_REALTIME; *_condAttr = attr; return B_OK; @@ -71,3 +72,29 @@ pthread_condattr_setpshared(pthread_condattr_t *_condAttr, int processShared) return B_OK; } + +int +pthread_condattr_getclock(const pthread_condattr_t *_condAttr, clockid_t *_clockID) +{ + pthread_condattr *attr; + + if (_condAttr == NULL || (attr = *_condAttr) == NULL || _clockID == NULL) + return B_BAD_VALUE; + + *_clockID = attr->clock_id; + return B_OK; +} + + +int +pthread_condattr_setclock(pthread_condattr_t *_condAttr, clockid_t clockID) +{ + pthread_condattr *attr; + + if (_condAttr == NULL || (attr = *_condAttr) == NULL + || (clockID != CLOCK_REALTIME && clockID != CLOCK_MONOTONIC)) + return B_BAD_VALUE; + + attr->clock_id = clockID; + return B_OK; +}