Clean up the router's PtrIntMap

This commit is contained in:
Chris Robinson 2018-10-30 13:47:01 -07:00
parent 44f91760b5
commit f747ac8882
3 changed files with 96 additions and 137 deletions

View File

@ -251,8 +251,8 @@ static std::mutex EnumerationLock;
static std::mutex ContextSwitchLock;
static std::atomic<ALCenum> LastError{ALC_NO_ERROR};
static PtrIntMap DeviceIfaceMap = PTRINTMAP_STATIC_INITIALIZE;
static PtrIntMap ContextIfaceMap = PTRINTMAP_STATIC_INITIALIZE;
static PtrIntMap DeviceIfaceMap;
static PtrIntMap ContextIfaceMap;
typedef struct EnumeratedList {
@ -306,16 +306,6 @@ static ALint GetDriverIndexForName(const EnumeratedList *list, const ALCchar *na
return -1;
}
void InitALC(void)
{
}
void ReleaseALC(void)
{
ResetPtrIntMap(&ContextIfaceMap);
ResetPtrIntMap(&DeviceIfaceMap);
}
ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename)
{
@ -371,7 +361,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename)
if(device)
{
if(InsertPtrIntMapEntry(&DeviceIfaceMap, device, idx) != ALC_NO_ERROR)
if(DeviceIfaceMap.insert(device, idx) != ALC_NO_ERROR)
{
DriverList[idx].alcCloseDevice(device);
device = nullptr;
@ -385,14 +375,14 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
{
ALint idx;
if(!device || (idx=LookupPtrIntMapKey(&DeviceIfaceMap, device)) < 0)
if(!device || (idx=DeviceIfaceMap.lookupByKey(device)) < 0)
{
LastError.store(ALC_INVALID_DEVICE);
return ALC_FALSE;
}
if(!DriverList[idx].alcCloseDevice(device))
return ALC_FALSE;
RemovePtrIntMapKey(&DeviceIfaceMap, device);
DeviceIfaceMap.removeByKey(device);
return ALC_TRUE;
}
@ -402,7 +392,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
ALCcontext *context;
ALint idx;
if(!device || (idx=LookupPtrIntMapKey(&DeviceIfaceMap, device)) < 0)
if(!device || (idx=DeviceIfaceMap.lookupByKey(device)) < 0)
{
LastError.store(ALC_INVALID_DEVICE);
return nullptr;
@ -410,7 +400,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
context = DriverList[idx].alcCreateContext(device, attrlist);
if(context)
{
if(InsertPtrIntMapEntry(&ContextIfaceMap, context, idx) != ALC_NO_ERROR)
if(ContextIfaceMap.insert(context, idx) != ALC_NO_ERROR)
{
DriverList[idx].alcDestroyContext(context);
context = nullptr;
@ -427,7 +417,7 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
std::lock_guard<std::mutex> _{ContextSwitchLock};
if(context)
{
idx = LookupPtrIntMapKey(&ContextIfaceMap, context);
idx = ContextIfaceMap.lookupByKey(context);
if(idx < 0)
{
LastError.store(ALC_INVALID_CONTEXT);
@ -465,7 +455,7 @@ ALC_API void ALC_APIENTRY alcProcessContext(ALCcontext *context)
{
if(context)
{
ALint idx = LookupPtrIntMapKey(&ContextIfaceMap, context);
ALint idx = ContextIfaceMap.lookupByKey(context);
if(idx >= 0)
return DriverList[idx].alcProcessContext(context);
}
@ -476,7 +466,7 @@ ALC_API void ALC_APIENTRY alcSuspendContext(ALCcontext *context)
{
if(context)
{
ALint idx = LookupPtrIntMapKey(&ContextIfaceMap, context);
ALint idx = ContextIfaceMap.lookupByKey(context);
if(idx >= 0)
return DriverList[idx].alcSuspendContext(context);
}
@ -487,14 +477,14 @@ ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context)
{
ALint idx;
if(!context || (idx=LookupPtrIntMapKey(&ContextIfaceMap, context)) < 0)
if(!context || (idx=ContextIfaceMap.lookupByKey(context)) < 0)
{
LastError.store(ALC_INVALID_CONTEXT);
return;
}
DriverList[idx].alcDestroyContext(context);
RemovePtrIntMapKey(&ContextIfaceMap, context);
ContextIfaceMap.removeByKey(context);
}
ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
@ -508,7 +498,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *context)
{
if(context)
{
ALint idx = LookupPtrIntMapKey(&ContextIfaceMap, context);
ALint idx = ContextIfaceMap.lookupByKey(context);
if(idx >= 0)
return DriverList[idx].alcGetContextsDevice(context);
}
@ -521,7 +511,7 @@ ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
{
if(device)
{
ALint idx = LookupPtrIntMapKey(&DeviceIfaceMap, device);
ALint idx = DeviceIfaceMap.lookupByKey(device);
if(idx < 0) return ALC_INVALID_DEVICE;
return DriverList[idx].alcGetError(device);
}
@ -535,7 +525,7 @@ ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const A
if(device)
{
ALint idx = LookupPtrIntMapKey(&DeviceIfaceMap, device);
ALint idx = DeviceIfaceMap.lookupByKey(device);
if(idx < 0)
{
LastError.store(ALC_INVALID_DEVICE);
@ -564,7 +554,7 @@ ALC_API void* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *f
{
if(device)
{
ALint idx = LookupPtrIntMapKey(&DeviceIfaceMap, device);
ALint idx = DeviceIfaceMap.lookupByKey(device);
if(idx < 0)
{
LastError.store(ALC_INVALID_DEVICE);
@ -584,7 +574,7 @@ ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *e
{
if(device)
{
ALint idx = LookupPtrIntMapKey(&DeviceIfaceMap, device);
ALint idx = DeviceIfaceMap.lookupByKey(device);
if(idx < 0)
{
LastError.store(ALC_INVALID_DEVICE);
@ -604,7 +594,7 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum para
{
if(device)
{
ALint idx = LookupPtrIntMapKey(&DeviceIfaceMap, device);
ALint idx = DeviceIfaceMap.lookupByKey(device);
if(idx < 0)
{
LastError.store(ALC_INVALID_DEVICE);
@ -748,7 +738,7 @@ ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsi
{
if(device)
{
ALint idx = LookupPtrIntMapKey(&DeviceIfaceMap, device);
ALint idx = DeviceIfaceMap.lookupByKey(device);
if(idx < 0)
{
LastError.store(ALC_INVALID_DEVICE);
@ -844,7 +834,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename,
if(device)
{
if(InsertPtrIntMapEntry(&DeviceIfaceMap, device, idx) != ALC_NO_ERROR)
if(DeviceIfaceMap.insert(device, idx) != ALC_NO_ERROR)
{
DriverList[idx].alcCaptureCloseDevice(device);
device = nullptr;
@ -858,14 +848,14 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
{
ALint idx;
if(!device || (idx=LookupPtrIntMapKey(&DeviceIfaceMap, device)) < 0)
if(!device || (idx=DeviceIfaceMap.lookupByKey(device)) < 0)
{
LastError.store(ALC_INVALID_DEVICE);
return ALC_FALSE;
}
if(!DriverList[idx].alcCaptureCloseDevice(device))
return ALC_FALSE;
RemovePtrIntMapKey(&DeviceIfaceMap, device);
DeviceIfaceMap.removeByKey(device);
return ALC_TRUE;
}
@ -873,7 +863,7 @@ ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
{
if(device)
{
ALint idx = LookupPtrIntMapKey(&DeviceIfaceMap, device);
ALint idx = DeviceIfaceMap.lookupByKey(device);
if(idx >= 0)
return DriverList[idx].alcCaptureStart(device);
}
@ -884,7 +874,7 @@ ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
{
if(device)
{
ALint idx = LookupPtrIntMapKey(&DeviceIfaceMap, device);
ALint idx = DeviceIfaceMap.lookupByKey(device);
if(idx >= 0)
return DriverList[idx].alcCaptureStop(device);
}
@ -895,7 +885,7 @@ ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer,
{
if(device)
{
ALint idx = LookupPtrIntMapKey(&DeviceIfaceMap, device);
ALint idx = DeviceIfaceMap.lookupByKey(device);
if(idx >= 0)
return DriverList[idx].alcCaptureSamples(device, buffer, samples);
}
@ -917,7 +907,7 @@ ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
return ALC_TRUE;
}
idx = LookupPtrIntMapKey(&ContextIfaceMap, context);
idx = ContextIfaceMap.lookupByKey(context);
if(idx >= 0)
{
if(DriverList[idx].alcSetThreadContext(context))

View File

@ -55,7 +55,6 @@ BOOL APIENTRY DllMain(HINSTANCE UNUSED(module), DWORD reason, void* UNUSED(reser
TRACE("Initializing router v0.1-%s %s\n", ALSOFT_GIT_COMMIT_HASH, ALSOFT_GIT_BRANCH);
LoadDriverList();
InitALC();
break;
case DLL_THREAD_ATTACH:
@ -64,8 +63,6 @@ BOOL APIENTRY DllMain(HINSTANCE UNUSED(module), DWORD reason, void* UNUSED(reser
break;
case DLL_PROCESS_DETACH:
ReleaseALC();
for(auto &drv : DriverList)
{
if(drv.Module)
@ -360,38 +357,28 @@ void LoadDriverList(void)
}
void InitPtrIntMap(PtrIntMap *map)
PtrIntMap::~PtrIntMap()
{
map->keys = nullptr;
map->values = nullptr;
map->size = 0;
map->capacity = 0;
RWLockInit(&map->lock);
std::lock_guard<std::mutex> maplock{mLock};
al_free(mKeys);
mKeys = nullptr;
mValues = nullptr;
mSize = 0;
mCapacity = 0;
}
void ResetPtrIntMap(PtrIntMap *map)
{
WriteLock(&map->lock);
al_free(map->keys);
map->keys = nullptr;
map->values = nullptr;
map->size = 0;
map->capacity = 0;
WriteUnlock(&map->lock);
}
ALenum InsertPtrIntMapEntry(PtrIntMap *map, ALvoid *key, ALint value)
ALenum PtrIntMap::insert(ALvoid *key, ALint value)
{
ALsizei pos = 0;
WriteLock(&map->lock);
if(map->size > 0)
std::lock_guard<std::mutex> maplock{mLock};
if(mSize > 0)
{
ALsizei count = map->size;
ALsizei count = mSize;
do {
ALsizei step = count>>1;
ALsizei i = pos+step;
if(map->keys[i] >= key)
if(mKeys[i] >= key)
count = step;
else
{
@ -401,65 +388,60 @@ ALenum InsertPtrIntMapEntry(PtrIntMap *map, ALvoid *key, ALint value)
} while(count > 0);
}
if(pos == map->size || map->keys[pos] != key)
if(pos == mSize || mKeys[pos] != key)
{
if(map->size == map->capacity)
if(mSize == mCapacity)
{
ALvoid **keys = nullptr;
ALint *values;
ALvoid **newkeys = nullptr;
ALint *newvalues;
ALsizei newcap;
newcap = (map->capacity ? (map->capacity<<1) : 4);
if(newcap > map->capacity)
keys = reinterpret_cast<ALvoid**>(
al_calloc(16, (sizeof(map->keys[0])+sizeof(map->values[0]))*newcap)
newcap = (mCapacity ? (mCapacity<<1) : 4);
if(newcap > mCapacity)
newkeys = reinterpret_cast<ALvoid**>(
al_calloc(16, (sizeof(mKeys[0])+sizeof(mValues[0]))*newcap)
);
if(!keys)
{
WriteUnlock(&map->lock);
if(!newkeys)
return AL_OUT_OF_MEMORY;
}
values = (ALint*)&keys[newcap];
newvalues = (ALint*)&newkeys[newcap];
if(map->keys)
if(mKeys)
{
memcpy(keys, map->keys, map->size*sizeof(map->keys[0]));
memcpy(values, map->values, map->size*sizeof(map->values[0]));
memcpy(newkeys, mKeys, mSize*sizeof(mKeys[0]));
memcpy(newvalues, mValues, mSize*sizeof(mValues[0]));
}
al_free(map->keys);
map->keys = keys;
map->values = values;
map->capacity = newcap;
al_free(mKeys);
mKeys = newkeys;
mValues = newvalues;
mCapacity = newcap;
}
if(pos < map->size)
if(pos < mSize)
{
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]));
memmove(&mKeys[pos+1], &mKeys[pos], (mSize-pos)*sizeof(mKeys[0]));
memmove(&mValues[pos+1], &mValues[pos], (mSize-pos)*sizeof(mValues[0]));
}
map->size++;
mSize++;
}
map->keys[pos] = key;
map->values[pos] = value;
WriteUnlock(&map->lock);
mKeys[pos] = key;
mValues[pos] = value;
return AL_NO_ERROR;
}
ALint RemovePtrIntMapKey(PtrIntMap *map, ALvoid *key)
ALint PtrIntMap::removeByKey(ALvoid *key)
{
ALint ret = -1;
WriteLock(&map->lock);
if(map->size > 0)
std::lock_guard<std::mutex> maplock{mLock};
if(mSize > 0)
{
ALsizei pos = 0;
ALsizei count = map->size;
ALsizei count = mSize;
do {
ALsizei step = count>>1;
ALsizei i = pos+step;
if(map->keys[i] >= key)
if(mKeys[i] >= key)
count = step;
else
{
@ -467,35 +449,33 @@ ALint RemovePtrIntMapKey(PtrIntMap *map, ALvoid *key)
count -= step+1;
}
} while(count > 0);
if(pos < map->size && map->keys[pos] == key)
if(pos < mSize && mKeys[pos] == key)
{
ret = map->values[pos];
if(pos < map->size-1)
ret = mValues[pos];
if(pos < mSize-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]));
memmove(&mKeys[pos], &mKeys[pos+1], (mSize-1-pos)*sizeof(mKeys[0]));
memmove(&mValues[pos], &mValues[pos+1], (mSize-1-pos)*sizeof(mValues[0]));
}
map->size--;
mSize--;
}
}
WriteUnlock(&map->lock);
return ret;
}
ALint LookupPtrIntMapKey(PtrIntMap *map, ALvoid *key)
ALint PtrIntMap::lookupByKey(ALvoid* key)
{
ALint ret = -1;
ReadLock(&map->lock);
if(map->size > 0)
std::lock_guard<std::mutex> maplock{mLock};
if(mSize > 0)
{
ALsizei pos = 0;
ALsizei count = map->size;
ALsizei count = mSize;
do {
ALsizei step = count>>1;
ALsizei i = pos+step;
if(map->keys[i] >= key)
if(mKeys[i] >= key)
count = step;
else
{
@ -503,9 +483,8 @@ ALint LookupPtrIntMapKey(PtrIntMap *map, ALvoid *key)
count -= step+1;
}
} while(count > 0);
if(pos < map->size && map->keys[pos] == key)
ret = map->values[pos];
if(pos < mSize && mKeys[pos] == key)
ret = mValues[pos];
}
ReadUnlock(&map->lock);
return ret;
}

View File

@ -8,8 +8,9 @@
#include <stdio.h>
#include <vector>
#include <atomic>
#include <string>
#include <atomic>
#include <mutex>
#include "AL/alc.h"
#include "AL/al.h"
@ -17,10 +18,6 @@
#include "rwlock.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef UNUSED
#if defined(__cplusplus)
#define UNUSED(x)
@ -145,26 +142,23 @@ extern thread_local DriverIface *ThreadCtxDriver;
extern std::atomic<DriverIface*> CurrentCtxDriver;
typedef struct PtrIntMap {
ALvoid **keys;
class PtrIntMap {
ALvoid **mKeys{nullptr};
/* Shares memory with keys. */
ALint *values;
ALint *mValues{nullptr};
ALsizei size;
ALsizei capacity;
RWLock lock;
} PtrIntMap;
#define PTRINTMAP_STATIC_INITIALIZE { nullptr, nullptr, 0, 0, RWLOCK_STATIC_INITIALIZE }
ALsizei mSize{0};
ALsizei mCapacity{0};
std::mutex mLock;
void InitPtrIntMap(PtrIntMap *map);
void ResetPtrIntMap(PtrIntMap *map);
ALenum InsertPtrIntMapEntry(PtrIntMap *map, ALvoid *key, ALint value);
ALint RemovePtrIntMapKey(PtrIntMap *map, ALvoid *key);
ALint LookupPtrIntMapKey(PtrIntMap *map, ALvoid *key);
public:
PtrIntMap() = default;
~PtrIntMap();
void InitALC(void);
void ReleaseALC(void);
ALenum insert(ALvoid *key, ALint value);
ALint removeByKey(ALvoid *key);
ALint lookupByKey(ALvoid *key);
};
enum LogLevel {
@ -198,8 +192,4 @@ extern FILE *LogFile;
} \
} while(0)
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* ROUTER_ROUTER_H */