POSIX: introduce sem_clockwait
will appear in the next version: https://www.opengroup.org/austin/docs/austin_1110.pdf Change-Id: Iee3faf23647aa5244ad316fe1c3d825592483935 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4966 Reviewed-by: waddlesplash <waddlesplash@gmail.com> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
parent
a21676b669
commit
a866e2d902
@ -33,7 +33,9 @@ int sem_init(sem_t* semaphore, int shared, unsigned value);
|
||||
int sem_destroy(sem_t* semaphore);
|
||||
|
||||
int sem_post(sem_t* semaphore);
|
||||
int sem_timedwait(sem_t* semaphore, const struct timespec* timeout);
|
||||
int sem_clockwait(sem_t* semaphore, clockid_t clock_id,
|
||||
const struct timespec* abstime);
|
||||
int sem_timedwait(sem_t* semaphore, const struct timespec* abstime);
|
||||
int sem_trywait(sem_t* semaphore);
|
||||
int sem_wait(sem_t* semaphore);
|
||||
int sem_getvalue(sem_t* semaphore, int* value);
|
||||
|
@ -32,7 +32,8 @@ status_t _user_realtime_sem_unlink(const char* name);
|
||||
|
||||
status_t _user_realtime_sem_get_value(sem_id semID, int* value);
|
||||
status_t _user_realtime_sem_post(sem_id semID);
|
||||
status_t _user_realtime_sem_wait(sem_id semID, bigtime_t timeout);
|
||||
status_t _user_realtime_sem_wait(sem_id semID, uint32 flags,
|
||||
bigtime_t timeout);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
@ -112,7 +112,8 @@ extern status_t _kern_realtime_sem_unlink(const char* name);
|
||||
|
||||
extern status_t _kern_realtime_sem_get_value(sem_id semID, int* value);
|
||||
extern status_t _kern_realtime_sem_post(sem_id semID);
|
||||
extern status_t _kern_realtime_sem_wait(sem_id semID, bigtime_t timeout);
|
||||
extern status_t _kern_realtime_sem_wait(sem_id semID, uint32 flags,
|
||||
bigtime_t timeout);
|
||||
|
||||
/* POSIX XSI semaphore syscalls */
|
||||
extern int _kern_xsi_semget(key_t key, int numSems, int flags);
|
||||
|
@ -506,7 +506,7 @@ struct realtime_sem_context {
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t AcquireSem(sem_id id, bigtime_t timeout)
|
||||
status_t AcquireSem(sem_id id, uint32 flags, bigtime_t timeout)
|
||||
{
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
@ -518,17 +518,7 @@ struct realtime_sem_context {
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
status_t error;
|
||||
if (timeout == 0) {
|
||||
error = acquire_sem_etc(id, 1, B_CAN_INTERRUPT | B_RELATIVE_TIMEOUT,
|
||||
0);
|
||||
} else if (timeout == B_INFINITE_TIMEOUT) {
|
||||
error = acquire_sem_etc(id, 1, B_CAN_INTERRUPT, 0);
|
||||
} else {
|
||||
error = acquire_sem_etc(id, 1,
|
||||
B_CAN_INTERRUPT | B_ABSOLUTE_REAL_TIME_TIMEOUT, timeout);
|
||||
}
|
||||
|
||||
status_t error = acquire_sem_etc(id, 1, flags | B_CAN_INTERRUPT, timeout);
|
||||
return error == B_BAD_SEM_ID ? B_BAD_VALUE : error;
|
||||
}
|
||||
|
||||
@ -813,11 +803,11 @@ _user_realtime_sem_post(sem_id semID)
|
||||
|
||||
|
||||
status_t
|
||||
_user_realtime_sem_wait(sem_id semID, bigtime_t timeout)
|
||||
_user_realtime_sem_wait(sem_id semID, uint32 flags, bigtime_t timeout)
|
||||
{
|
||||
realtime_sem_context* context = get_current_team_context();
|
||||
if (context == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return syscall_restart_handle_post(context->AcquireSem(semID, timeout));
|
||||
return syscall_restart_handle_post(context->AcquireSem(semID, flags, timeout));
|
||||
}
|
||||
|
@ -131,7 +131,8 @@ sem_destroy(sem_t* semaphore)
|
||||
|
||||
|
||||
static int
|
||||
unnamed_sem_post(sem_t* semaphore) {
|
||||
unnamed_sem_post(sem_t* semaphore)
|
||||
{
|
||||
int32* sem = (int32*)&semaphore->u.unnamed_sem;
|
||||
int32 oldValue = atomic_add_if_greater(sem, 1, -1);
|
||||
if (oldValue > -1)
|
||||
@ -142,7 +143,8 @@ unnamed_sem_post(sem_t* semaphore) {
|
||||
|
||||
|
||||
static int
|
||||
unnamed_sem_trywait(sem_t* semaphore) {
|
||||
unnamed_sem_trywait(sem_t* semaphore)
|
||||
{
|
||||
int32* sem = (int32*)&semaphore->u.unnamed_sem;
|
||||
int32 oldValue = atomic_add_if_greater(sem, -1, 0);
|
||||
if (oldValue > 0)
|
||||
@ -153,22 +155,33 @@ unnamed_sem_trywait(sem_t* semaphore) {
|
||||
|
||||
|
||||
static int
|
||||
unnamed_sem_timedwait(sem_t* semaphore, const struct timespec* timeout) {
|
||||
unnamed_sem_timedwait(sem_t* semaphore, clockid_t clock_id,
|
||||
const struct timespec* timeout)
|
||||
{
|
||||
int32* sem = (int32*)&semaphore->u.unnamed_sem;
|
||||
|
||||
bigtime_t timeoutMicros = B_INFINITE_TIMEOUT;
|
||||
uint32 flags = 0;
|
||||
if (timeout != NULL) {
|
||||
timeoutMicros = ((bigtime_t)timeout->tv_sec) * 1000000
|
||||
+ timeout->tv_nsec / 1000;
|
||||
switch (clock_id) {
|
||||
case CLOCK_REALTIME:
|
||||
flags = B_ABSOLUTE_REAL_TIME_TIMEOUT;
|
||||
break;
|
||||
case CLOCK_MONOTONIC:
|
||||
flags = B_ABSOLUTE_TIMEOUT;
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int result = unnamed_sem_trywait(semaphore);
|
||||
if (result == 0)
|
||||
return 0;
|
||||
|
||||
return _kern_mutex_sem_acquire(sem, NULL,
|
||||
timeoutMicros == B_INFINITE_TIMEOUT ? 0 : B_ABSOLUTE_REAL_TIME_TIMEOUT,
|
||||
timeoutMicros);
|
||||
return _kern_mutex_sem_acquire(sem, NULL, flags, timeoutMicros);
|
||||
}
|
||||
|
||||
|
||||
@ -186,11 +199,13 @@ sem_post(sem_t* semaphore)
|
||||
|
||||
|
||||
static int
|
||||
named_sem_timedwait(sem_t* semaphore, const struct timespec* timeout)
|
||||
named_sem_timedwait(sem_t* semaphore, clockid_t clock_id,
|
||||
const struct timespec* timeout)
|
||||
{
|
||||
if (timeout != NULL
|
||||
&& (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000)) {
|
||||
status_t err = _kern_realtime_sem_wait(semaphore->u.named_sem_id, 0);
|
||||
status_t err = _kern_realtime_sem_wait(semaphore->u.named_sem_id,
|
||||
B_RELATIVE_TIMEOUT, 0);
|
||||
if (err == B_WOULD_BLOCK)
|
||||
err = EINVAL;
|
||||
// do nothing, return err as it is.
|
||||
@ -198,11 +213,22 @@ named_sem_timedwait(sem_t* semaphore, const struct timespec* timeout)
|
||||
}
|
||||
|
||||
bigtime_t timeoutMicros = B_INFINITE_TIMEOUT;
|
||||
uint32 flags = 0;
|
||||
if (timeout != NULL) {
|
||||
timeoutMicros = ((bigtime_t)timeout->tv_sec) * 1000000
|
||||
+ timeout->tv_nsec / 1000;
|
||||
switch (clock_id) {
|
||||
case CLOCK_REALTIME:
|
||||
flags = B_ABSOLUTE_REAL_TIME_TIMEOUT;
|
||||
break;
|
||||
case CLOCK_MONOTONIC:
|
||||
flags = B_ABSOLUTE_TIMEOUT;
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
status_t err = _kern_realtime_sem_wait(semaphore->u.named_sem_id,
|
||||
status_t err = _kern_realtime_sem_wait(semaphore->u.named_sem_id, flags,
|
||||
timeoutMicros);
|
||||
if (err == B_WOULD_BLOCK)
|
||||
err = ETIMEDOUT;
|
||||
@ -215,9 +241,10 @@ int
|
||||
sem_trywait(sem_t* semaphore)
|
||||
{
|
||||
status_t error;
|
||||
if (semaphore->type == SEM_TYPE_NAMED)
|
||||
error = _kern_realtime_sem_wait(semaphore->u.named_sem_id, 0);
|
||||
else
|
||||
if (semaphore->type == SEM_TYPE_NAMED) {
|
||||
error = _kern_realtime_sem_wait(semaphore->u.named_sem_id,
|
||||
B_RELATIVE_TIMEOUT, 0);
|
||||
} else
|
||||
error = unnamed_sem_trywait(semaphore);
|
||||
|
||||
RETURN_AND_SET_ERRNO(error);
|
||||
@ -229,27 +256,34 @@ sem_wait(sem_t* semaphore)
|
||||
{
|
||||
status_t error;
|
||||
if (semaphore->type == SEM_TYPE_NAMED)
|
||||
error = named_sem_timedwait(semaphore, NULL);
|
||||
error = named_sem_timedwait(semaphore, CLOCK_REALTIME, NULL);
|
||||
else
|
||||
error = unnamed_sem_timedwait(semaphore, NULL);
|
||||
error = unnamed_sem_timedwait(semaphore, CLOCK_REALTIME, NULL);
|
||||
|
||||
RETURN_AND_SET_ERRNO_TEST_CANCEL(error);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sem_timedwait(sem_t* semaphore, const struct timespec* timeout)
|
||||
sem_clockwait(sem_t* semaphore, clockid_t clock_id, const struct timespec* abstime)
|
||||
{
|
||||
status_t error;
|
||||
if (semaphore->type == SEM_TYPE_NAMED)
|
||||
error = named_sem_timedwait(semaphore, timeout);
|
||||
error = named_sem_timedwait(semaphore, clock_id, abstime);
|
||||
else
|
||||
error = unnamed_sem_timedwait(semaphore, timeout);
|
||||
error = unnamed_sem_timedwait(semaphore, clock_id, abstime);
|
||||
|
||||
RETURN_AND_SET_ERRNO_TEST_CANCEL(error);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sem_timedwait(sem_t* semaphore, const struct timespec* abstime)
|
||||
{
|
||||
return sem_clockwait(semaphore, CLOCK_REALTIME, abstime);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sem_getvalue(sem_t* semaphore, int* value)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user