From ac020f62f768b7d92a4c217436a35c01f667e277 Mon Sep 17 00:00:00 2001 From: Jeroen Koekkoek Date: Tue, 20 Nov 2018 13:31:32 +0100 Subject: [PATCH] Add read-write locks for POSIX Signed-off-by: Jeroen Koekkoek --- src/os/CMakeLists.txt | 1 + src/os/include/os/posix/os_platform_sync.h | 14 +- src/os/src/posix/os_platform_sync.c | 132 ++++++------ src/os/src/windows/os_platform_sync.c | 235 ++++++++------------- 4 files changed, 159 insertions(+), 223 deletions(-) diff --git a/src/os/CMakeLists.txt b/src/os/CMakeLists.txt index 2fce835..f8d93c1 100644 --- a/src/os/CMakeLists.txt +++ b/src/os/CMakeLists.txt @@ -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) diff --git a/src/os/include/os/posix/os_platform_sync.h b/src/os/include/os/posix/os_platform_sync.h index dc73db6..cd7987d 100644 --- a/src/os/include/os/posix/os_platform_sync.h +++ b/src/os/include/os/posix/os_platform_sync.h @@ -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; diff --git a/src/os/src/posix/os_platform_sync.c b/src/os/src/posix/os_platform_sync.c index abc8c29..dccf259 100644 --- a/src/os/src/posix/os_platform_sync.c +++ b/src/os/src/posix/os_platform_sync.c @@ -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) +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) +void os_rwlockDestroy(os_rwlock *rwlock) { - assert (rwlock != NULL); - os_mutexDestroy (&rwlock->mutex); + int err; + + assert(rwlock != NULL); + + if ((err = pthread_rwlock_destroy(&rwlock->rwlock)) != 0) { + abort(); + } } -void os_rwlockRead (os_rwlock *rwlock) +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) +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) +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) +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) +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 diff --git a/src/os/src/windows/os_platform_sync.c b/src/os/src/windows/os_platform_sync.c index 34a5141..5084b13 100644 --- a/src/os/src/windows/os_platform_sync.c +++ b/src/os/src/windows/os_platform_sync.c @@ -13,234 +13,179 @@ #include "os/os.h" void os_mutexInit( - _Out_ os_mutex *mutex) + _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 + assert(mutex != NULL); + + InitializeSRWLock(&mutex->lock); } void os_mutexDestroy( - _Inout_ _Post_invalid_ os_mutex *mutex) + _Inout_ _Post_invalid_ os_mutex *mutex) { - assert(mutex != NULL); -#ifdef OSPL_STRICT_MEM - assert(mutex->signature == OS_MUTEX_MAGIC_SIG); - mutex->signature = 0; -#endif + assert(mutex != NULL); } _Acquires_nonreentrant_lock_(&mutex->lock) void os_mutexLock( - _Inout_ os_mutex *mutex) + _Inout_ os_mutex *mutex) { - assert(mutex != NULL); -#ifdef OSPL_STRICT_MEM - assert(mutex->signature == OS_MUTEX_MAGIC_SIG); -#endif - AcquireSRWLockExclusive(&mutex->lock); + assert(mutex != NULL); + + AcquireSRWLockExclusive(&mutex->lock); } _Check_return_ _When_(return == os_resultSuccess, _Acquires_nonreentrant_lock_(&mutex->lock)) os_result os_mutexLock_s( - _Inout_ os_mutex *mutex) + _Inout_ os_mutex *mutex) { - os_mutexLock(mutex); - return os_resultSuccess; + os_mutexLock(mutex); + return os_resultSuccess; } _Check_return_ _When_(return == os_resultSuccess, _Acquires_nonreentrant_lock_(&mutex->lock)) os_result os_mutexTryLock( - _Inout_ os_mutex *mutex) + _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; + assert(mutex != NULL); + + return TryAcquireSRWLockExclusive(&mutex->lock) ? os_resultSuccess : os_resultBusy; } _Releases_nonreentrant_lock_(&mutex->lock) void os_mutexUnlock( - _Inout_ os_mutex *mutex) + _Inout_ os_mutex *mutex) { - assert(mutex != NULL); -#ifdef OSPL_STRICT_MEM - assert(mutex->signature == OS_MUTEX_MAGIC_SIG); -#endif - ReleaseSRWLockExclusive(&mutex->lock); + assert(mutex != NULL); + + ReleaseSRWLockExclusive(&mutex->lock); } void os_condInit( _Out_ os_cond *cond, _In_ os_mutex *dummymtx) { - 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 + assert(cond != NULL); + assert(dummymtx != NULL); + + (void)dummymtx; + InitializeConditionVariable(&cond->cond); } 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 + assert(cond != NULL); } 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(); - } + assert(cond != NULL); + assert(mutex != NULL); + + if (!SleepConditionVariableSRW(&cond->cond, &mutex->lock, INFINITE, 0)) { + abort(); + } } 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)) - return os_resultSuccess; - else if (GetLastError() != ERROR_TIMEOUT) - abort(); - else if (timems != INFINITE) - return os_resultTimeout; - else - return os_resultSuccess; + DWORD timems; + assert(cond != NULL); + assert(mutex != NULL); + + timems = time->tv_sec * 1000 + (time->tv_nsec + 999999999) / 1000000; + if (SleepConditionVariableSRW(&cond->cond, &mutex->lock, timems, 0)) { + return os_resultSuccess; + } else if (GetLastError() != ERROR_TIMEOUT) { + abort(); + } else if (timems != INFINITE) { + return os_resultTimeout; + } 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); + assert(cond != NULL); + + 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); + assert(cond != NULL); + + 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 + assert(rwlock); + + InitializeSRWLock(&rwlock->lock); + rwlock->state = 0; } 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 + assert(rwlock); } 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; + assert(rwlock); + + AcquireSRWLockShared(&rwlock->lock); + rwlock->state = 1; } 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; + assert(rwlock); + + AcquireSRWLockExclusive(&rwlock->lock); + rwlock->state = -1; } 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; - } + assert(rwlock); + + if (TryAcquireSRWLockShared(&rwlock->lock)) { + rwlock->state = 1; + return os_resultSuccess; + } + + 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; - } + assert(rwlock); + + if (TryAcquireSRWLockExclusive(&rwlock->lock)) { + rwlock->state = -1; + return os_resultSuccess; + } + + 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 { - ReleaseSRWLockExclusive(&rwlock->lock); - } + assert(rwlock); + + assert(rwlock->state != 0); + if (rwlock->state > 0) { + ReleaseSRWLockShared(&rwlock->lock); + } else { + ReleaseSRWLockExclusive(&rwlock->lock); + } } struct os__onceWrapper {