Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > Queue_impl
diff PrivateQueue.c @ 24:677afc259a58
fix branch to compile with new folder structure
| author | Merten Sach <msach@mailbox.tu-berlin.de> |
|---|---|
| date | Mon, 13 Feb 2012 19:32:12 +0100 |
| parents | 7c9e00ff1bf4 |
| children |
line diff
1.1 --- a/PrivateQueue.c Wed Jun 22 18:49:17 2011 +0200 1.2 +++ b/PrivateQueue.c Mon Feb 13 19:32:12 2012 +0100 1.3 @@ -1,203 +1,203 @@ 1.4 -/* 1.5 - * Copyright 2009 OpenSourceStewardshipFoundation.org 1.6 - * Licensed under GNU General Public License version 2 1.7 - * 1.8 - * Author: seanhalle@yahoo.com 1.9 - */ 1.10 - 1.11 - 1.12 -#include <stdio.h> 1.13 -#include <string.h> 1.14 -#include <errno.h> 1.15 -#include <stdlib.h> 1.16 - 1.17 -#include "PrivateQueue.h" 1.18 -#include "../vmalloc.h" 1.19 - 1.20 - 1.21 - 1.22 -//=========================================================================== 1.23 - 1.24 -/*This kind of queue is private to a single core at a time -- has no 1.25 - * synchronizations 1.26 - */ 1.27 - 1.28 -PrivQueueStruc* makeVMSPrivQ() 1.29 - { 1.30 - PrivQueueStruc *retQ; 1.31 - retQ = VMS__malloc( sizeof( PrivQueueStruc ) ); 1.32 - retQ->startOfData = (void*)VMS__malloc( 1024 * sizeof(void *) ); 1.33 - memset( retQ->startOfData, 0, 1024 ); 1.34 - 1.35 - retQ->extractPos = &(retQ->startOfData[0]); //side by side == empty 1.36 - retQ->insertPos = &(retQ->startOfData[1]); // so start pos's have to be 1.37 - retQ->endOfData = &(retQ->startOfData[1023]); 1.38 - 1.39 - return retQ; 1.40 - } 1.41 - 1.42 - 1.43 -void 1.44 -enlargePrivQ( PrivQueueStruc *Q ) 1.45 - { size_t oldSize, newSize; 1.46 - void **oldStartOfData; 1.47 - 1.48 - oldSize = Q->endOfData - Q->startOfData + 1; 1.49 - newSize = 2 * oldSize; 1.50 - oldStartOfData = Q->startOfData; 1.51 - Q->startOfData = VMS__malloc( newSize * sizeof(void*)); 1.52 - //copy second half 1.53 - size_t secondHalfSize = Q->endOfData - Q->extractPos + 1; 1.54 - memcpy(Q->startOfData,Q->extractPos, secondHalfSize * sizeof(void*)); 1.55 - //copy first half 1.56 - memcpy(Q->startOfData + secondHalfSize, oldStartOfData, 1.57 - (oldSize-secondHalfSize) * sizeof(void*)); 1.58 - VMS__free(oldStartOfData); 1.59 - 1.60 - Q->extractPos = Q->startOfData; 1.61 - Q->insertPos = Q->startOfData + oldSize - 1; 1.62 - Q->endOfData = &(Q->startOfData[newSize - 1]); 1.63 - } 1.64 - 1.65 - 1.66 -/*Returns NULL when queue is empty 1.67 - */ 1.68 -void* readPrivQ( PrivQueueStruc* Q ) 1.69 - { void *out = 0; 1.70 - void **startOfData = Q->startOfData; 1.71 - void **endOfData = Q->endOfData; 1.72 - 1.73 - void **insertPos = Q->insertPos; 1.74 - void **extractPos = Q->extractPos; 1.75 - 1.76 - //if not empty -- (extract is just below insert when empty) 1.77 - if( insertPos - extractPos != 1 && 1.78 - !(extractPos == endOfData && insertPos == startOfData)) 1.79 - { //move before read 1.80 - if( extractPos == endOfData ) //write new pos exactly once, correctly 1.81 - { Q->extractPos = startOfData; //can't overrun then fix it 'cause 1.82 - } // other thread might read bad pos 1.83 - else 1.84 - { Q->extractPos++; 1.85 - } 1.86 - out = *(Q->extractPos); 1.87 - return out; 1.88 - } 1.89 - //Q is empty 1.90 - return NULL; 1.91 - } 1.92 - 1.93 -int32 1.94 -numInPrivQ( PrivQueueStruc *Q ) 1.95 - { int32 size, numIn; 1.96 - 1.97 - if( Q->insertPos < Q->extractPos ) 1.98 - { //insert has wrapped around so numIn is: 1.99 - // insertPos + size - extractPos -- Consider, is empty when 1.100 - // extractPos = endOfData and insert = start -- correctly get zero 1.101 - size = Q->endOfData - Q->startOfData; 1.102 - numIn = Q->insertPos + size - Q->extractPos; 1.103 - } 1.104 - else 1.105 - { 1.106 - numIn = Q->insertPos - Q->extractPos -1;//-1 bec empty @ side-by-side 1.107 - } 1.108 - return numIn; 1.109 - } 1.110 - 1.111 - 1.112 -/*Expands the queue size automatically when it's full 1.113 - */ 1.114 -void 1.115 -writePrivQ( void * in, PrivQueueStruc* Q ) 1.116 - { 1.117 - while(1){ 1.118 - void **startOfData = Q->startOfData; 1.119 - void **endOfData = Q->endOfData; 1.120 - 1.121 - void **insertPos = Q->insertPos; 1.122 - void **extractPos = Q->extractPos; 1.123 - 1.124 - //Full? (insert is just below extract when full) 1.125 - if( extractPos - insertPos != 1 && 1.126 - !(insertPos == endOfData && extractPos == startOfData)) 1.127 - { *(Q->insertPos) = in; //insert before move 1.128 - if( insertPos == endOfData ) //write new pos exactly once, correctly 1.129 - { Q->insertPos = startOfData; 1.130 - } 1.131 - else 1.132 - { Q->insertPos++; 1.133 - } 1.134 - return; 1.135 - } 1.136 - //Q is full 1.137 - enlargePrivQ( Q ); 1.138 - } 1.139 - } 1.140 - 1.141 - 1.142 -/*Returns false when the queue was full. 1.143 - * have option of calling make_larger_PrivQ to make more room, then try again 1.144 - */ 1.145 -int writeIfSpacePrivQ( void * in, PrivQueueStruc* Q ) 1.146 - { 1.147 - void **startOfData = Q->startOfData; 1.148 - void **endOfData = Q->endOfData; 1.149 - 1.150 - void **insertPos = Q->insertPos; 1.151 - void **extractPos = Q->extractPos; 1.152 - 1.153 - if( extractPos - insertPos != 1 && 1.154 - !(insertPos == endOfData && extractPos == startOfData)) 1.155 - { *(Q->insertPos) = in; //insert before move 1.156 - if( insertPos == endOfData ) //write new pos exactly once, correctly 1.157 - { Q->insertPos = startOfData; 1.158 - } 1.159 - else 1.160 - { Q->insertPos++; 1.161 - } 1.162 - return TRUE; 1.163 - } 1.164 - //Q is full 1.165 - return FALSE; 1.166 - } 1.167 - 1.168 -/*Treats queue as a stack -- no matter contents, if read done right after 1.169 - * a push, then the pushed item is what comes out. 1.170 - * Expands the queue size automatically when it's full. 1.171 - */ 1.172 -void 1.173 -pushPrivQ( void * in, PrivQueueStruc* Q ) 1.174 - { 1.175 - while(1){ 1.176 - void **startOfData = Q->startOfData; 1.177 - void **endOfData = Q->endOfData; 1.178 - 1.179 - void **insertPos = Q->insertPos; 1.180 - void **extractPos = Q->extractPos; 1.181 - 1.182 - //Full? (insert is just below extract when full) 1.183 - if( extractPos - insertPos != 1 && 1.184 - !(insertPos == endOfData && extractPos == startOfData)) 1.185 - { //insert -- but go backwards, inserting at read position then 1.186 - // move read pos backwards 1.187 - *(Q->extractPos) = in; 1.188 - if( extractPos == startOfData ) //write new pos exactly once, correctly 1.189 - { Q->extractPos = endOfData; //can't overrun then fix it 'cause 1.190 - } // other thread might read bad pos 1.191 - else 1.192 - { Q->extractPos--; 1.193 - } 1.194 - return; 1.195 - } 1.196 - //Q is full 1.197 - enlargePrivQ( Q ); 1.198 - } 1.199 - } 1.200 - 1.201 -void 1.202 -freePrivQ( PrivQueueStruc *Q ) 1.203 - { 1.204 - VMS__free( Q->startOfData ); 1.205 - VMS__free( Q ); 1.206 +/* 1.207 + * Copyright 2009 OpenSourceStewardshipFoundation.org 1.208 + * Licensed under GNU General Public License version 2 1.209 + * 1.210 + * Author: seanhalle@yahoo.com 1.211 + */ 1.212 + 1.213 + 1.214 +#include <stdio.h> 1.215 +#include <string.h> 1.216 +#include <errno.h> 1.217 +#include <stdlib.h> 1.218 + 1.219 +#include "PrivateQueue.h" 1.220 +#include "VMS_Implementations/VMS_impl/vmalloc.h" 1.221 + 1.222 + 1.223 + 1.224 +//=========================================================================== 1.225 + 1.226 +/*This kind of queue is private to a single core at a time -- has no 1.227 + * synchronizations 1.228 + */ 1.229 + 1.230 +PrivQueueStruc* makePrivQ() 1.231 + { 1.232 + PrivQueueStruc *retQ; 1.233 + retQ = VMS_int__malloc( sizeof( PrivQueueStruc ) ); 1.234 + retQ->startOfData = (void*)VMS_int__malloc( 1024 * sizeof(void *) ); 1.235 + memset( retQ->startOfData, 0, 1024 ); 1.236 + 1.237 + retQ->extractPos = &(retQ->startOfData[0]); //side by side == empty 1.238 + retQ->insertPos = &(retQ->startOfData[1]); // so start pos's have to be 1.239 + retQ->endOfData = &(retQ->startOfData[1023]); 1.240 + 1.241 + return retQ; 1.242 + } 1.243 + 1.244 + 1.245 +void 1.246 +enlargePrivQ( PrivQueueStruc *Q ) 1.247 + { size_t oldSize, newSize; 1.248 + void **oldStartOfData; 1.249 + 1.250 + oldSize = Q->endOfData - Q->startOfData + 1; 1.251 + newSize = 2 * oldSize; 1.252 + oldStartOfData = Q->startOfData; 1.253 + Q->startOfData = VMS_int__malloc( newSize * sizeof(void*)); 1.254 + //copy second half 1.255 + size_t secondHalfSize = Q->endOfData - Q->extractPos + 1; 1.256 + memcpy(Q->startOfData,Q->extractPos, secondHalfSize * sizeof(void*)); 1.257 + //copy first half 1.258 + memcpy(Q->startOfData + secondHalfSize, oldStartOfData, 1.259 + (oldSize-secondHalfSize) * sizeof(void*)); 1.260 + VMS_int__free(oldStartOfData); 1.261 + 1.262 + Q->extractPos = Q->startOfData; 1.263 + Q->insertPos = Q->startOfData + oldSize - 1; 1.264 + Q->endOfData = &(Q->startOfData[newSize - 1]); 1.265 + } 1.266 + 1.267 + 1.268 +/*Returns NULL when queue is empty 1.269 + */ 1.270 +void* readPrivQ( PrivQueueStruc* Q ) 1.271 + { void *out = 0; 1.272 + void **startOfData = Q->startOfData; 1.273 + void **endOfData = Q->endOfData; 1.274 + 1.275 + void **insertPos = Q->insertPos; 1.276 + void **extractPos = Q->extractPos; 1.277 + 1.278 + //if not empty -- (extract is just below insert when empty) 1.279 + if( insertPos - extractPos != 1 && 1.280 + !(extractPos == endOfData && insertPos == startOfData)) 1.281 + { //move before read 1.282 + if( extractPos == endOfData ) //write new pos exactly once, correctly 1.283 + { Q->extractPos = startOfData; //can't overrun then fix it 'cause 1.284 + } // other thread might read bad pos 1.285 + else 1.286 + { Q->extractPos++; 1.287 + } 1.288 + out = *(Q->extractPos); 1.289 + return out; 1.290 + } 1.291 + //Q is empty 1.292 + return NULL; 1.293 + } 1.294 + 1.295 +int32 1.296 +numInPrivQ( PrivQueueStruc *Q ) 1.297 + { int32 size, numIn; 1.298 + 1.299 + if( Q->insertPos < Q->extractPos ) 1.300 + { //insert has wrapped around so numIn is: 1.301 + // insertPos + size - extractPos -- Consider, is empty when 1.302 + // extractPos = endOfData and insert = start -- correctly get zero 1.303 + size = Q->endOfData - Q->startOfData; 1.304 + numIn = Q->insertPos + size - Q->extractPos; 1.305 + } 1.306 + else 1.307 + { 1.308 + numIn = Q->insertPos - Q->extractPos -1;//-1 bec empty @ side-by-side 1.309 + } 1.310 + return numIn; 1.311 + } 1.312 + 1.313 + 1.314 +/*Expands the queue size automatically when it's full 1.315 + */ 1.316 +void 1.317 +writePrivQ( void * in, PrivQueueStruc* Q ) 1.318 + { 1.319 + while(1){ 1.320 + void **startOfData = Q->startOfData; 1.321 + void **endOfData = Q->endOfData; 1.322 + 1.323 + void **insertPos = Q->insertPos; 1.324 + void **extractPos = Q->extractPos; 1.325 + 1.326 + //Full? (insert is just below extract when full) 1.327 + if( extractPos - insertPos != 1 && 1.328 + !(insertPos == endOfData && extractPos == startOfData)) 1.329 + { *(Q->insertPos) = in; //insert before move 1.330 + if( insertPos == endOfData ) //write new pos exactly once, correctly 1.331 + { Q->insertPos = startOfData; 1.332 + } 1.333 + else 1.334 + { Q->insertPos++; 1.335 + } 1.336 + return; 1.337 + } 1.338 + //Q is full 1.339 + enlargePrivQ( Q ); 1.340 + } 1.341 + } 1.342 + 1.343 + 1.344 +/*Returns false when the queue was full. 1.345 + * have option of calling make_larger_PrivQ to make more room, then try again 1.346 + */ 1.347 +int writeIfSpacePrivQ( void * in, PrivQueueStruc* Q ) 1.348 + { 1.349 + void **startOfData = Q->startOfData; 1.350 + void **endOfData = Q->endOfData; 1.351 + 1.352 + void **insertPos = Q->insertPos; 1.353 + void **extractPos = Q->extractPos; 1.354 + 1.355 + if( extractPos - insertPos != 1 && 1.356 + !(insertPos == endOfData && extractPos == startOfData)) 1.357 + { *(Q->insertPos) = in; //insert before move 1.358 + if( insertPos == endOfData ) //write new pos exactly once, correctly 1.359 + { Q->insertPos = startOfData; 1.360 + } 1.361 + else 1.362 + { Q->insertPos++; 1.363 + } 1.364 + return TRUE; 1.365 + } 1.366 + //Q is full 1.367 + return FALSE; 1.368 + } 1.369 + 1.370 +/*Treats queue as a stack -- no matter contents, if read done right after 1.371 + * a push, then the pushed item is what comes out. 1.372 + * Expands the queue size automatically when it's full. 1.373 + */ 1.374 +void 1.375 +pushPrivQ( void * in, PrivQueueStruc* Q ) 1.376 + { 1.377 + while(1){ 1.378 + void **startOfData = Q->startOfData; 1.379 + void **endOfData = Q->endOfData; 1.380 + 1.381 + void **insertPos = Q->insertPos; 1.382 + void **extractPos = Q->extractPos; 1.383 + 1.384 + //Full? (insert is just below extract when full) 1.385 + if( extractPos - insertPos != 1 && 1.386 + !(insertPos == endOfData && extractPos == startOfData)) 1.387 + { //insert -- but go backwards, inserting at read position then 1.388 + // move read pos backwards 1.389 + *(Q->extractPos) = in; 1.390 + if( extractPos == startOfData ) //write new pos exactly once, correctly 1.391 + { Q->extractPos = endOfData; //can't overrun then fix it 'cause 1.392 + } // other thread might read bad pos 1.393 + else 1.394 + { Q->extractPos--; 1.395 + } 1.396 + return; 1.397 + } 1.398 + //Q is full 1.399 + enlargePrivQ( Q ); 1.400 + } 1.401 + } 1.402 + 1.403 +void 1.404 +freePrivQ( PrivQueueStruc *Q ) 1.405 + { 1.406 + VMS_int__free( Q->startOfData ); 1.407 + VMS_int__free( Q ); 1.408 } 1.409 \ No newline at end of file
