Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > Queue_impl
changeset 34:c5d2f2a94133 pure_C
updated to fixed versions from MC_shared brch, then removed VMS_ from malloc
| author | Some Random Person <seanhalle@yahoo.com> |
|---|---|
| date | Wed, 14 Mar 2012 23:02:28 -0700 |
| parents | 7742a5e0d92e |
| children | d6da470bbd38 |
| files | PrivateQueue.c PrivateQueue.h |
| diffstat | 2 files changed, 128 insertions(+), 15 deletions(-) [+] |
line diff
1.1 --- a/PrivateQueue.c Mon Feb 13 13:29:51 2012 -0800 1.2 +++ b/PrivateQueue.c Wed Mar 14 23:02:28 2012 -0700 1.3 @@ -26,8 +26,10 @@ 1.4 PrivQueueStruc* makePrivQ() 1.5 { 1.6 PrivQueueStruc* retQ; 1.7 + //This malloc is not safe to use inside VMS-language! 1.8 retQ = (PrivQueueStruc *) malloc( sizeof( PrivQueueStruc ) ); 1.9 1.10 + //This malloc is not safe to use inside VMS-language! 1.11 retQ->startOfData = malloc( 1024 * sizeof(void *) ); 1.12 memset( retQ->startOfData, 0, 1024 * sizeof(void *) ); 1.13 retQ->extractPos = &(retQ->startOfData[0]); //side by side == empty 1.14 @@ -40,19 +42,63 @@ 1.15 1.16 void 1.17 enlargePrivQ( PrivQueueStruc *Q ) 1.18 - { int oldSize, newSize; 1.19 - void **oldStartOfData; 1.20 + { int32 oldSize, newSize; 1.21 + int8 *insertPos, *extractPos; 1.22 + int8 *oldStartOfData, *oldEndOfData, *newStartOfData, *newEndOfData; 1.23 + int8 *insertOffsetBytes, *extractOffsetBytes; 1.24 1.25 - oldSize = Q->endOfData - Q->startOfData; 1.26 - newSize = 2 * oldSize; 1.27 - oldStartOfData = Q->startOfData; 1.28 - Q->startOfData = malloc( newSize * sizeof(void *) ); 1.29 - memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *)); 1.30 - free(oldStartOfData); 1.31 + oldStartOfData = (int8 *)Q->startOfData; 1.32 + oldEndOfData = (int8 *)Q->endOfData; 1.33 + insertPos = (int8 *)Q->insertPos; 1.34 + extractPos = (int8 *)Q->extractPos; 1.35 1.36 - Q->extractPos = &(Q->startOfData[0]); //side by side == empty 1.37 - Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be 1.38 - Q->endOfData = &(Q->startOfData[newSize - 1]); 1.39 + //TODO: verify these get number of bytes correct 1.40 + insertOffsetBytes = insertPos - oldStartOfData; 1.41 + extractOffsetBytes = extractPos - oldStartOfData); 1.42 + 1.43 + oldSize = endOfData - startOfData + 1; //in bytes 1.44 + newSize = 2 * oldSize; 1.45 + 1.46 + //This malloc is not safe to use inside VMS-language! 1.47 + Q->startOfData = (void **)malloc( newSize ); 1.48 + newStartOfData = (int8 *)Q->startOfData; 1.49 + newEndOfData = newStartOfData + newSize; //all calcs in Bytes 1.50 + Q->endOfData = (void **)newEndOfData; 1.51 + 1.52 + //TODO: test all of this, for both cases 1.53 + 1.54 + //Moving the data and pointers to the new array is 1.55 + //a little trickier than at first it seems.. the top part 1.56 + // of old queue must be moved to the top part of new queue, while 1.57 + // bottom part of old to bottom part of new, then the new insert 1.58 + // and extract positions calculated by offset from top and bottom 1.59 + //UNLESS the one case where old extract was at bottom and insert 1.60 + // was at top. 1.61 + //TODO: check that this is correct! 1.62 + if( extractPos == startOfData && insertPos == endOfData ) 1.63 + { 1.64 + memcpy( newStartOfData, oldStartOfData, oldSize ); //oldSize is bytes 1.65 + Q->extractPos = Q->startOfData; //start of valid data 1.66 + Q->insertPos = Q->startOfData + oldSize - 1; //end of valid data 1.67 + } 1.68 + else //have to copy two parts separately, then calc positions 1.69 + { //TODO: check end-addr, sizes, and new positions carefully 1.70 + 1.71 + //copy top part, starting at extract up until end of data, 1.72 + // into top of new array 1.73 + topPartSize = oldEndOfData - extractPos + 1; //+1 includes extractPos 1.74 + copyStartAddr = newEndOfData - topPartSize + 1;//+1 cancels other 1.75 + memcpy( copyStartAddr, Q->extractPos, topPartSize ); 1.76 + Q->extractPos = (void **)copyStartAddr; //extract just-copied data 1.77 + 1.78 + //copy bottom part, from old start up to old insert, 1.79 + // into bottom of new array 1.80 + bottPartSize = oldSize - topPartSize - 1; //-1 for empty insertPos 1.81 + memcpy( newStartOfData, oldStartOfData, bottPartSize ); 1.82 + Q->insertPos = (void **)(newStartOfData + bottPartSize); 1.83 + } 1.84 + //This free is not safe to use inside VMS-language! 1.85 + free(oldStartOfData); 1.86 } 1.87 1.88 1.89 @@ -139,3 +185,64 @@ 1.90 //Q is full 1.91 return FALSE; 1.92 } 1.93 + 1.94 +int32 1.95 +numInPrivQ( PrivQueueStruc *Q ) 1.96 + { int32 size, numIn; 1.97 + 1.98 + if( Q->insertPos < Q->extractPos ) 1.99 + { //insert has wrapped around so numIn is: 1.100 + // insertPos + size - extractPos -- Consider, is empty when 1.101 + // extractPos = endOfData and insert = start -- correctly get zero 1.102 + size = Q->endOfData - Q->startOfData + 1; //sz of 10 is 0..9 1.103 + numIn = Q->insertPos - Q->extractPos + size - 1; //-1 bec insrt empty 1.104 + } 1.105 + else 1.106 + { 1.107 + numIn = Q->insertPos - Q->extractPos -1;//-1 bec insertPos empty 1.108 + } 1.109 + return numIn; 1.110 + } 1.111 + 1.112 + 1.113 +/*Treats queue as a stack -- no matter contents, if read done right after 1.114 + * a push, then the pushed item is what comes out. 1.115 + * Expands the queue size automatically when it's full. 1.116 + */ 1.117 +void 1.118 +pushPrivQ( void * in, PrivQueueStruc* Q ) 1.119 + { 1.120 + while(1){ 1.121 + void **startOfData = Q->startOfData; 1.122 + void **endOfData = Q->endOfData; 1.123 + 1.124 + void **insertPos = Q->insertPos; 1.125 + void **extractPos = Q->extractPos; 1.126 + 1.127 + //Full? (insert is just below extract when full) 1.128 + if( extractPos - insertPos != 1 && 1.129 + !(insertPos == endOfData && extractPos == startOfData)) 1.130 + { //insert -- but go backwards, inserting at read position then 1.131 + // move read pos backwards 1.132 + *(Q->extractPos) = in; 1.133 + if( extractPos == startOfData ) //write new pos exactly once, correctly 1.134 + { Q->extractPos = endOfData; //can't overrun then fix it 'cause 1.135 + } // other thread might read bad pos 1.136 + else 1.137 + { Q->extractPos--; 1.138 + } 1.139 + return; 1.140 + } 1.141 + //Q is full 1.142 + enlargePrivQ( Q ); 1.143 + } 1.144 + } 1.145 + 1.146 + 1.147 + void 1.148 + freePrivQ( PrivQueueStruc *Q ) 1.149 + { 1.150 + //This free is not safe to use inside VMS-language! 1.151 + free( Q->startOfData ); 1.152 + free( Q ); 1.153 + } 1.154 \ No newline at end of file
2.1 --- a/PrivateQueue.h Mon Feb 13 13:29:51 2012 -0800 2.2 +++ b/PrivateQueue.h Wed Mar 14 23:02:28 2012 -0700 2.3 @@ -8,7 +8,9 @@ 2.4 #ifndef _PRIVATE_QUEUE_H 2.5 #define _PRIVATE_QUEUE_H 2.6 2.7 -#include <pthread.h> 2.8 + 2.9 +#include "VMS_impl/VMS_primitive_data_types.h" 2.10 + 2.11 2.12 #define TRUE 1 2.13 #define FALSE 0 2.14 @@ -26,12 +28,16 @@ 2.15 } 2.16 PrivQueueStruc; 2.17 2.18 +typedef void (*DynArrayFnPtr) ( void * ); //fn has to cast void * 2.19 2.20 PrivQueueStruc* makePrivQ ( ); 2.21 -void* readPrivQ ( PrivQueueStruc *Q ); 2.22 +void* readPrivQ ( PrivQueueStruc *Q ); //ret NULL if empty 2.23 void writePrivQ( void *in, PrivQueueStruc *Q ); 2.24 -int writeIfSpacePrivQ( void * in, PrivQueueStruc* Q ); //return 2.25 - // false when full 2.26 + //return false when full 2.27 +bool32 writeIfSpacePrivQ( void * in, PrivQueueStruc* Q ); 2.28 +int32 numInPrivQ( PrivQueueStruc *Q ); 2.29 +void pushPrivQ( void * in, PrivQueueStruc* Q ); 2.30 +void freePrivQ( PrivQueueStruc *Q ); 2.31 2.32 #endif /* _PRIVATE_QUEUE_H */ 2.33
