From 1fae8c16a8c0634ffa44b4a2e25f3be4899ea7e2 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 17 Nov 2018 05:31:29 -0800 Subject: [PATCH] Convert threads.c to C++ Also vastly simplify and remove related code. --- CMakeLists.txt | 5 +- OpenAL32/Include/alBuffer.h | 1 - common/rwlock.c | 59 ------------ common/rwlock.h | 32 ------- common/{threads.c => threads.cpp} | 18 ++-- common/uintmap.c | 182 -------------------------------------- common/uintmap.h | 76 ++++++++-------- 7 files changed, 42 insertions(+), 331 deletions(-) delete mode 100644 common/rwlock.c delete mode 100644 common/rwlock.h rename common/{threads.c => threads.cpp} (95%) delete mode 100644 common/uintmap.c rewrite common/uintmap.h (91%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 768856df..79530117 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -764,12 +764,9 @@ SET(COMMON_OBJS common/atomic.h common/bool.h common/math_defs.h - common/rwlock.c - common/rwlock.h common/static_assert.h - common/threads.c + common/threads.cpp common/threads.h - common/uintmap.c common/uintmap.h ) SET(OPENAL_OBJS diff --git a/OpenAL32/Include/alBuffer.h b/OpenAL32/Include/alBuffer.h index fbe3e6e5..f264caa5 100644 --- a/OpenAL32/Include/alBuffer.h +++ b/OpenAL32/Include/alBuffer.h @@ -7,7 +7,6 @@ #include "inprogext.h" #include "atomic.h" -#include "rwlock.h" #ifdef __cplusplus extern "C" { diff --git a/common/rwlock.c b/common/rwlock.c deleted file mode 100644 index 44237282..00000000 --- a/common/rwlock.c +++ /dev/null @@ -1,59 +0,0 @@ - -#include "config.h" - -#include "rwlock.h" - -#include "bool.h" -#include "atomic.h" -#include "threads.h" - - -/* A simple spinlock. Yield the thread while the given integer is set by - * another. Could probably be improved... */ -#define LOCK(l) do { \ - while(ATOMIC_EXCHANGE(&(l), 1, almemory_order_acq_rel) == true) \ - althrd_yield(); \ -} while(0) -#define UNLOCK(l) ATOMIC_STORE(&(l), 0, almemory_order_release) - - -void RWLockInit(RWLock *lock) -{ - InitRef(&lock->read_count, 0); - InitRef(&lock->write_count, 0); - ATOMIC_INIT(&lock->read_lock, 0); - ATOMIC_INIT(&lock->read_entry_lock, 0); - ATOMIC_INIT(&lock->write_lock, 0); -} - -void ReadLock(RWLock *lock) -{ - LOCK(lock->read_entry_lock); - LOCK(lock->read_lock); - /* NOTE: ATOMIC_ADD returns the *old* value! */ - if(ATOMIC_ADD(&lock->read_count, 1, almemory_order_acq_rel) == 0) - LOCK(lock->write_lock); - UNLOCK(lock->read_lock); - UNLOCK(lock->read_entry_lock); -} - -void ReadUnlock(RWLock *lock) -{ - /* NOTE: ATOMIC_SUB returns the *old* value! */ - if(ATOMIC_SUB(&lock->read_count, 1, almemory_order_acq_rel) == 1) - UNLOCK(lock->write_lock); -} - -void WriteLock(RWLock *lock) -{ - if(ATOMIC_ADD(&lock->write_count, 1, almemory_order_acq_rel) == 0) - LOCK(lock->read_lock); - LOCK(lock->write_lock); -} - -void WriteUnlock(RWLock *lock) -{ - UNLOCK(lock->write_lock); - if(ATOMIC_SUB(&lock->write_count, 1, almemory_order_acq_rel) == 1) - UNLOCK(lock->read_lock); -} diff --git a/common/rwlock.h b/common/rwlock.h deleted file mode 100644 index fee1b070..00000000 --- a/common/rwlock.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef AL_RWLOCK_H -#define AL_RWLOCK_H - -#include "bool.h" -#include "atomic.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - RefCount read_count; - RefCount write_count; - ATOMIC(int) read_lock; - ATOMIC(int) read_entry_lock; - ATOMIC(int) write_lock; -} RWLock; -#define RWLOCK_STATIC_INITIALIZE { ATOMIC_INIT_STATIC(0), ATOMIC_INIT_STATIC(0), \ - ATOMIC_INIT_STATIC(0), ATOMIC_INIT_STATIC(0), \ - ATOMIC_INIT_STATIC(0) } - -void RWLockInit(RWLock *lock); -void ReadLock(RWLock *lock); -void ReadUnlock(RWLock *lock); -void WriteLock(RWLock *lock); -void WriteUnlock(RWLock *lock); - -#ifdef __cplusplus -} -#endif - -#endif /* AL_RWLOCK_H */ diff --git a/common/threads.c b/common/threads.cpp similarity index 95% rename from common/threads.c rename to common/threads.cpp index b0f90bc5..48f62274 100644 --- a/common/threads.c +++ b/common/threads.cpp @@ -29,11 +29,6 @@ #include "uintmap.h" -extern inline althrd_t althrd_current(void); -extern inline int althrd_equal(althrd_t thr0, althrd_t thr1); -extern inline void althrd_yield(void); - - #ifndef UNUSED #if defined(__cplusplus) #define UNUSED(x) @@ -62,7 +57,7 @@ extern inline void althrd_yield(void); * referenced by multiple different HANDLEs. This map allows retrieving the * original handle which is needed to join the thread and get its return value. */ -static UIntMap ThrdIdHandle = UINTMAP_STATIC_INITIALIZE; +static ThrSafeMap ThrdIdHandle{}; void althrd_setname(althrd_t thr, const char *name) @@ -116,7 +111,7 @@ int althrd_create(althrd_t *thr, althrd_start_t func, void *arg) DWORD thrid; HANDLE hdl; - cntr = malloc(sizeof(*cntr)); + cntr = static_cast(malloc(sizeof(*cntr))); if(!cntr) return althrd_nomem; cntr->func = func; @@ -128,7 +123,7 @@ int althrd_create(althrd_t *thr, althrd_start_t func, void *arg) free(cntr); return althrd_error; } - InsertUIntMapEntry(&ThrdIdHandle, thrid, hdl); + ThrdIdHandle.InsertEntry(thrid, hdl); *thr = thrid; return althrd_success; @@ -136,7 +131,7 @@ int althrd_create(althrd_t *thr, althrd_start_t func, void *arg) int althrd_detach(althrd_t thr) { - HANDLE hdl = RemoveUIntMapKey(&ThrdIdHandle, thr); + HANDLE hdl = ThrdIdHandle.RemoveKey(thr); if(!hdl) return althrd_error; CloseHandle(hdl); @@ -147,7 +142,7 @@ int althrd_join(althrd_t thr, int *res) { DWORD code; - HANDLE hdl = RemoveUIntMapKey(&ThrdIdHandle, thr); + HANDLE hdl = ThrdIdHandle.RemoveKey(thr); if(!hdl) return althrd_error; WaitForSingleObject(hdl, INFINITE); @@ -215,7 +210,6 @@ int alsem_trywait(alsem_t *sem) void althrd_deinit(void) { - ResetUIntMap(&ThrdIdHandle); } #else @@ -270,7 +264,7 @@ int althrd_create(althrd_t *thr, althrd_start_t func, void *arg) size_t stackmult = 1; int err; - cntr = malloc(sizeof(*cntr)); + cntr = static_cast(malloc(sizeof(*cntr))); if(!cntr) return althrd_nomem; if(pthread_attr_init(&attr) != 0) diff --git a/common/uintmap.c b/common/uintmap.c deleted file mode 100644 index 3654779c..00000000 --- a/common/uintmap.c +++ /dev/null @@ -1,182 +0,0 @@ - -#include "config.h" - -#include "uintmap.h" - -#include -#include - -#include "almalloc.h" - - -extern inline void LockUIntMapRead(UIntMap *map); -extern inline void UnlockUIntMapRead(UIntMap *map); -extern inline void LockUIntMapWrite(UIntMap *map); -extern inline void UnlockUIntMapWrite(UIntMap *map); - - -void InitUIntMap(UIntMap *map, ALsizei limit) -{ - map->keys = NULL; - map->values = NULL; - map->size = 0; - map->capacity = 0; - map->limit = limit; - RWLockInit(&map->lock); -} - -void ResetUIntMap(UIntMap *map) -{ - WriteLock(&map->lock); - al_free(map->keys); - map->keys = NULL; - map->values = NULL; - map->size = 0; - map->capacity = 0; - WriteUnlock(&map->lock); -} - -ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value) -{ - ALsizei pos = 0; - - WriteLock(&map->lock); - if(map->size > 0) - { - ALsizei count = map->size; - do { - ALsizei step = count>>1; - ALsizei i = pos+step; - if(map->keys[i] >= key) - count = step; - else - { - pos = i+1; - count -= step+1; - } - } while(count > 0); - } - - if(pos == map->size || map->keys[pos] != key) - { - if(map->size >= map->limit) - { - WriteUnlock(&map->lock); - return AL_OUT_OF_MEMORY; - } - - if(map->size == map->capacity) - { - ALuint *keys = NULL; - ALvoid **values; - ALsizei newcap, keylen; - - newcap = (map->capacity ? (map->capacity<<1) : 4); - if(map->limit > 0 && newcap > map->limit) - newcap = map->limit; - if(newcap > map->capacity) - { - /* Round the memory size for keys up to a multiple of the - * pointer size. - */ - keylen = newcap * sizeof(map->keys[0]); - keylen += sizeof(map->values[0]) - 1; - keylen -= keylen%sizeof(map->values[0]); - - keys = al_malloc(16, keylen + newcap*sizeof(map->values[0])); - } - if(!keys) - { - WriteUnlock(&map->lock); - return AL_OUT_OF_MEMORY; - } - values = (ALvoid**)((ALbyte*)keys + keylen); - - if(map->keys) - { - memcpy(keys, map->keys, map->size*sizeof(map->keys[0])); - memcpy(values, map->values, map->size*sizeof(map->values[0])); - } - al_free(map->keys); - map->keys = keys; - map->values = values; - map->capacity = newcap; - } - - if(pos < map->size) - { - memmove(&map->keys[pos+1], &map->keys[pos], - (map->size-pos)*sizeof(map->keys[0])); - memmove(&map->values[pos+1], &map->values[pos], - (map->size-pos)*sizeof(map->values[0])); - } - map->size++; - } - map->keys[pos] = key; - map->values[pos] = value; - WriteUnlock(&map->lock); - - return AL_NO_ERROR; -} - -ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key) -{ - ALvoid *ptr = NULL; - WriteLock(&map->lock); - if(map->size > 0) - { - ALsizei pos = 0; - ALsizei count = map->size; - do { - ALsizei step = count>>1; - ALsizei i = pos+step; - if(map->keys[i] >= key) - count = step; - else - { - pos = i+1; - count -= step+1; - } - } while(count > 0); - if(pos < map->size && map->keys[pos] == key) - { - ptr = map->values[pos]; - if(pos < map->size-1) - { - memmove(&map->keys[pos], &map->keys[pos+1], - (map->size-1-pos)*sizeof(map->keys[0])); - memmove(&map->values[pos], &map->values[pos+1], - (map->size-1-pos)*sizeof(map->values[0])); - } - map->size--; - } - } - WriteUnlock(&map->lock); - return ptr; -} - -ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key) -{ - ALvoid *ptr = NULL; - ReadLock(&map->lock); - if(map->size > 0) - { - ALsizei pos = 0; - ALsizei count = map->size; - do { - ALsizei step = count>>1; - ALsizei i = pos+step; - if(map->keys[i] >= key) - count = step; - else - { - pos = i+1; - count -= step+1; - } - } while(count > 0); - if(pos < map->size && map->keys[pos] == key) - ptr = map->values[pos]; - } - ReadUnlock(&map->lock); - return ptr; -} diff --git a/common/uintmap.h b/common/uintmap.h dissimilarity index 91% index 32868653..0646d2b5 100644 --- a/common/uintmap.h +++ b/common/uintmap.h @@ -1,41 +1,35 @@ -#ifndef AL_UINTMAP_H -#define AL_UINTMAP_H - -#include - -#include "AL/al.h" -#include "rwlock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct UIntMap { - ALuint *keys; - /* Shares memory with keys. */ - ALvoid **values; - - ALsizei size; - ALsizei capacity; - ALsizei limit; - RWLock lock; -} UIntMap; -#define UINTMAP_STATIC_INITIALIZE_N(_n) { NULL, NULL, 0, 0, (_n), RWLOCK_STATIC_INITIALIZE } -#define UINTMAP_STATIC_INITIALIZE UINTMAP_STATIC_INITIALIZE_N(INT_MAX) - -void InitUIntMap(UIntMap *map, ALsizei limit); -void ResetUIntMap(UIntMap *map); -ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value); -ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key); -ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key); - -inline void LockUIntMapRead(UIntMap *map) { ReadLock(&map->lock); } -inline void UnlockUIntMapRead(UIntMap *map) { ReadUnlock(&map->lock); } -inline void LockUIntMapWrite(UIntMap *map) { WriteLock(&map->lock); } -inline void UnlockUIntMapWrite(UIntMap *map) { WriteUnlock(&map->lock); } - -#ifdef __cplusplus -} -#endif - -#endif /* AL_UINTMAP_H */ +#ifndef AL_UINTMAP_H +#define AL_UINTMAP_H + +#include +#include + +#include "AL/al.h" + +template +class ThrSafeMap { + std::unordered_map mValues; + std::mutex mLock; + +public: + void InsertEntry(T0 key, T1 value) noexcept + { + std::lock_guard _{mLock}; + mValues[key] = value; + } + + T1 RemoveKey(T0 key) noexcept + { + T1 retval{}; + + std::lock_guard _{mLock}; + auto iter = mValues.find(key); + if(iter != mValues.end()) + retval = iter->second; + mValues.erase(iter); + + return retval; + } +}; + +#endif /* AL_UINTMAP_H */ -- 2.11.4.GIT