# HG changeset patch # User Some Random Person # Date 1331791348 25200 # Node ID c5d2f2a941333d81ff8b2d91b282ba61e8a75f96 # Parent 7742a5e0d92e45e56702743ce017b70b16507f4f updated to fixed versions from MC_shared brch, then removed VMS_ from malloc diff -r 7742a5e0d92e -r c5d2f2a94133 PrivateQueue.c --- a/PrivateQueue.c Mon Feb 13 13:29:51 2012 -0800 +++ b/PrivateQueue.c Wed Mar 14 23:02:28 2012 -0700 @@ -26,8 +26,10 @@ PrivQueueStruc* makePrivQ() { PrivQueueStruc* retQ; + //This malloc is not safe to use inside VMS-language! retQ = (PrivQueueStruc *) malloc( sizeof( PrivQueueStruc ) ); + //This malloc is not safe to use inside VMS-language! retQ->startOfData = malloc( 1024 * sizeof(void *) ); memset( retQ->startOfData, 0, 1024 * sizeof(void *) ); retQ->extractPos = &(retQ->startOfData[0]); //side by side == empty @@ -40,19 +42,63 @@ void enlargePrivQ( PrivQueueStruc *Q ) - { int oldSize, newSize; - void **oldStartOfData; + { int32 oldSize, newSize; + int8 *insertPos, *extractPos; + int8 *oldStartOfData, *oldEndOfData, *newStartOfData, *newEndOfData; + int8 *insertOffsetBytes, *extractOffsetBytes; - oldSize = Q->endOfData - Q->startOfData; - newSize = 2 * oldSize; - oldStartOfData = Q->startOfData; - Q->startOfData = malloc( newSize * sizeof(void *) ); - memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *)); - free(oldStartOfData); + oldStartOfData = (int8 *)Q->startOfData; + oldEndOfData = (int8 *)Q->endOfData; + insertPos = (int8 *)Q->insertPos; + extractPos = (int8 *)Q->extractPos; - Q->extractPos = &(Q->startOfData[0]); //side by side == empty - Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be - Q->endOfData = &(Q->startOfData[newSize - 1]); + //TODO: verify these get number of bytes correct + insertOffsetBytes = insertPos - oldStartOfData; + extractOffsetBytes = extractPos - oldStartOfData); + + oldSize = endOfData - startOfData + 1; //in bytes + newSize = 2 * oldSize; + + //This malloc is not safe to use inside VMS-language! + Q->startOfData = (void **)malloc( newSize ); + newStartOfData = (int8 *)Q->startOfData; + newEndOfData = newStartOfData + newSize; //all calcs in Bytes + Q->endOfData = (void **)newEndOfData; + + //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 + // bottom part of old to bottom part of new, then the new insert + // and extract positions calculated by offset from top and bottom + //UNLESS the one case where old extract was at bottom and insert + // was at top. + //TODO: check that this is correct! + if( extractPos == startOfData && insertPos == endOfData ) + { + 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 + } + 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 ); + 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 + memcpy( newStartOfData, oldStartOfData, bottPartSize ); + Q->insertPos = (void **)(newStartOfData + bottPartSize); + } + //This free is not safe to use inside VMS-language! + free(oldStartOfData); } @@ -139,3 +185,64 @@ //Q is full return FALSE; } + +int32 +numInPrivQ( PrivQueueStruc *Q ) + { int32 size, numIn; + + if( Q->insertPos < Q->extractPos ) + { //insert has wrapped around so numIn is: + // insertPos + size - extractPos -- Consider, is empty when + // extractPos = endOfData and insert = start -- correctly get zero + size = Q->endOfData - Q->startOfData + 1; //sz of 10 is 0..9 + numIn = Q->insertPos - Q->extractPos + size - 1; //-1 bec insrt empty + } + else + { + numIn = Q->insertPos - Q->extractPos -1;//-1 bec insertPos empty + } + return numIn; + } + + +/*Treats queue as a stack -- no matter contents, if read done right after + * a push, then the pushed item is what comes out. + * Expands the queue size automatically when it's full. + */ +void +pushPrivQ( void * in, PrivQueueStruc* Q ) + { + while(1){ + void **startOfData = Q->startOfData; + void **endOfData = Q->endOfData; + + void **insertPos = Q->insertPos; + void **extractPos = Q->extractPos; + + //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 + freePrivQ( PrivQueueStruc *Q ) + { + //This free is not safe to use inside VMS-language! + free( Q->startOfData ); + free( Q ); + } \ No newline at end of file diff -r 7742a5e0d92e -r c5d2f2a94133 PrivateQueue.h --- a/PrivateQueue.h Mon Feb 13 13:29:51 2012 -0800 +++ b/PrivateQueue.h Wed Mar 14 23:02:28 2012 -0700 @@ -8,7 +8,9 @@ #ifndef _PRIVATE_QUEUE_H #define _PRIVATE_QUEUE_H -#include + +#include "VMS_impl/VMS_primitive_data_types.h" + #define TRUE 1 #define FALSE 0 @@ -26,12 +28,16 @@ } PrivQueueStruc; +typedef void (*DynArrayFnPtr) ( void * ); //fn has to cast void * PrivQueueStruc* makePrivQ ( ); -void* readPrivQ ( PrivQueueStruc *Q ); +void* readPrivQ ( PrivQueueStruc *Q ); //ret NULL if empty void writePrivQ( void *in, PrivQueueStruc *Q ); -int writeIfSpacePrivQ( void * in, PrivQueueStruc* Q ); //return - // false when full + //return false when full +bool32 writeIfSpacePrivQ( void * in, PrivQueueStruc* Q ); +int32 numInPrivQ( PrivQueueStruc *Q ); +void pushPrivQ( void * in, PrivQueueStruc* Q ); +void freePrivQ( PrivQueueStruc *Q ); #endif /* _PRIVATE_QUEUE_H */