# HG changeset patch # User Merten Sach # Date 1308761357 -7200 # Node ID 7c9e00ff1bf452be98dce61cfa42c01939964d7d # Parent 1e93e5dbeda18b25c8fca88e97fdf5e70b782513 fixed queue enlarging function diff -r 1e93e5dbeda1 -r 7c9e00ff1bf4 PrivateQueue.c --- a/PrivateQueue.c Wed Jun 22 16:55:10 2011 +0200 +++ b/PrivateQueue.c Wed Jun 22 18:49:17 2011 +0200 @@ -39,18 +39,23 @@ void enlargePrivQ( PrivQueueStruc *Q ) - { int oldSize, newSize; + { size_t oldSize, newSize; void **oldStartOfData; - oldSize = Q->endOfData - Q->startOfData; + oldSize = Q->endOfData - Q->startOfData + 1; newSize = 2 * oldSize; oldStartOfData = Q->startOfData; - Q->startOfData = VMS__malloc( newSize * sizeof(void *) ); - memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *)); + Q->startOfData = VMS__malloc( newSize * sizeof(void*)); + //copy second half + size_t secondHalfSize = Q->endOfData - Q->extractPos + 1; + memcpy(Q->startOfData,Q->extractPos, secondHalfSize * sizeof(void*)); + //copy first half + memcpy(Q->startOfData + secondHalfSize, oldStartOfData, + (oldSize-secondHalfSize) * sizeof(void*)); VMS__free(oldStartOfData); - Q->extractPos = &(Q->startOfData[0]); //side by side == empty - Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be + Q->extractPos = Q->startOfData; + Q->insertPos = Q->startOfData + oldSize - 1; Q->endOfData = &(Q->startOfData[newSize - 1]); } @@ -106,28 +111,28 @@ void writePrivQ( void * in, PrivQueueStruc* Q ) { - void **startOfData = Q->startOfData; - void **endOfData = Q->endOfData; - - void **insertPos = Q->insertPos; - void **extractPos = Q->extractPos; + while(1){ + void **startOfData = Q->startOfData; + void **endOfData = Q->endOfData; -tryAgain: - //Full? (insert is just below extract when full) - if( extractPos - insertPos != 1 && - !(insertPos == endOfData && extractPos == startOfData)) - { *(Q->insertPos) = in; //insert before move - if( insertPos == endOfData ) //write new pos exactly once, correctly - { Q->insertPos = startOfData; - } - else - { Q->insertPos++; - } - return; - } - //Q is full - enlargePrivQ( Q ); - goto tryAgain; + void **insertPos = Q->insertPos; + void **extractPos = Q->extractPos; + + //Full? (insert is just below extract when full) + if( extractPos - insertPos != 1 && + !(insertPos == endOfData && extractPos == startOfData)) + { *(Q->insertPos) = in; //insert before move + if( insertPos == endOfData ) //write new pos exactly once, correctly + { Q->insertPos = startOfData; + } + else + { Q->insertPos++; + } + return; + } + //Q is full + enlargePrivQ( Q ); + } } @@ -164,30 +169,30 @@ void pushPrivQ( void * in, PrivQueueStruc* Q ) { - void **startOfData = Q->startOfData; - void **endOfData = Q->endOfData; + while(1){ + void **startOfData = Q->startOfData; + void **endOfData = Q->endOfData; - void **insertPos = Q->insertPos; - void **extractPos = Q->extractPos; + void **insertPos = Q->insertPos; + void **extractPos = Q->extractPos; -tryAgain: - //Full? (insert is just below extract when full) - if( extractPos - insertPos != 1 && - !(insertPos == endOfData && extractPos == startOfData)) - { //insert -- but go backwards, inserting at read position then - // move read pos backwards - *(Q->extractPos) = in; - if( extractPos == startOfData ) //write new pos exactly once, correctly - { Q->extractPos = endOfData; //can't overrun then fix it 'cause - } // other thread might read bad pos - else - { Q->extractPos--; - } - return; - } - //Q is full - enlargePrivQ( Q ); - goto tryAgain; + //Full? (insert is just below extract when full) + if( extractPos - insertPos != 1 && + !(insertPos == endOfData && extractPos == startOfData)) + { //insert -- but go backwards, inserting at read position then + // move read pos backwards + *(Q->extractPos) = in; + if( extractPos == startOfData ) //write new pos exactly once, correctly + { Q->extractPos = endOfData; //can't overrun then fix it 'cause + } // other thread might read bad pos + else + { Q->extractPos--; + } + return; + } + //Q is full + enlargePrivQ( Q ); + } } void