comparison PrivateQueue.c @ 34:c5d2f2a94133

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 1ed562d601d9
children d6da470bbd38
comparison
equal deleted inserted replaced
13:d6e6de89698a 20:11e7c3bb6780
24 */ 24 */
25 25
26 PrivQueueStruc* makePrivQ() 26 PrivQueueStruc* makePrivQ()
27 { 27 {
28 PrivQueueStruc* retQ; 28 PrivQueueStruc* retQ;
29 //This malloc is not safe to use inside VMS-language!
29 retQ = (PrivQueueStruc *) malloc( sizeof( PrivQueueStruc ) ); 30 retQ = (PrivQueueStruc *) malloc( sizeof( PrivQueueStruc ) );
30 31
32 //This malloc is not safe to use inside VMS-language!
31 retQ->startOfData = malloc( 1024 * sizeof(void *) ); 33 retQ->startOfData = malloc( 1024 * sizeof(void *) );
32 memset( retQ->startOfData, 0, 1024 * sizeof(void *) ); 34 memset( retQ->startOfData, 0, 1024 * sizeof(void *) );
33 retQ->extractPos = &(retQ->startOfData[0]); //side by side == empty 35 retQ->extractPos = &(retQ->startOfData[0]); //side by side == empty
34 retQ->insertPos = &(retQ->startOfData[1]); // so start pos's have to be 36 retQ->insertPos = &(retQ->startOfData[1]); // so start pos's have to be
35 retQ->endOfData = &(retQ->startOfData[1023]); 37 retQ->endOfData = &(retQ->startOfData[1023]);
38 } 40 }
39 41
40 42
41 void 43 void
42 enlargePrivQ( PrivQueueStruc *Q ) 44 enlargePrivQ( PrivQueueStruc *Q )
43 { int oldSize, newSize; 45 { int32 oldSize, newSize;
44 void **oldStartOfData; 46 int8 *insertPos, *extractPos;
45 47 int8 *oldStartOfData, *oldEndOfData, *newStartOfData, *newEndOfData;
46 oldSize = Q->endOfData - Q->startOfData; 48 int8 *insertOffsetBytes, *extractOffsetBytes;
47 newSize = 2 * oldSize; 49
48 oldStartOfData = Q->startOfData; 50 oldStartOfData = (int8 *)Q->startOfData;
49 Q->startOfData = malloc( newSize * sizeof(void *) ); 51 oldEndOfData = (int8 *)Q->endOfData;
50 memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *)); 52 insertPos = (int8 *)Q->insertPos;
51 free(oldStartOfData); 53 extractPos = (int8 *)Q->extractPos;
52 54
53 Q->extractPos = &(Q->startOfData[0]); //side by side == empty 55 //TODO: verify these get number of bytes correct
54 Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be 56 insertOffsetBytes = insertPos - oldStartOfData;
55 Q->endOfData = &(Q->startOfData[newSize - 1]); 57 extractOffsetBytes = extractPos - oldStartOfData);
58
59 oldSize = endOfData - startOfData + 1; //in bytes
60 newSize = 2 * oldSize;
61
62 //This malloc is not safe to use inside VMS-language!
63 Q->startOfData = (void **)malloc( newSize );
64 newStartOfData = (int8 *)Q->startOfData;
65 newEndOfData = newStartOfData + newSize; //all calcs in Bytes
66 Q->endOfData = (void **)newEndOfData;
67
68 //TODO: test all of this, for both cases
69
70 //Moving the data and pointers to the new array is
71 //a little trickier than at first it seems.. the top part
72 // of old queue must be moved to the top part of new queue, while
73 // bottom part of old to bottom part of new, then the new insert
74 // and extract positions calculated by offset from top and bottom
75 //UNLESS the one case where old extract was at bottom and insert
76 // was at top.
77 //TODO: check that this is correct!
78 if( extractPos == startOfData && insertPos == endOfData )
79 {
80 memcpy( newStartOfData, oldStartOfData, oldSize ); //oldSize is bytes
81 Q->extractPos = Q->startOfData; //start of valid data
82 Q->insertPos = Q->startOfData + oldSize - 1; //end of valid data
83 }
84 else //have to copy two parts separately, then calc positions
85 { //TODO: check end-addr, sizes, and new positions carefully
86
87 //copy top part, starting at extract up until end of data,
88 // into top of new array
89 topPartSize = oldEndOfData - extractPos + 1; //+1 includes extractPos
90 copyStartAddr = newEndOfData - topPartSize + 1;//+1 cancels other
91 memcpy( copyStartAddr, Q->extractPos, topPartSize );
92 Q->extractPos = (void **)copyStartAddr; //extract just-copied data
93
94 //copy bottom part, from old start up to old insert,
95 // into bottom of new array
96 bottPartSize = oldSize - topPartSize - 1; //-1 for empty insertPos
97 memcpy( newStartOfData, oldStartOfData, bottPartSize );
98 Q->insertPos = (void **)(newStartOfData + bottPartSize);
99 }
100 //This free is not safe to use inside VMS-language!
101 free(oldStartOfData);
56 } 102 }
57 103
58 104
59 /*Returns NULL when queue is empty 105 /*Returns NULL when queue is empty
60 */ 106 */
137 return TRUE; 183 return TRUE;
138 } 184 }
139 //Q is full 185 //Q is full
140 return FALSE; 186 return FALSE;
141 } 187 }
188
189 int32
190 numInPrivQ( PrivQueueStruc *Q )
191 { int32 size, numIn;
192
193 if( Q->insertPos < Q->extractPos )
194 { //insert has wrapped around so numIn is:
195 // insertPos + size - extractPos -- Consider, is empty when
196 // extractPos = endOfData and insert = start -- correctly get zero
197 size = Q->endOfData - Q->startOfData + 1; //sz of 10 is 0..9
198 numIn = Q->insertPos - Q->extractPos + size - 1; //-1 bec insrt empty
199 }
200 else
201 {
202 numIn = Q->insertPos - Q->extractPos -1;//-1 bec insertPos empty
203 }
204 return numIn;
205 }
206
207
208 /*Treats queue as a stack -- no matter contents, if read done right after
209 * a push, then the pushed item is what comes out.
210 * Expands the queue size automatically when it's full.
211 */
212 void
213 pushPrivQ( void * in, PrivQueueStruc* Q )
214 {
215 while(1){
216 void **startOfData = Q->startOfData;
217 void **endOfData = Q->endOfData;
218
219 void **insertPos = Q->insertPos;
220 void **extractPos = Q->extractPos;
221
222 //Full? (insert is just below extract when full)
223 if( extractPos - insertPos != 1 &&
224 !(insertPos == endOfData && extractPos == startOfData))
225 { //insert -- but go backwards, inserting at read position then
226 // move read pos backwards
227 *(Q->extractPos) = in;
228 if( extractPos == startOfData ) //write new pos exactly once, correctly
229 { Q->extractPos = endOfData; //can't overrun then fix it 'cause
230 } // other thread might read bad pos
231 else
232 { Q->extractPos--;
233 }
234 return;
235 }
236 //Q is full
237 enlargePrivQ( Q );
238 }
239 }
240
241
242 void
243 freePrivQ( PrivQueueStruc *Q )
244 {
245 //This free is not safe to use inside VMS-language!
246 free( Q->startOfData );
247 free( Q );
248 }