Add read-write locks for POSIX

Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
This commit is contained in:
Jeroen Koekkoek 2018-11-20 13:31:32 +01:00
parent 69f563be5b
commit ac020f62f7
4 changed files with 159 additions and 223 deletions

View file

@ -17,6 +17,7 @@ IF(${platform} IN_LIST posix_platforms)
set(platform posix)
ENDIF()
# For posix platforms include the files in the posix/ directory.
PREPEND(srcs_platform ${platform} os_platform_errno.c os_platform_heap.c os_platform_init.c os_platform_process.c os_platform_ifaddrs.c os_platform_socket.c os_platform_stdlib.c os_platform_sync.c os_platform_thread.c os_platform_time.c)
include (GenerateExportHeader)

View file

@ -23,27 +23,15 @@ extern "C" {
#endif
typedef struct os_cond {
#ifdef OSPL_STRICT_MEM
/* Used to identify initialized cond when memory is freed -
keep this first in the structure so its so its address is
the same as the os_cond */
uint64_t signature;
#endif
pthread_cond_t cond;
} os_cond;
typedef struct os_mutex {
#ifdef OSPL_STRICT_MEM
/* Used to identify initialized cond when memory is freed -
keep this first in the structure so its so its address is
the same as the os_cond */
uint64_t signature;
#endif
pthread_mutex_t mutex;
} os_mutex;
typedef struct os_rwlock {
os_mutex mutex;
pthread_rwlock_t rwlock;
} os_rwlock;
typedef pthread_once_t os_once_t;

View file

@ -78,9 +78,7 @@ void os_mutexInit (os_mutex *mutex)
{
int shared;
assert (mutex != NULL);
#ifdef OSPL_STRICT_MEM
assert (mutex->signature != OS_MUTEX_MAGIC_SIG);
#endif
pthread_mutex_init (&mutex->mutex, NULL);
#if HAVE_LKST
if (ospl_lkst_enabled)
@ -88,9 +86,6 @@ void os_mutexInit (os_mutex *mutex)
#else
(void)shared;
#endif
#ifdef OSPL_STRICT_MEM
mutex->signature = OS_MUTEX_MAGIC_SIG;
#endif
}
void os_mutexDestroy (os_mutex *mutex)
@ -100,22 +95,15 @@ void os_mutexDestroy (os_mutex *mutex)
if (ospl_lkst_enabled)
lkst_track_destroy (mutex);
#endif
#ifdef OSPL_STRICT_MEM
assert(mutex->signature == OS_MUTEX_MAGIC_SIG);
#endif
if (pthread_mutex_destroy (&mutex->mutex) != 0)
abort();
#ifdef OSPL_STRICT_MEM
mutex->signature = 0;
#endif
}
void os_mutexLock (os_mutex *mutex)
{
assert (mutex != NULL);
#ifdef OSPL_STRICT_MEM
assert(mutex->signature == OS_MUTEX_MAGIC_SIG);
#endif
#if HAVE_LKST
if (!ospl_lkst_enabled)
#endif
@ -146,9 +134,7 @@ os_result os_mutexLock_s (os_mutex *mutex)
{
int result;
assert (mutex != NULL);
#ifdef OSPL_STRICT_MEM
assert(mutex->signature == OS_MUTEX_MAGIC_SIG);
#endif
#if HAVE_LKST
if (!ospl_lkst_enabled)
#endif
@ -178,9 +164,7 @@ os_result os_mutexTryLock (os_mutex *mutex)
{
int result;
assert (mutex != NULL);
#ifdef OSPL_STRICT_MEM
assert(mutex->signature == OS_MUTEX_MAGIC_SIG);
#endif
result = pthread_mutex_trylock (&mutex->mutex);
if (result != 0 && result != EBUSY)
abort();
@ -194,9 +178,7 @@ os_result os_mutexTryLock (os_mutex *mutex)
void os_mutexUnlock (os_mutex *mutex)
{
assert (mutex != NULL);
#ifdef OSPL_STRICT_MEM
assert(mutex->signature == OS_MUTEX_MAGIC_SIG);
#endif
#if HAVE_LKST
if (ospl_lkst_enabled)
lkst_track_op (mutex, LKST_UNLOCK, mach_absolute_time (), 0);
@ -208,36 +190,23 @@ void os_mutexUnlock (os_mutex *mutex)
void os_condInit (os_cond *cond, os_mutex *dummymtx __attribute__ ((unused)))
{
assert (cond != NULL);
#ifdef OSPL_STRICT_MEM
assert(cond->signature != OS_COND_MAGIC_SIG);
#endif
pthread_cond_init (&cond->cond, NULL);
#ifdef OSPL_STRICT_MEM
cond->signature = OS_COND_MAGIC_SIG;
#endif
}
void os_condDestroy (os_cond *cond)
{
assert (cond != NULL);
#ifdef OSPL_STRICT_MEM
assert(cond->signature == OS_COND_MAGIC_SIG);
#endif
if (pthread_cond_destroy (&cond->cond) != 0)
abort();
#ifdef OSPL_STRICT_MEM
cond->signature = 0;
#endif
}
void os_condWait (os_cond *cond, os_mutex *mutex)
{
assert (cond != NULL);
assert (mutex != NULL);
#ifdef OSPL_STRICT_MEM
assert( cond->signature == OS_COND_MAGIC_SIG );
assert( mutex->signature == OS_MUTEX_MAGIC_SIG );
#endif
#if HAVE_LKST
if (ospl_lkst_enabled)
lkst_track_op (mutex, LKST_UNLOCK, mach_absolute_time (), 0);
@ -263,10 +232,6 @@ os_result os_condTimedWait (os_cond *cond, os_mutex *mutex, const os_time *time)
assert (cond != NULL);
assert (mutex != NULL);
assert (time != NULL);
#ifdef OSPL_STRICT_MEM
assert( cond->signature == OS_COND_MAGIC_SIG );
assert( mutex->signature == OS_MUTEX_MAGIC_SIG );
#endif
(void) gettimeofday (&tv, NULL);
@ -300,9 +265,7 @@ os_result os_condTimedWait (os_cond *cond, os_mutex *mutex, const os_time *time)
void os_condSignal (os_cond *cond)
{
assert (cond != NULL);
#ifdef OSPL_STRICT_MEM
assert( cond->signature == OS_COND_MAGIC_SIG );
#endif
if (pthread_cond_signal (&cond->cond) != 0)
abort();
}
@ -310,47 +273,86 @@ void os_condSignal (os_cond *cond)
void os_condBroadcast (os_cond *cond)
{
assert (cond != NULL);
#ifdef OSPL_STRICT_MEM
assert( cond->signature == OS_COND_MAGIC_SIG );
#endif
if (pthread_cond_broadcast (&cond->cond) != 0)
abort();
}
void os_rwlockInit(os_rwlock *rwlock)
{
os_mutexInit (&rwlock->mutex);
int err = 0;
assert(rwlock != NULL);
/* process-shared attribute is set to PTHREAD_PROCESS_PRIVATE by default */
if ((err = pthread_rwlock_init(&rwlock->rwlock, NULL)) != 0) {
abort();
}
}
void os_rwlockDestroy(os_rwlock *rwlock)
{
int err;
assert(rwlock != NULL);
os_mutexDestroy (&rwlock->mutex);
if ((err = pthread_rwlock_destroy(&rwlock->rwlock)) != 0) {
abort();
}
}
void os_rwlockRead(os_rwlock *rwlock)
{
os_mutexLock (&rwlock->mutex);
int err;
assert(rwlock != NULL);
err = pthread_rwlock_rdlock(&rwlock->rwlock);
assert(err == 0);
}
void os_rwlockWrite(os_rwlock *rwlock)
{
os_mutexLock (&rwlock->mutex);
int err;
assert(rwlock != NULL);
err = pthread_rwlock_wrlock(&rwlock->rwlock);
assert(err == 0);
}
os_result os_rwlockTryRead(os_rwlock *rwlock)
{
return os_mutexTryLock (&rwlock->mutex);
int err;
assert(rwlock != NULL);
err = pthread_rwlock_tryrdlock(&rwlock->rwlock);
assert(err == 0 || err == EBUSY);
return err == 0 ? os_resultSuccess : os_resultBusy;
}
os_result os_rwlockTryWrite(os_rwlock *rwlock)
{
return os_mutexTryLock (&rwlock->mutex);
int err;
assert(rwlock != NULL);
err = pthread_rwlock_trywrlock(&rwlock->rwlock);
assert(err == 0 || err == EBUSY);
return err == 0 ? os_resultSuccess : os_resultBusy;
}
void os_rwlockUnlock(os_rwlock *rwlock)
{
os_mutexUnlock (&rwlock->mutex);
int err;
assert(rwlock != NULL);
err = pthread_rwlock_unlock(&rwlock->rwlock);
assert(err == 0);
}
void

View file

@ -16,23 +16,14 @@ void os_mutexInit(
_Out_ os_mutex *mutex)
{
assert(mutex != NULL);
#ifdef OSPL_STRICT_MEM
assert(mutex->signature != OS_MUTEX_MAGIC_SIG);
#endif
InitializeSRWLock(&mutex->lock);
#ifdef OSPL_STRICT_MEM
mutex->signature = OS_MUTEX_MAGIC_SIG;
#endif
}
void os_mutexDestroy(
_Inout_ _Post_invalid_ os_mutex *mutex)
{
assert(mutex != NULL);
#ifdef OSPL_STRICT_MEM
assert(mutex->signature == OS_MUTEX_MAGIC_SIG);
mutex->signature = 0;
#endif
}
_Acquires_nonreentrant_lock_(&mutex->lock)
@ -40,9 +31,7 @@ void os_mutexLock(
_Inout_ os_mutex *mutex)
{
assert(mutex != NULL);
#ifdef OSPL_STRICT_MEM
assert(mutex->signature == OS_MUTEX_MAGIC_SIG);
#endif
AcquireSRWLockExclusive(&mutex->lock);
}
@ -62,9 +51,7 @@ os_mutexTryLock(
_Inout_ os_mutex *mutex)
{
assert(mutex != NULL);
#ifdef OSPL_STRICT_MEM
assert(mutex->signature == OS_MUTEX_MAGIC_SIG);
#endif
return TryAcquireSRWLockExclusive(&mutex->lock) ? os_resultSuccess : os_resultBusy;
}
@ -73,9 +60,7 @@ void os_mutexUnlock(
_Inout_ os_mutex *mutex)
{
assert(mutex != NULL);
#ifdef OSPL_STRICT_MEM
assert(mutex->signature == OS_MUTEX_MAGIC_SIG);
#endif
ReleaseSRWLockExclusive(&mutex->lock);
}
@ -85,34 +70,22 @@ void os_condInit(
{
assert(cond != NULL);
assert(dummymtx != NULL);
#ifdef OSPL_STRICT_MEM
assert(cond->signature != OS_COND_MAGIC_SIG);
#endif
(void)dummymtx;
InitializeConditionVariable(&cond->cond);
#ifdef OSPL_STRICT_MEM
cond->signature = OS_COND_MAGIC_SIG;
#endif
}
void os_condDestroy(
_Inout_ _Post_invalid_ os_cond *cond)
{
assert(cond != NULL);
#ifdef OSPL_STRICT_MEM
assert(cond->signature == OS_COND_MAGIC_SIG);
cond->signature = 0;
#endif
}
void os_condWait(os_cond *cond, os_mutex *mutex)
{
assert(cond != NULL);
assert(mutex != NULL);
#ifdef OSPL_STRICT_MEM
assert(cond->signature == OS_COND_MAGIC_SIG);
assert(mutex->signature == OS_MUTEX_MAGIC_SIG);
#endif
if (!SleepConditionVariableSRW(&cond->cond, &mutex->lock, INFINITE, 0)) {
abort();
}
@ -123,67 +96,50 @@ os_result os_condTimedWait(os_cond *cond, os_mutex *mutex, const os_time *time)
DWORD timems;
assert(cond != NULL);
assert(mutex != NULL);
#ifdef OSPL_STRICT_MEM
assert(cond->signature == OS_COND_MAGIC_SIG);
assert(mutex->signature == OS_MUTEX_MAGIC_SIG);
#endif
timems = time->tv_sec * 1000 + (time->tv_nsec + 999999999) / 1000000;
if (SleepConditionVariableSRW(&cond->cond, &mutex->lock, timems, 0))
if (SleepConditionVariableSRW(&cond->cond, &mutex->lock, timems, 0)) {
return os_resultSuccess;
else if (GetLastError() != ERROR_TIMEOUT)
} else if (GetLastError() != ERROR_TIMEOUT) {
abort();
else if (timems != INFINITE)
} else if (timems != INFINITE) {
return os_resultTimeout;
else
} else {
return os_resultSuccess;
}
}
void os_condSignal(os_cond *cond)
{
assert(cond != NULL);
#ifdef OSPL_STRICT_MEM
assert(cond->signature == OS_COND_MAGIC_SIG);
#endif
WakeConditionVariable(&cond->cond);
}
void os_condBroadcast(os_cond *cond)
{
assert(cond != NULL);
#ifdef OSPL_STRICT_MEM
assert(cond->signature == OS_COND_MAGIC_SIG);
#endif
WakeAllConditionVariable(&cond->cond);
}
void os_rwlockInit(_Out_ os_rwlock *rwlock)
{
assert(rwlock);
#ifdef OSPL_STRICT_MEM
assert(rwlock->signature != OS_RWLOCK_MAGIC_SIG);
#endif
InitializeSRWLock(&rwlock->lock);
rwlock->state = 0;
#ifdef OSPL_STRICT_MEM
rwlock->signature = OS_RWLOCK_MAGIC_SIG;
#endif
}
void os_rwlockDestroy(_Inout_ _Post_invalid_ os_rwlock *rwlock)
{
assert(rwlock);
#ifdef OSPL_STRICT_MEM
assert(rwlock->signature != OS_RWLOCK_MAGIC_SIG);
rwlock->signature = 0;
#endif
}
void os_rwlockRead(os_rwlock *rwlock)
{
assert(rwlock);
#ifdef OSPL_STRICT_MEM
assert(rwlock->signature != OS_RWLOCK_MAGIC_SIG);
#endif
AcquireSRWLockShared(&rwlock->lock);
rwlock->state = 1;
}
@ -191,9 +147,7 @@ void os_rwlockRead(os_rwlock *rwlock)
void os_rwlockWrite(os_rwlock *rwlock)
{
assert(rwlock);
#ifdef OSPL_STRICT_MEM
assert(rwlock->signature != OS_RWLOCK_MAGIC_SIG);
#endif
AcquireSRWLockExclusive(&rwlock->lock);
rwlock->state = -1;
}
@ -201,44 +155,35 @@ void os_rwlockWrite(os_rwlock *rwlock)
os_result os_rwlockTryRead(os_rwlock *rwlock)
{
assert(rwlock);
#ifdef OSPL_STRICT_MEM
assert(rwlock->signature != OS_RWLOCK_MAGIC_SIG);
#endif
if (TryAcquireSRWLockShared(&rwlock->lock)) {
rwlock->state = 1;
return os_resultSuccess;
}
else {
return os_resultBusy;
}
}
os_result os_rwlockTryWrite(os_rwlock *rwlock)
{
assert(rwlock);
#ifdef OSPL_STRICT_MEM
assert(rwlock->signature != OS_RWLOCK_MAGIC_SIG);
#endif
if (TryAcquireSRWLockExclusive(&rwlock->lock)) {
rwlock->state = -1;
return os_resultSuccess;
}
else {
return os_resultBusy;
}
}
void os_rwlockUnlock(os_rwlock *rwlock)
{
assert(rwlock);
#ifdef OSPL_STRICT_MEM
assert(rwlock->signature != OS_RWLOCK_MAGIC_SIG);
#endif
assert(rwlock->state != 0);
if (rwlock->state > 0) {
ReleaseSRWLockShared(&rwlock->lock);
}
else {
} else {
ReleaseSRWLockExclusive(&rwlock->lock);
}
}