comparison PrivateQueue.c @ 18:7c9e00ff1bf4

fixed queue enlarging function
author Merten Sach <msach@mailbox.tu-berlin.de>
date Wed, 22 Jun 2011 18:49:17 +0200
parents 1e93e5dbeda1
children 677afc259a58
comparison
equal deleted inserted replaced
11:9e5d29d7b4f4 12:4f82930118bf
37 } 37 }
38 38
39 39
40 void 40 void
41 enlargePrivQ( PrivQueueStruc *Q ) 41 enlargePrivQ( PrivQueueStruc *Q )
42 { int oldSize, newSize; 42 { size_t oldSize, newSize;
43 void **oldStartOfData; 43 void **oldStartOfData;
44 44
45 oldSize = Q->endOfData - Q->startOfData; 45 oldSize = Q->endOfData - Q->startOfData + 1;
46 newSize = 2 * oldSize; 46 newSize = 2 * oldSize;
47 oldStartOfData = Q->startOfData; 47 oldStartOfData = Q->startOfData;
48 Q->startOfData = VMS__malloc( newSize * sizeof(void *) ); 48 Q->startOfData = VMS__malloc( newSize * sizeof(void*));
49 memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *)); 49 //copy second half
50 size_t secondHalfSize = Q->endOfData - Q->extractPos + 1;
51 memcpy(Q->startOfData,Q->extractPos, secondHalfSize * sizeof(void*));
52 //copy first half
53 memcpy(Q->startOfData + secondHalfSize, oldStartOfData,
54 (oldSize-secondHalfSize) * sizeof(void*));
50 VMS__free(oldStartOfData); 55 VMS__free(oldStartOfData);
51 56
52 Q->extractPos = &(Q->startOfData[0]); //side by side == empty 57 Q->extractPos = Q->startOfData;
53 Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be 58 Q->insertPos = Q->startOfData + oldSize - 1;
54 Q->endOfData = &(Q->startOfData[newSize - 1]); 59 Q->endOfData = &(Q->startOfData[newSize - 1]);
55 } 60 }
56 61
57 62
58 /*Returns NULL when queue is empty 63 /*Returns NULL when queue is empty
104 /*Expands the queue size automatically when it's full 109 /*Expands the queue size automatically when it's full
105 */ 110 */
106 void 111 void
107 writePrivQ( void * in, PrivQueueStruc* Q ) 112 writePrivQ( void * in, PrivQueueStruc* Q )
108 { 113 {
109 void **startOfData = Q->startOfData; 114 while(1){
110 void **endOfData = Q->endOfData; 115 void **startOfData = Q->startOfData;
111 116 void **endOfData = Q->endOfData;
112 void **insertPos = Q->insertPos; 117
113 void **extractPos = Q->extractPos; 118 void **insertPos = Q->insertPos;
114 119 void **extractPos = Q->extractPos;
115 tryAgain: 120
116 //Full? (insert is just below extract when full) 121 //Full? (insert is just below extract when full)
117 if( extractPos - insertPos != 1 && 122 if( extractPos - insertPos != 1 &&
118 !(insertPos == endOfData && extractPos == startOfData)) 123 !(insertPos == endOfData && extractPos == startOfData))
119 { *(Q->insertPos) = in; //insert before move 124 { *(Q->insertPos) = in; //insert before move
120 if( insertPos == endOfData ) //write new pos exactly once, correctly 125 if( insertPos == endOfData ) //write new pos exactly once, correctly
121 { Q->insertPos = startOfData; 126 { Q->insertPos = startOfData;
122 } 127 }
123 else 128 else
124 { Q->insertPos++; 129 { Q->insertPos++;
125 } 130 }
126 return; 131 return;
127 } 132 }
128 //Q is full 133 //Q is full
129 enlargePrivQ( Q ); 134 enlargePrivQ( Q );
130 goto tryAgain; 135 }
131 } 136 }
132 137
133 138
134 /*Returns false when the queue was full. 139 /*Returns false when the queue was full.
135 * have option of calling make_larger_PrivQ to make more room, then try again 140 * have option of calling make_larger_PrivQ to make more room, then try again
162 * Expands the queue size automatically when it's full. 167 * Expands the queue size automatically when it's full.
163 */ 168 */
164 void 169 void
165 pushPrivQ( void * in, PrivQueueStruc* Q ) 170 pushPrivQ( void * in, PrivQueueStruc* Q )
166 { 171 {
167 void **startOfData = Q->startOfData; 172 while(1){
168 void **endOfData = Q->endOfData; 173 void **startOfData = Q->startOfData;
169 174 void **endOfData = Q->endOfData;
170 void **insertPos = Q->insertPos; 175
171 void **extractPos = Q->extractPos; 176 void **insertPos = Q->insertPos;
172 177 void **extractPos = Q->extractPos;
173 tryAgain: 178
174 //Full? (insert is just below extract when full) 179 //Full? (insert is just below extract when full)
175 if( extractPos - insertPos != 1 && 180 if( extractPos - insertPos != 1 &&
176 !(insertPos == endOfData && extractPos == startOfData)) 181 !(insertPos == endOfData && extractPos == startOfData))
177 { //insert -- but go backwards, inserting at read position then 182 { //insert -- but go backwards, inserting at read position then
178 // move read pos backwards 183 // move read pos backwards
179 *(Q->extractPos) = in; 184 *(Q->extractPos) = in;
180 if( extractPos == startOfData ) //write new pos exactly once, correctly 185 if( extractPos == startOfData ) //write new pos exactly once, correctly
181 { Q->extractPos = endOfData; //can't overrun then fix it 'cause 186 { Q->extractPos = endOfData; //can't overrun then fix it 'cause
182 } // other thread might read bad pos 187 } // other thread might read bad pos
183 else 188 else
184 { Q->extractPos--; 189 { Q->extractPos--;
185 } 190 }
186 return; 191 return;
187 } 192 }
188 //Q is full 193 //Q is full
189 enlargePrivQ( Q ); 194 enlargePrivQ( Q );
190 goto tryAgain; 195 }
191 } 196 }
192 197
193 void 198 void
194 freePrivQ( PrivQueueStruc *Q ) 199 freePrivQ( PrivQueueStruc *Q )
195 { 200 {