aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/hrtf.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-04-06 13:00:29 -0700
committerChris Robinson <[email protected]>2017-04-06 13:00:29 -0700
commit338d61f9072bfb811266012c2a9c0a290cf353d1 (patch)
tree0ef0b218db261569105a782824c5bf50ea3a3067 /Alc/hrtf.c
parent94f514ae5a0392f5f01f2b479d1d858af688ae24 (diff)
Reference count HRTFs and unload them when unused
Diffstat (limited to 'Alc/hrtf.c')
-rw-r--r--Alc/hrtf.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/Alc/hrtf.c b/Alc/hrtf.c
index 35be4dc3..32a6357e 100644
--- a/Alc/hrtf.c
+++ b/Alc/hrtf.c
@@ -59,6 +59,7 @@ static const ALchar magicMarker01[8] = "MinPHR01";
* directional sounds. */
static const ALfloat PassthruCoeff = 0.707106781187f/*sqrt(0.5)*/;
+static ATOMIC_FLAG LoadedHrtfLock = ATOMIC_FLAG_INIT;
static struct HrtfEntry *LoadedHrtfs = NULL;
@@ -272,6 +273,7 @@ static struct Hrtf *CreateHrtfStore(ALuint rate, ALsizei irSize, ALsizei evCount
ALfloat *_coeffs;
ALsizei i;
+ InitRef(&Hrtf->ref, 0);
Hrtf->sampleRate = rate;
Hrtf->irSize = irSize;
Hrtf->evCount = evCount;
@@ -973,7 +975,6 @@ void FreeHrtfList(vector_EnumeratedHrtf *list)
struct Hrtf *GetLoadedHrtf(struct HrtfEntry *entry)
{
- static ATOMIC_FLAG LoadLock = ATOMIC_FLAG_INIT;
struct Hrtf *hrtf = NULL;
struct FileMapping fmap;
const ALubyte *rdata;
@@ -982,12 +983,13 @@ struct Hrtf *GetLoadedHrtf(struct HrtfEntry *entry)
size_t rsize;
char ch;
- while(ATOMIC_FLAG_TEST_AND_SET(&LoadLock, almemory_order_seq_cst))
+ while(ATOMIC_FLAG_TEST_AND_SET(&LoadedHrtfLock, almemory_order_seq_cst))
althrd_yield();
if(entry->handle)
{
hrtf = entry->handle;
+ Hrtf_IncRef(hrtf);
goto done;
}
@@ -1047,18 +1049,55 @@ struct Hrtf *GetLoadedHrtf(struct HrtfEntry *entry)
ERR("Failed to load %s\n", name);
goto done;
}
+ entry->handle = hrtf;
+ Hrtf_IncRef(hrtf);
TRACE("Loaded HRTF support for format: %s %uhz\n",
DevFmtChannelsString(DevFmtStereo), hrtf->sampleRate);
- entry->handle = hrtf;
-
done:
- ATOMIC_FLAG_CLEAR(&LoadLock, almemory_order_seq_cst);
+ ATOMIC_FLAG_CLEAR(&LoadedHrtfLock, almemory_order_seq_cst);
return hrtf;
}
+void Hrtf_IncRef(struct Hrtf *hrtf)
+{
+ uint ref = IncrementRef(&hrtf->ref);
+ TRACEREF("%p increasing refcount to %u\n", hrtf, ref);
+}
+
+void Hrtf_DecRef(struct Hrtf *hrtf)
+{
+ struct HrtfEntry *Hrtf;
+ uint ref = DecrementRef(&hrtf->ref);
+ TRACEREF("%p decreasing refcount to %u\n", hrtf, ref);
+ if(ref == 0)
+ {
+ while(ATOMIC_FLAG_TEST_AND_SET(&LoadedHrtfLock, almemory_order_seq_cst))
+ althrd_yield();
+
+ Hrtf = LoadedHrtfs;
+ while(Hrtf != NULL)
+ {
+ /* Need to double-check that it's still unused, as another device
+ * could've reacquired this HRTF after its reference went to 0 and
+ * before the lock was taken.
+ */
+ if(hrtf == Hrtf->handle && ReadRef(&hrtf->ref) == 0)
+ {
+ al_free(Hrtf->handle);
+ Hrtf->handle = NULL;
+ TRACE("Unloaded unused HRTF %s\n", Hrtf->filename);
+ }
+ Hrtf = Hrtf->next;
+ }
+
+ ATOMIC_FLAG_CLEAR(&LoadedHrtfLock, almemory_order_seq_cst);
+ }
+}
+
+
void FreeHrtfs(void)
{
struct HrtfEntry *Hrtf = LoadedHrtfs;