From 8dcf4372f4a63322c50e88f5795cf65e863b0f76 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 2 Apr 2014 22:47:49 -0400 Subject: [PATCH] Use a double-linked list for the linked blocking queue so insertions are done in O(1) time --- limelight-common/AudioStream.c | 2 +- limelight-common/InputStream.c | 2 +- limelight-common/LinkedBlockingQueue.c | 33 ++++++++++++++++---------- limelight-common/LinkedBlockingQueue.h | 4 +++- limelight-common/VideoDepacketizer.c | 2 +- limelight-common/VideoStream.c | 2 +- 6 files changed, 27 insertions(+), 18 deletions(-) diff --git a/limelight-common/AudioStream.c b/limelight-common/AudioStream.c index b1d9ed3..2968644 100644 --- a/limelight-common/AudioStream.c +++ b/limelight-common/AudioStream.c @@ -33,7 +33,7 @@ void destroyAudioStream(void) { entry = LbqDestroyLinkedBlockingQueue(&packetQueue); while (entry != NULL) { - nextEntry = entry->next; + nextEntry = entry->flink; free(entry->data); free(entry); entry = nextEntry; diff --git a/limelight-common/InputStream.c b/limelight-common/InputStream.c index 2ae7d6f..58580f7 100644 --- a/limelight-common/InputStream.c +++ b/limelight-common/InputStream.c @@ -35,7 +35,7 @@ void destroyInputStream(void) { entry = LbqDestroyLinkedBlockingQueue(&packetQueue); while (entry != NULL) { - nextEntry = entry->next; + nextEntry = entry->flink; free(entry->data); free(entry); entry = nextEntry; diff --git a/limelight-common/LinkedBlockingQueue.c b/limelight-common/LinkedBlockingQueue.c index 26c9f79..8804665 100644 --- a/limelight-common/LinkedBlockingQueue.c +++ b/limelight-common/LinkedBlockingQueue.c @@ -21,6 +21,7 @@ int LbqInitializeLinkedBlockingQueue(PLINKED_BLOCKING_QUEUE queueHead, int sizeB } queueHead->head = NULL; + queueHead->tail = NULL; queueHead->sizeBound = sizeBound; queueHead->currentSize = 0; @@ -28,14 +29,14 @@ int LbqInitializeLinkedBlockingQueue(PLINKED_BLOCKING_QUEUE queueHead, int sizeB } int LbqOfferQueueItem(PLINKED_BLOCKING_QUEUE queueHead, void* data) { - PLINKED_BLOCKING_QUEUE_ENTRY entry, lastEntry; + PLINKED_BLOCKING_QUEUE_ENTRY entry; entry = (PLINKED_BLOCKING_QUEUE_ENTRY) malloc(sizeof(*entry)); if (entry == NULL) { return LBQ_NO_MEMORY; } - entry->next = NULL; + entry->flink = NULL; entry->data = data; PltLockMutex(&queueHead->mutex); @@ -48,15 +49,17 @@ int LbqOfferQueueItem(PLINKED_BLOCKING_QUEUE queueHead, void* data) { if (queueHead->head == NULL) { LC_ASSERT(queueHead->currentSize == 0); + LC_ASSERT(queueHead->tail == NULL); queueHead->head = entry; + queueHead->tail = entry; + entry->blink = NULL; } else { LC_ASSERT(queueHead->currentSize >= 1); - lastEntry = queueHead->head; - while (lastEntry->next != NULL) { - lastEntry = lastEntry->next; - } - lastEntry->next = entry; + LC_ASSERT(queueHead->head != NULL); + queueHead->tail->flink = entry; + entry->blink = queueHead->tail; + queueHead->tail = entry; } queueHead->currentSize++; @@ -86,18 +89,22 @@ int LbqWaitForQueueElement(PLINKED_BLOCKING_QUEUE queueHead, void** data) { } entry = queueHead->head; - queueHead->head = entry->next; + queueHead->head = entry->flink; queueHead->currentSize--; + if (queueHead->head == NULL) { + LC_ASSERT(queueHead->currentSize == 0); + queueHead->tail = NULL; + PltClearEvent(&queueHead->containsDataEvent); + } + else { + LC_ASSERT(queueHead->currentSize != 0); + queueHead->head->blink = NULL; + } *data = entry->data; free(entry); - if (queueHead->head == NULL) { - LC_ASSERT(queueHead->currentSize == 0); - PltClearEvent(&queueHead->containsDataEvent); - } - PltUnlockMutex(&queueHead->mutex); break; diff --git a/limelight-common/LinkedBlockingQueue.h b/limelight-common/LinkedBlockingQueue.h index 142addb..1f03efe 100644 --- a/limelight-common/LinkedBlockingQueue.h +++ b/limelight-common/LinkedBlockingQueue.h @@ -9,7 +9,8 @@ #define LBQ_NO_MEMORY 3 typedef struct _LINKED_BLOCKING_QUEUE_ENTRY { - struct _LINKED_BLOCKING_QUEUE_ENTRY *next; + struct _LINKED_BLOCKING_QUEUE_ENTRY *flink; + struct _LINKED_BLOCKING_QUEUE_ENTRY *blink; void* data; } LINKED_BLOCKING_QUEUE_ENTRY, *PLINKED_BLOCKING_QUEUE_ENTRY; @@ -19,6 +20,7 @@ typedef struct _LINKED_BLOCKING_QUEUE { int sizeBound; int currentSize; PLINKED_BLOCKING_QUEUE_ENTRY head; + PLINKED_BLOCKING_QUEUE_ENTRY tail; } LINKED_BLOCKING_QUEUE, *PLINKED_BLOCKING_QUEUE; int LbqInitializeLinkedBlockingQueue(PLINKED_BLOCKING_QUEUE queueHead, int sizeBound); diff --git a/limelight-common/VideoDepacketizer.c b/limelight-common/VideoDepacketizer.c index a218e94..9d74a06 100644 --- a/limelight-common/VideoDepacketizer.c +++ b/limelight-common/VideoDepacketizer.c @@ -45,7 +45,7 @@ void destroyVideoDepacketizer(void) { entry = LbqDestroyLinkedBlockingQueue(&decodeUnitQueue); while (entry != NULL) { - nextEntry = entry->next; + nextEntry = entry->flink; free(entry->data); free(entry); entry = nextEntry; diff --git a/limelight-common/VideoStream.c b/limelight-common/VideoStream.c index e181560..eb6c53b 100644 --- a/limelight-common/VideoStream.c +++ b/limelight-common/VideoStream.c @@ -45,7 +45,7 @@ void destroyVideoStream(void) { entry = LbqDestroyLinkedBlockingQueue(&packetQueue); while (entry != NULL) { - nextEntry = entry->next; + nextEntry = entry->flink; free(entry->data); free(entry); entry = nextEntry;