diff options
-rw-r--r-- | Alc/helpers.c | 187 | ||||
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | common/rwlock.c | 62 | ||||
-rw-r--r-- | common/uintmap.c | 144 | ||||
-rw-r--r-- | include/rwlock.h (renamed from Alc/rwlock.h) | 0 | ||||
-rw-r--r-- | include/uintmap.h (renamed from Alc/uintmap.h) | 0 |
6 files changed, 208 insertions, 187 deletions
diff --git a/Alc/helpers.c b/Alc/helpers.c index 07e87815..4b5eceb7 100644 --- a/Alc/helpers.c +++ b/Alc/helpers.c @@ -93,11 +93,6 @@ DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, #include "threads.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); - extern inline ALuint NextPowerOf2(ALuint value); extern inline ALint fastf2i(ALfloat f); extern inline ALuint fastf2u(ALfloat f); @@ -584,57 +579,6 @@ void SetRTPriority(void) } -static void Lock(volatile int *l) -{ - while(ExchangeInt(l, true) == true) - althrd_yield(); -} - -static void Unlock(volatile int *l) -{ - ExchangeInt(l, false); -} - -void RWLockInit(RWLock *lock) -{ - lock->read_count = 0; - lock->write_count = 0; - lock->read_lock = false; - lock->read_entry_lock = false; - lock->write_lock = false; -} - -void ReadLock(RWLock *lock) -{ - Lock(&lock->read_entry_lock); - Lock(&lock->read_lock); - if(IncrementRef(&lock->read_count) == 1) - Lock(&lock->write_lock); - Unlock(&lock->read_lock); - Unlock(&lock->read_entry_lock); -} - -void ReadUnlock(RWLock *lock) -{ - if(DecrementRef(&lock->read_count) == 0) - Unlock(&lock->write_lock); -} - -void WriteLock(RWLock *lock) -{ - if(IncrementRef(&lock->write_count) == 1) - Lock(&lock->read_lock); - Lock(&lock->write_lock); -} - -void WriteUnlock(RWLock *lock) -{ - Unlock(&lock->write_lock); - if(DecrementRef(&lock->write_count) == 0) - Unlock(&lock->read_lock); -} - - ALboolean vector_reserve(void *ptr, size_t base_size, size_t obj_count, size_t obj_size, ALboolean exact) { vector_ *vecptr = ptr; @@ -800,134 +744,3 @@ void al_string_copy_wcstr(al_string *str, const wchar_t *from) } } #endif - - -void InitUIntMap(UIntMap *map, ALsizei limit) -{ - map->array = NULL; - map->size = 0; - map->maxsize = 0; - map->limit = limit; - RWLockInit(&map->lock); -} - -void ResetUIntMap(UIntMap *map) -{ - WriteLock(&map->lock); - free(map->array); - map->array = NULL; - map->size = 0; - map->maxsize = 0; - WriteUnlock(&map->lock); -} - -ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value) -{ - ALsizei pos = 0; - - WriteLock(&map->lock); - if(map->size > 0) - { - ALsizei low = 0; - ALsizei high = map->size - 1; - while(low < high) - { - ALsizei mid = low + (high-low)/2; - if(map->array[mid].key < key) - low = mid + 1; - else - high = mid; - } - if(map->array[low].key < key) - low++; - pos = low; - } - - if(pos == map->size || map->array[pos].key != key) - { - if(map->size == map->limit) - { - WriteUnlock(&map->lock); - return AL_OUT_OF_MEMORY; - } - - if(map->size == map->maxsize) - { - ALvoid *temp = NULL; - ALsizei newsize; - - newsize = (map->maxsize ? (map->maxsize<<1) : 4); - if(newsize >= map->maxsize) - temp = realloc(map->array, newsize*sizeof(map->array[0])); - if(!temp) - { - WriteUnlock(&map->lock); - return AL_OUT_OF_MEMORY; - } - map->array = temp; - map->maxsize = newsize; - } - - if(pos < map->size) - memmove(&map->array[pos+1], &map->array[pos], - (map->size-pos)*sizeof(map->array[0])); - map->size++; - } - map->array[pos].key = key; - map->array[pos].value = 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 low = 0; - ALsizei high = map->size - 1; - while(low < high) - { - ALsizei mid = low + (high-low)/2; - if(map->array[mid].key < key) - low = mid + 1; - else - high = mid; - } - if(map->array[low].key == key) - { - ptr = map->array[low].value; - if(low < map->size-1) - memmove(&map->array[low], &map->array[low+1], - (map->size-1-low)*sizeof(map->array[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 low = 0; - ALsizei high = map->size - 1; - while(low < high) - { - ALsizei mid = low + (high-low)/2; - if(map->array[mid].key < key) - low = mid + 1; - else - high = mid; - } - if(map->array[low].key == key) - ptr = map->array[low].value; - } - ReadUnlock(&map->lock); - return ptr; -} diff --git a/CMakeLists.txt b/CMakeLists.txt index e6e0761e..aae35f5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -499,7 +499,9 @@ ENDIF() SET(COMMON_OBJS common/atomic.c + common/rwlock.c common/threads.c + common/uintmap.c ) SET(OPENAL_OBJS OpenAL32/alAuxEffectSlot.c OpenAL32/alBuffer.c diff --git a/common/rwlock.c b/common/rwlock.c new file mode 100644 index 00000000..b967db0a --- /dev/null +++ b/common/rwlock.c @@ -0,0 +1,62 @@ + +#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... */ +static void Lock(volatile int *l) +{ + while(ExchangeInt(l, true) == true) + althrd_yield(); +} + +static void Unlock(volatile int *l) +{ + ExchangeInt(l, false); +} + + +void RWLockInit(RWLock *lock) +{ + lock->read_count = 0; + lock->write_count = 0; + lock->read_lock = false; + lock->read_entry_lock = false; + lock->write_lock = false; +} + +void ReadLock(RWLock *lock) +{ + Lock(&lock->read_entry_lock); + Lock(&lock->read_lock); + if(IncrementRef(&lock->read_count) == 1) + Lock(&lock->write_lock); + Unlock(&lock->read_lock); + Unlock(&lock->read_entry_lock); +} + +void ReadUnlock(RWLock *lock) +{ + if(DecrementRef(&lock->read_count) == 0) + Unlock(&lock->write_lock); +} + +void WriteLock(RWLock *lock) +{ + if(IncrementRef(&lock->write_count) == 1) + Lock(&lock->read_lock); + Lock(&lock->write_lock); +} + +void WriteUnlock(RWLock *lock) +{ + Unlock(&lock->write_lock); + if(DecrementRef(&lock->write_count) == 0) + Unlock(&lock->read_lock); +} diff --git a/common/uintmap.c b/common/uintmap.c new file mode 100644 index 00000000..b7a9a29c --- /dev/null +++ b/common/uintmap.c @@ -0,0 +1,144 @@ + +#include "config.h" + +#include "uintmap.h" + +#include <stdlib.h> +#include <string.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->array = NULL; + map->size = 0; + map->maxsize = 0; + map->limit = limit; + RWLockInit(&map->lock); +} + +void ResetUIntMap(UIntMap *map) +{ + WriteLock(&map->lock); + free(map->array); + map->array = NULL; + map->size = 0; + map->maxsize = 0; + WriteUnlock(&map->lock); +} + +ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value) +{ + ALsizei pos = 0; + + WriteLock(&map->lock); + if(map->size > 0) + { + ALsizei low = 0; + ALsizei high = map->size - 1; + while(low < high) + { + ALsizei mid = low + (high-low)/2; + if(map->array[mid].key < key) + low = mid + 1; + else + high = mid; + } + if(map->array[low].key < key) + low++; + pos = low; + } + + if(pos == map->size || map->array[pos].key != key) + { + if(map->size == map->limit) + { + WriteUnlock(&map->lock); + return AL_OUT_OF_MEMORY; + } + + if(map->size == map->maxsize) + { + ALvoid *temp = NULL; + ALsizei newsize; + + newsize = (map->maxsize ? (map->maxsize<<1) : 4); + if(newsize >= map->maxsize) + temp = realloc(map->array, newsize*sizeof(map->array[0])); + if(!temp) + { + WriteUnlock(&map->lock); + return AL_OUT_OF_MEMORY; + } + map->array = temp; + map->maxsize = newsize; + } + + if(pos < map->size) + memmove(&map->array[pos+1], &map->array[pos], + (map->size-pos)*sizeof(map->array[0])); + map->size++; + } + map->array[pos].key = key; + map->array[pos].value = 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 low = 0; + ALsizei high = map->size - 1; + while(low < high) + { + ALsizei mid = low + (high-low)/2; + if(map->array[mid].key < key) + low = mid + 1; + else + high = mid; + } + if(map->array[low].key == key) + { + ptr = map->array[low].value; + if(low < map->size-1) + memmove(&map->array[low], &map->array[low+1], + (map->size-1-low)*sizeof(map->array[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 low = 0; + ALsizei high = map->size - 1; + while(low < high) + { + ALsizei mid = low + (high-low)/2; + if(map->array[mid].key < key) + low = mid + 1; + else + high = mid; + } + if(map->array[low].key == key) + ptr = map->array[low].value; + } + ReadUnlock(&map->lock); + return ptr; +} diff --git a/Alc/rwlock.h b/include/rwlock.h index 764940fa..764940fa 100644 --- a/Alc/rwlock.h +++ b/include/rwlock.h diff --git a/Alc/uintmap.h b/include/uintmap.h index 611ed39b..611ed39b 100644 --- a/Alc/uintmap.h +++ b/include/uintmap.h |