Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > Queue_impl
diff PrivateQueue.c @ 19:1ed562d601d9
Newly created project repository -- commit sub-states
| author | Me@portablequad |
|---|---|
| date | Tue, 07 Feb 2012 12:51:29 -0800 |
| parents | 53c614b781ce |
| children | b5ae7fbb1f01 c5d2f2a94133 |
line diff
1.1 --- a/PrivateQueue.c Thu Nov 04 17:50:29 2010 -0700 1.2 +++ b/PrivateQueue.c Tue Feb 07 12:51:29 2012 -0800 1.3 @@ -1,141 +1,141 @@ 1.4 -/* 1.5 - * Copyright 2009 OpenSourceStewardshipFoundation.org 1.6 - * Licensed under GNU General Public License version 2 1.7 - * 1.8 - * NOTE: this version of SRSW correct as of April 25, 2010 1.9 - * 1.10 - * Author: seanhalle@yahoo.com 1.11 - */ 1.12 - 1.13 - 1.14 -#include <stdio.h> 1.15 -#include <string.h> 1.16 -#include <errno.h> 1.17 -#include <stdlib.h> 1.18 - 1.19 -#include "PrivateQueue.h" 1.20 - 1.21 - 1.22 - 1.23 -//=========================================================================== 1.24 - 1.25 -/*This kind of queue is private to a single core at a time -- has no 1.26 - * synchronizations 1.27 - */ 1.28 - 1.29 -PrivQueueStruc* makePrivQ() 1.30 - { 1.31 - PrivQueueStruc* retQ; 1.32 - retQ = (PrivQueueStruc *) malloc( sizeof( PrivQueueStruc ) ); 1.33 - 1.34 - retQ->startOfData = malloc( 1024 * sizeof(void *) ); 1.35 - memset( retQ->startOfData, 0, 1024 * sizeof(void *) ); 1.36 - retQ->extractPos = &(retQ->startOfData[0]); //side by side == empty 1.37 - retQ->insertPos = &(retQ->startOfData[1]); // so start pos's have to be 1.38 - retQ->endOfData = &(retQ->startOfData[1023]); 1.39 - 1.40 - return retQ; 1.41 - } 1.42 - 1.43 - 1.44 -void 1.45 -enlargePrivQ( PrivQueueStruc *Q ) 1.46 - { int oldSize, newSize; 1.47 - void **oldStartOfData; 1.48 - 1.49 - oldSize = Q->endOfData - Q->startOfData; 1.50 - newSize = 2 * oldSize; 1.51 - oldStartOfData = Q->startOfData; 1.52 - Q->startOfData = malloc( newSize * sizeof(void *) ); 1.53 - memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *)); 1.54 - free(oldStartOfData); 1.55 - 1.56 - Q->extractPos = &(Q->startOfData[0]); //side by side == empty 1.57 - Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be 1.58 - Q->endOfData = &(Q->startOfData[newSize - 1]); 1.59 - } 1.60 - 1.61 - 1.62 -/*Returns NULL when queue is empty 1.63 - */ 1.64 -void* readPrivQ( PrivQueueStruc* Q ) 1.65 - { void *out = 0; 1.66 - void **startOfData = Q->startOfData; 1.67 - void **endOfData = Q->endOfData; 1.68 - 1.69 - void **insertPos = Q->insertPos; 1.70 - void **extractPos = Q->extractPos; 1.71 - 1.72 - //if not empty -- (extract is just below insert when empty) 1.73 - if( insertPos - extractPos != 1 && 1.74 - !(extractPos == endOfData && insertPos == startOfData)) 1.75 - { //move before read 1.76 - if( extractPos == endOfData ) //write new pos exactly once, correctly 1.77 - { Q->extractPos = startOfData; //can't overrun then fix it 'cause 1.78 - } // other thread might read bad pos 1.79 - else 1.80 - { Q->extractPos++; 1.81 - } 1.82 - out = *(Q->extractPos); 1.83 - return out; 1.84 - } 1.85 - //Q is empty 1.86 - return NULL; 1.87 - } 1.88 - 1.89 - 1.90 -/*Expands the queue size automatically when it's full 1.91 - */ 1.92 -void 1.93 -writePrivQ( void * in, PrivQueueStruc* Q ) 1.94 - { 1.95 - void **startOfData = Q->startOfData; 1.96 - void **endOfData = Q->endOfData; 1.97 - 1.98 - void **insertPos = Q->insertPos; 1.99 - void **extractPos = Q->extractPos; 1.100 - 1.101 -tryAgain: 1.102 - //Full? (insert is just below extract when full) 1.103 - if( extractPos - insertPos != 1 && 1.104 - !(insertPos == endOfData && extractPos == startOfData)) 1.105 - { *(Q->insertPos) = in; //insert before move 1.106 - if( insertPos == endOfData ) //write new pos exactly once, correctly 1.107 - { Q->insertPos = startOfData; 1.108 - } 1.109 - else 1.110 - { Q->insertPos++; 1.111 - } 1.112 - return; 1.113 - } 1.114 - //Q is full 1.115 - enlargePrivQ( Q ); 1.116 - goto tryAgain; 1.117 - } 1.118 - 1.119 - 1.120 -/*Returns false when the queue was full. 1.121 - * have option of calling make_larger_PrivQ to make more room, then try again 1.122 - */ 1.123 -int writeIfSpacePrivQ( void * in, PrivQueueStruc* Q ) 1.124 - { 1.125 - void **startOfData = Q->startOfData; 1.126 - void **endOfData = Q->endOfData; 1.127 - 1.128 - void **insertPos = Q->insertPos; 1.129 - void **extractPos = Q->extractPos; 1.130 - 1.131 - if( extractPos - insertPos != 1 && 1.132 - !(insertPos == endOfData && extractPos == startOfData)) 1.133 - { *(Q->insertPos) = in; //insert before move 1.134 - if( insertPos == endOfData ) //write new pos exactly once, correctly 1.135 - { Q->insertPos = startOfData; 1.136 - } 1.137 - else 1.138 - { Q->insertPos++; 1.139 - } 1.140 - return TRUE; 1.141 - } 1.142 - //Q is full 1.143 - return FALSE; 1.144 - } 1.145 +/* 1.146 + * Copyright 2009 OpenSourceStewardshipFoundation.org 1.147 + * Licensed under GNU General Public License version 2 1.148 + * 1.149 + * NOTE: this version of SRSW correct as of April 25, 2010 1.150 + * 1.151 + * Author: seanhalle@yahoo.com 1.152 + */ 1.153 + 1.154 + 1.155 +#include <stdio.h> 1.156 +#include <string.h> 1.157 +#include <errno.h> 1.158 +#include <stdlib.h> 1.159 + 1.160 +#include "PrivateQueue.h" 1.161 + 1.162 + 1.163 + 1.164 +//=========================================================================== 1.165 + 1.166 +/*This kind of queue is private to a single core at a time -- has no 1.167 + * synchronizations 1.168 + */ 1.169 + 1.170 +PrivQueueStruc* makePrivQ() 1.171 + { 1.172 + PrivQueueStruc* retQ; 1.173 + retQ = (PrivQueueStruc *) malloc( sizeof( PrivQueueStruc ) ); 1.174 + 1.175 + retQ->startOfData = malloc( 1024 * sizeof(void *) ); 1.176 + memset( retQ->startOfData, 0, 1024 * sizeof(void *) ); 1.177 + retQ->extractPos = &(retQ->startOfData[0]); //side by side == empty 1.178 + retQ->insertPos = &(retQ->startOfData[1]); // so start pos's have to be 1.179 + retQ->endOfData = &(retQ->startOfData[1023]); 1.180 + 1.181 + return retQ; 1.182 + } 1.183 + 1.184 + 1.185 +void 1.186 +enlargePrivQ( PrivQueueStruc *Q ) 1.187 + { int oldSize, newSize; 1.188 + void **oldStartOfData; 1.189 + 1.190 + oldSize = Q->endOfData - Q->startOfData; 1.191 + newSize = 2 * oldSize; 1.192 + oldStartOfData = Q->startOfData; 1.193 + Q->startOfData = malloc( newSize * sizeof(void *) ); 1.194 + memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *)); 1.195 + free(oldStartOfData); 1.196 + 1.197 + Q->extractPos = &(Q->startOfData[0]); //side by side == empty 1.198 + Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be 1.199 + Q->endOfData = &(Q->startOfData[newSize - 1]); 1.200 + } 1.201 + 1.202 + 1.203 +/*Returns NULL when queue is empty 1.204 + */ 1.205 +void* readPrivQ( PrivQueueStruc* Q ) 1.206 + { void *out = 0; 1.207 + void **startOfData = Q->startOfData; 1.208 + void **endOfData = Q->endOfData; 1.209 + 1.210 + void **insertPos = Q->insertPos; 1.211 + void **extractPos = Q->extractPos; 1.212 + 1.213 + //if not empty -- (extract is just below insert when empty) 1.214 + if( insertPos - extractPos != 1 && 1.215 + !(extractPos == endOfData && insertPos == startOfData)) 1.216 + { //move before read 1.217 + if( extractPos == endOfData ) //write new pos exactly once, correctly 1.218 + { Q->extractPos = startOfData; //can't overrun then fix it 'cause 1.219 + } // other thread might read bad pos 1.220 + else 1.221 + { Q->extractPos++; 1.222 + } 1.223 + out = *(Q->extractPos); 1.224 + return out; 1.225 + } 1.226 + //Q is empty 1.227 + return NULL; 1.228 + } 1.229 + 1.230 + 1.231 +/*Expands the queue size automatically when it's full 1.232 + */ 1.233 +void 1.234 +writePrivQ( void * in, PrivQueueStruc* Q ) 1.235 + { 1.236 + void **startOfData = Q->startOfData; 1.237 + void **endOfData = Q->endOfData; 1.238 + 1.239 + void **insertPos = Q->insertPos; 1.240 + void **extractPos = Q->extractPos; 1.241 + 1.242 +tryAgain: 1.243 + //Full? (insert is just below extract when full) 1.244 + if( extractPos - insertPos != 1 && 1.245 + !(insertPos == endOfData && extractPos == startOfData)) 1.246 + { *(Q->insertPos) = in; //insert before move 1.247 + if( insertPos == endOfData ) //write new pos exactly once, correctly 1.248 + { Q->insertPos = startOfData; 1.249 + } 1.250 + else 1.251 + { Q->insertPos++; 1.252 + } 1.253 + return; 1.254 + } 1.255 + //Q is full 1.256 + enlargePrivQ( Q ); 1.257 + goto tryAgain; 1.258 + } 1.259 + 1.260 + 1.261 +/*Returns false when the queue was full. 1.262 + * have option of calling make_larger_PrivQ to make more room, then try again 1.263 + */ 1.264 +int writeIfSpacePrivQ( void * in, PrivQueueStruc* Q ) 1.265 + { 1.266 + void **startOfData = Q->startOfData; 1.267 + void **endOfData = Q->endOfData; 1.268 + 1.269 + void **insertPos = Q->insertPos; 1.270 + void **extractPos = Q->extractPos; 1.271 + 1.272 + if( extractPos - insertPos != 1 && 1.273 + !(insertPos == endOfData && extractPos == startOfData)) 1.274 + { *(Q->insertPos) = in; //insert before move 1.275 + if( insertPos == endOfData ) //write new pos exactly once, correctly 1.276 + { Q->insertPos = startOfData; 1.277 + } 1.278 + else 1.279 + { Q->insertPos++; 1.280 + } 1.281 + return TRUE; 1.282 + } 1.283 + //Q is full 1.284 + return FALSE; 1.285 + }
