aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-01-31 00:42:58 -0800
committerChris Robinson <[email protected]>2016-01-31 00:42:58 -0800
commitd69dd6dc7aa50fa3bd77338065b381b57be05acd (patch)
tree18b83f8fa64cd41f3f5cdabc060ea74ede726ec6
parent063ef9c2fccdf8ce4b0148a1a06de4b9234d86b8 (diff)
Make the source's buffer queue a singly-linked list
-rw-r--r--OpenAL32/Include/alSource.h1
-rw-r--r--OpenAL32/alSource.c57
2 files changed, 27 insertions, 31 deletions
diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h
index 13596161..253cd05f 100644
--- a/OpenAL32/Include/alSource.h
+++ b/OpenAL32/Include/alSource.h
@@ -18,7 +18,6 @@ struct ALsource;
typedef struct ALbufferlistitem {
struct ALbuffer *buffer;
struct ALbufferlistitem *volatile next;
- struct ALbufferlistitem *volatile prev;
} ALbufferlistitem;
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index 0d454882..d31a0377 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -631,7 +631,6 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
newlist = malloc(sizeof(ALbufferlistitem));
newlist->buffer = buffer;
newlist->next = NULL;
- newlist->prev = NULL;
IncrementRef(&buffer->ref);
/* Source is now Static */
@@ -2334,19 +2333,15 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu
if(!BufferListStart)
{
BufferListStart = malloc(sizeof(ALbufferlistitem));
- BufferListStart->buffer = buffer;
- BufferListStart->next = NULL;
- BufferListStart->prev = NULL;
BufferList = BufferListStart;
}
else
{
BufferList->next = malloc(sizeof(ALbufferlistitem));
- BufferList->next->buffer = buffer;
- BufferList->next->next = NULL;
- BufferList->next->prev = BufferList;
BufferList = BufferList->next;
}
+ BufferList->buffer = buffer;
+ BufferList->next = NULL;
if(!buffer) continue;
/* Hold a read lock on each buffer being queued while checking all
@@ -2372,26 +2367,27 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu
buffer_error:
/* A buffer failed (invalid ID or format), so unlock and release
* each buffer we had. */
- while(BufferList != NULL)
+ while(BufferListStart)
{
- ALbufferlistitem *prev = BufferList->prev;
- if((buffer=BufferList->buffer) != NULL)
+ ALbufferlistitem *next = BufferListStart->next;
+ if((buffer=BufferListStart->buffer) != NULL)
{
DecrementRef(&buffer->ref);
ReadUnlock(&buffer->lock);
}
- free(BufferList);
- BufferList = prev;
+ free(BufferListStart);
+ BufferListStart = next;
}
goto done;
}
}
/* All buffers good, unlock them now. */
+ BufferList = BufferListStart;
while(BufferList != NULL)
{
ALbuffer *buffer = BufferList->buffer;
if(buffer) ReadUnlock(&buffer->lock);
- BufferList = BufferList->prev;
+ BufferList = BufferList->next;
}
/* Source is now streaming */
@@ -2403,10 +2399,11 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu
/* Queue head is not NULL, append to the end of the queue */
while(BufferList->next != NULL)
BufferList = BufferList->next;
-
- BufferListStart->prev = BufferList;
BufferList->next = BufferListStart;
}
+ /* If the current buffer was at the end (NULL), put it at the start of the newly queued
+ * buffers.
+ */
BufferList = NULL;
ATOMIC_COMPARE_EXCHANGE_STRONG(ALbufferlistitem*, &source->current_buffer, &BufferList, BufferListStart);
WriteUnlock(&source->queue_lock);
@@ -2419,10 +2416,10 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint
{
ALCcontext *context;
ALsource *source;
- ALbufferlistitem *NewHead;
ALbufferlistitem *OldHead;
+ ALbufferlistitem *OldTail;
ALbufferlistitem *Current;
- ALsizei i;
+ ALsizei i = 0;
if(nb == 0)
return;
@@ -2438,13 +2435,16 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint
WriteLock(&source->queue_lock);
/* Find the new buffer queue head */
- NewHead = ATOMIC_LOAD(&source->queue);
+ OldTail = ATOMIC_LOAD(&source->queue);
Current = ATOMIC_LOAD(&source->current_buffer);
- for(i = 0;i < nb && NewHead;i++)
+ if(OldTail != Current)
{
- if(NewHead == Current)
- break;
- NewHead = NewHead->next;
+ for(i = 1;i < nb;i++)
+ {
+ ALbufferlistitem *next = OldTail->next;
+ if(!next || next == Current) break;
+ OldTail = next;
+ }
}
if(source->Looping || source->SourceType != AL_STREAMING || i != nb)
{
@@ -2454,18 +2454,15 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint
}
/* Swap it, and cut the new head from the old. */
- OldHead = ATOMIC_EXCHANGE(ALbufferlistitem*, &source->queue, NewHead);
- if(NewHead)
+ OldHead = ATOMIC_EXCHANGE(ALbufferlistitem*, &source->queue, OldTail->next);
+ if(OldTail->next)
{
ALCdevice *device = context->Device;
- ALbufferlistitem *OldTail = NewHead->prev;
uint count;
- /* Cut the new head's link back to the old body. The mixer is robust
- * enough to handle the link back going away. Once the active mix (if
- * any) is complete, it's safe to finish cutting the old tail from the
- * new head. */
- NewHead->prev = NULL;
+ /* Once the active mix (if any) is done, it's safe to cut the old tail
+ * from the new head.
+ */
if(((count=ReadRef(&device->MixCount))&1) != 0)
{
while(count == ReadRef(&device->MixCount))