From a09487cb98273aee3ee950965b49f59d3fc3554f Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 31 May 2009 23:20:17 +0000 Subject: Fix OPL callback queue. Subversion-branch: /branches/opl-branch Subversion-revision: 1539 --- opl/opl_queue.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 3 deletions(-) (limited to 'opl') diff --git a/opl/opl_queue.c b/opl/opl_queue.c index 6639eee5..fe5f1ef8 100644 --- a/opl/opl_queue.c +++ b/opl/opl_queue.c @@ -70,6 +70,7 @@ void OPL_Queue_Push(opl_callback_queue_t *queue, unsigned int time) { int entry_id; + int parent_id; if (queue->num_entries >= MAX_OPL_QUEUE) { @@ -84,13 +85,26 @@ void OPL_Queue_Push(opl_callback_queue_t *queue, // Shift existing entries down in the heap. - while (entry_id > 0 && time < queue->entries[entry_id / 2].time) + while (entry_id > 0) { + parent_id = (entry_id - 1) / 2; + + // Is the heap condition satisfied? + + if (time >= queue->entries[parent_id].time) + { + break; + } + + // Move the existing entry down in the heap. + memcpy(&queue->entries[entry_id], - &queue->entries[entry_id / 2], + &queue->entries[parent_id], sizeof(opl_queue_entry_t)); - entry_id /= 2; + // Advance to the parent. + + entry_id = parent_id; } // Insert new callback data. @@ -190,3 +204,72 @@ unsigned int OPL_Queue_Peek(opl_callback_queue_t *queue) } } +#ifdef TEST + +#include + +static void PrintQueueNode(opl_callback_queue_t *queue, int node, int depth) +{ + int i; + + if (node >= queue->num_entries) + { + return; + } + + for (i=0; ientries[node].time); + + PrintQueueNode(queue, node * 2 + 1, depth + 1); + PrintQueueNode(queue, node * 2 + 2, depth + 1); +} + +static void PrintQueue(opl_callback_queue_t *queue) +{ + PrintQueueNode(queue, 0, 0); +} + +int main() +{ + opl_callback_queue_t *queue; + int iteration; + + queue = OPL_Queue_Create(); + + for (iteration=0; iteration<5000; ++iteration) + { + opl_callback_t callback; + void *data; + unsigned int time; + unsigned int newtime; + int i; + + for (i=0; i= time); + time = newtime; + } + + assert(OPL_Queue_IsEmpty(queue)); + assert(!OPL_Queue_Pop(queue, &callback, &data)); + } +} + +#endif + -- cgit v1.2.3