# HG changeset patch # User Nina Engelhardt # Date 1355927888 -3600 # Node ID 8fcbe46de60a68d2c0a8bef5e7f8ef20a584d246 # Parent cb29e773f76f110e2e9293edda438106d469b165 bugfixes - peek and enlarge now working properly diff -r cb29e773f76f -r 8fcbe46de60a PrivateQueue.c --- a/PrivateQueue.c Tue Sep 11 04:19:51 2012 -0700 +++ b/PrivateQueue.c Wed Dec 19 15:38:08 2012 +0100 @@ -8,10 +8,9 @@ */ +#include +#include #include -#include -#include -#include #include "PrivateQueue.h" @@ -36,38 +35,54 @@ retQ->insertPos = &(retQ->startOfData[1]); // so start pos's have to be retQ->endOfData = &(retQ->startOfData[1023]); + #ifdef DEBUG_PRIVATE_Q + retQ->numReads = 0; + retQ->numWrites =0; + #endif + return retQ; } void enlargePrivQ( PrivQueueStruc *Q ) - { int32 oldSize, newSize, topPartSize, bottPartSize; - int8 *insertPos, *extractPos; - int8 *oldStartOfData, *oldEndOfData, *newStartOfData, *newEndOfData; - int32 insertOffsetBytes, extractOffsetBytes; - int8 *copyStartAddr; + { size_t oldSize, newSize, topPartSize, bottPartSize; + char *insertPos, *extractPos; + char *oldStartOfData, *oldEndOfData, *newStartOfData, *newEndOfData; + size_t insertOffsetBytes, extractOffsetBytes; + char* copyStartAddr; - oldStartOfData = (int8 *)Q->startOfData; - oldEndOfData = (int8 *)Q->endOfData; - insertPos = (int8 *)Q->insertPos; - extractPos = (int8 *)Q->extractPos; + #ifdef DEBUG_PRIVATE_Q + printf("Enlarging queue Q = %p\nnumReads = %d; numWrites = %d\n",Q,Q->numReads,Q->numWrites); + #endif + + oldStartOfData = (char*)Q->startOfData; + oldEndOfData = (char*)(Q->endOfData + 1); + insertPos = (char*)Q->insertPos; + extractPos = (char*)Q->extractPos; //TODO: verify these get number of bytes correct - insertOffsetBytes = (int32)(insertPos - oldStartOfData); - extractOffsetBytes = (int32)(extractPos - oldStartOfData); + insertOffsetBytes = (insertPos - oldStartOfData); + extractOffsetBytes = (extractPos - oldStartOfData); - oldSize = oldEndOfData - oldStartOfData + 1; //in bytes + oldSize = oldEndOfData - oldStartOfData; //in bytes newSize = 2 * oldSize; + #ifdef DEBUG_PRIVATE_Q + printf("Old size = %d, new size = %d\n",(int)oldSize,(int)newSize); + #endif + //This malloc is not safe to use in wrapper lib nor app code! - Q->startOfData = (void **)VMS_int__malloc( newSize ); - newStartOfData = (int8 *)Q->startOfData; + newStartOfData = (char *) VMS_int__malloc( newSize ); + if(newStartOfData == NULL){ + perror("malloc"); exit(1); + } newEndOfData = newStartOfData + newSize; //all calcs in Bytes - Q->endOfData = (void **)newEndOfData; + + //TODO: test all of this, for both cases + Q->startOfData = newStartOfData; + Q->endOfData = ((void **)newEndOfData) - 1; - //TODO: test all of this, for both cases - //Moving the data and pointers to the new array is //a little trickier than at first it seems.. the top part // of old queue must be moved to the top part of new queue, while @@ -76,25 +91,25 @@ //UNLESS the one case where old extract was at bottom and insert // was at top. //TODO: check that this is correct! - if( extractPos == oldStartOfData && insertPos == oldEndOfData ) + if( extractPos == oldStartOfData ) { memcpy( newStartOfData, oldStartOfData, oldSize ); //oldSize is bytes Q->extractPos = Q->startOfData; //start of valid data - Q->insertPos = Q->startOfData + oldSize - 1; //end of valid data + Q->insertPos = (void**)(newStartOfData + insertOffsetBytes); //end of valid data } else //have to copy two parts separately, then calc positions { //TODO: check end-addr, sizes, and new positions carefully - + //copy top part, starting at extract up until end of data, // into top of new array - topPartSize = oldEndOfData - extractPos + 1; //+1 includes extractPos - copyStartAddr = newEndOfData - topPartSize + 1;//+1 cancels other - memcpy( copyStartAddr, Q->extractPos, topPartSize ); + topPartSize = oldEndOfData - extractPos; + copyStartAddr = newEndOfData - topPartSize; + memcpy( copyStartAddr, extractPos, topPartSize ); Q->extractPos = (void **)copyStartAddr; //extract just-copied data //copy bottom part, from old start up to old insert, // into bottom of new array - bottPartSize = oldSize - topPartSize - 1; //-1 for empty insertPos + bottPartSize = insertPos - oldStartOfData; //-1 for empty insertPos memcpy( newStartOfData, oldStartOfData, bottPartSize ); Q->insertPos = (void **)(newStartOfData + bottPartSize); } @@ -137,70 +152,72 @@ if( insertPos - extractPos != 1 && !(extractPos == endOfData && insertPos == startOfData)) { - out = *(Q->extractPos); + out = *(Q->extractPos + 1); return out; } //Q is empty return NULL; } - /*Returns NULL when queue is empty */ -void* readPrivQ( PrivQueueStruc* Q ) - { void *out = 0; - void **startOfData = Q->startOfData; - void **endOfData = Q->endOfData; +void* readPrivQ(PrivQueueStruc* Q) { +#ifdef DEBUG_PRIVATE_Q + Q->numReads++; +#endif + + void *out = 0; + void **startOfData = Q->startOfData; + void **endOfData = Q->endOfData; - void **insertPos = Q->insertPos; - void **extractPos = Q->extractPos; + void **insertPos = Q->insertPos; + void **extractPos = Q->extractPos; - //if not empty -- (extract is just below insert when empty) - if( insertPos - extractPos != 1 && - !(extractPos == endOfData && insertPos == startOfData)) - { //move before read - if( extractPos == endOfData ) //write new pos exactly once, correctly - { Q->extractPos = startOfData; //can't overrun then fix it 'cause - } // other thread might read bad pos - else - { Q->extractPos++; - } - out = *(Q->extractPos); - return out; + //if not empty -- (extract is just below insert when empty) + if (insertPos - extractPos != 1 && + !(extractPos == endOfData && insertPos == startOfData)) { //move before read + if (extractPos == endOfData) //write new pos exactly once, correctly + { + Q->extractPos = startOfData; //can't overrun then fix it 'cause + }// other thread might read bad pos + else { + Q->extractPos++; + } + out = *(Q->extractPos); + return out; } - //Q is empty - return NULL; - } - - + //Q is empty + return NULL; +} /*Expands the queue size automatically when it's full */ void -writePrivQ( void * in, PrivQueueStruc* Q ) - { - void **startOfData = Q->startOfData; - void **endOfData = Q->endOfData; - - void **insertPos = Q->insertPos; - void **extractPos = Q->extractPos; +writePrivQ(void * in, PrivQueueStruc* Q) { -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; + #ifdef DEBUG_PRIVATE_Q + Q->numWrites++; + #endif + + //tryAgain: + //Full? (insert is just below extract when full) + if ((Q->extractPos - Q->insertPos) == 1 || + (Q->insertPos == Q->endOfData && Q->extractPos == Q->startOfData)) { + enlargePrivQ(Q); } - //Q is full - enlargePrivQ( Q ); - goto tryAgain; - } + + *(Q->insertPos) = in; //insert before move + if (Q->insertPos == Q->endOfData) //write new pos exactly once, correctly + { + Q->insertPos = Q->startOfData; + } else { + Q->insertPos++; + } + return; + + //Q is full + + //goto tryAgain; +} /*Returns false when the queue was full. @@ -224,6 +241,9 @@ else { Q->insertPos++; } + #ifdef DEBUG_PRIVATE_Q + Q->numWrites++; + #endif return TRUE; } //Q is full @@ -256,6 +276,9 @@ void pushPrivQ( void * in, PrivQueueStruc* Q ) { + #ifdef DEBUG_PRIVATE_Q + Q->numWrites++; + #endif while(1){ void **startOfData = Q->startOfData; void **endOfData = Q->endOfData; diff -r cb29e773f76f -r 8fcbe46de60a PrivateQueue.h --- a/PrivateQueue.h Tue Sep 11 04:19:51 2012 -0700 +++ b/PrivateQueue.h Wed Dec 19 15:38:08 2012 +0100 @@ -19,6 +19,7 @@ #define LOCKED 1 #define UNLOCKED 0 +#define DEBUG_PRIVATE_Q /* It is the data that is shared so only need one mutex. */ typedef struct @@ -26,6 +27,10 @@ void **extractPos; void **startOfData; //data is pointers void **endOfData; //set when alloc data +#ifdef DEBUG_PRIVATE_Q + int numWrites; + int numReads; +#endif } PrivQueueStruc;