Add support for pthread_condattr_get/setclock()
* Allows use of either CLOCK_REALTIME or CLOCK_MONOTONIC as the time base for pthread_cond_timedwait().
This commit is contained in:
@@ -131,6 +131,10 @@ extern int pthread_condattr_getpshared(const pthread_condattr_t *condAttr,
|
|||||||
int *processShared);
|
int *processShared);
|
||||||
extern int pthread_condattr_setpshared(pthread_condattr_t *condAttr,
|
extern int pthread_condattr_setpshared(pthread_condattr_t *condAttr,
|
||||||
int processShared);
|
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 */
|
/* rwlock functions */
|
||||||
extern int pthread_rwlock_init(pthread_rwlock_t *lock,
|
extern int pthread_rwlock_init(pthread_rwlock_t *lock,
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ struct thread_creation_attributes;
|
|||||||
|
|
||||||
typedef struct _pthread_condattr {
|
typedef struct _pthread_condattr {
|
||||||
bool process_shared;
|
bool process_shared;
|
||||||
|
clockid_t clock_id;
|
||||||
} pthread_condattr;
|
} pthread_condattr;
|
||||||
|
|
||||||
typedef struct _pthread_mutexattr {
|
typedef struct _pthread_mutexattr {
|
||||||
|
|||||||
@@ -32,3 +32,17 @@ WRAPPER_FUNCTION(int, pthread_condattr_setpshared,
|
|||||||
return B_TO_POSITIVE_ERROR(sReal_pthread_condattr_setpshared(condAttr,
|
return B_TO_POSITIVE_ERROR(sReal_pthread_condattr_setpshared(condAttr,
|
||||||
processShared));
|
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));
|
||||||
|
)
|
||||||
|
|||||||
@@ -19,10 +19,12 @@
|
|||||||
|
|
||||||
|
|
||||||
#define COND_FLAG_SHARED 0x01
|
#define COND_FLAG_SHARED 0x01
|
||||||
|
#define COND_FLAG_MONOTONIC 0x02
|
||||||
|
|
||||||
|
|
||||||
static const pthread_condattr pthread_condattr_default = {
|
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)
|
if (attr->process_shared)
|
||||||
cond->flags |= COND_FLAG_SHARED;
|
cond->flags |= COND_FLAG_SHARED;
|
||||||
|
|
||||||
|
if (attr->clock_id == CLOCK_MONOTONIC)
|
||||||
|
cond->flags |= COND_FLAG_MONOTONIC;
|
||||||
|
|
||||||
cond->mutex = NULL;
|
cond->mutex = NULL;
|
||||||
cond->waiter_count = 0;
|
cond->waiter_count = 0;
|
||||||
cond->lock = 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 = -1;
|
||||||
mutex->owner_count = 0;
|
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,
|
status_t status = _kern_mutex_switch_lock((int32*)&mutex->lock,
|
||||||
(int32*)&cond->lock, "pthread condition",
|
(int32*)&cond->lock, "pthread condition",
|
||||||
timeout == B_INFINITE_TIMEOUT ? 0 : B_ABSOLUTE_REAL_TIME_TIMEOUT,
|
timeout == B_INFINITE_TIMEOUT ? 0 : flags, timeout);
|
||||||
timeout);
|
|
||||||
|
|
||||||
if (status == B_INTERRUPTED) {
|
if (status == B_INTERRUPTED) {
|
||||||
// EINTR is not an allowed return value. We either have to restart
|
// EINTR is not an allowed return value. We either have to restart
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ pthread_condattr_init(pthread_condattr_t *_condAttr)
|
|||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
attr->process_shared = false;
|
attr->process_shared = false;
|
||||||
|
attr->clock_id = CLOCK_REALTIME;
|
||||||
|
|
||||||
*_condAttr = attr;
|
*_condAttr = attr;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -71,3 +72,29 @@ pthread_condattr_setpshared(pthread_condattr_t *_condAttr, int processShared)
|
|||||||
return B_OK;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user