Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > Queue_impl
diff PrivateQueue.c @ 0:85af604dee9b
initial add
| author | Me |
|---|---|
| date | Sat, 22 May 2010 19:51:09 -0700 |
| parents | |
| children | f4d50d8a1a38 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/PrivateQueue.c Sat May 22 19:51:09 2010 -0700 1.3 @@ -0,0 +1,110 @@ 1.4 +/* 1.5 + * Copyright 2009 OpenSourceCodeStewardshipFoundation.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 + 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 +PrivQueueStruc* make_larger_PrivQ( PrivQueueStruc *Q ) 1.44 + { int oldSize, newSize; 1.45 + void **oldStartOfData; 1.46 + 1.47 + oldSize = Q->endOfData - Q->startOfData; 1.48 + newSize = 2 * oldSize; 1.49 + Q->startOfData = malloc( newSize * sizeof(void *) ); 1.50 + memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *)); 1.51 + free(oldStartOfData); 1.52 + 1.53 + Q->extractPos = &(Q->startOfData[0]); //side by side == empty 1.54 + Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be 1.55 + Q->endOfData = &(Q->startOfData[newSize - 1]); 1.56 + 1.57 + return Q; 1.58 + } 1.59 + 1.60 + 1.61 +/*Returns NULL when queue is empty 1.62 + */ 1.63 +void* readPrivQ( PrivQueueStruc* Q ) 1.64 + { void *out = 0; 1.65 + int startOfData = Q->startOfData; 1.66 + int endOfData = Q->endOfData; 1.67 + 1.68 + volatile int insertPos = Q->insertPos; 1.69 + volatile int extractPos = Q->extractPos; 1.70 + 1.71 + //if not empty -- extract just below insert when empty 1.72 + if( insertPos - extractPos != 1 && 1.73 + !(extractPos == endOfData && insertPos == startOfData)) 1.74 + { //move before read 1.75 + if( extractPos == endOfData ) //write new pos exactly once, correctly 1.76 + { Q->extractPos = startOfData; //can't overrun then fix it 'cause 1.77 + } // other thread might read bad pos 1.78 + else 1.79 + { Q->extractPos++; 1.80 + } 1.81 + out = *(Q->extractPos); 1.82 + return out; 1.83 + } 1.84 + //Q is empty 1.85 + return NULL; 1.86 + } 1.87 + 1.88 +/*Returns false when the queue was full. 1.89 + * have option of calling make_larger_PrivQ to make more room, then try again 1.90 + */ 1.91 +bool8 writePrivQ( void * in, PrivQueueStruc* Q ) 1.92 + { 1.93 + int startOfData = Q->startOfData; 1.94 + int endOfData = Q->endOfData; 1.95 + 1.96 + volatile int insertPos = Q->insertPos; 1.97 + volatile int extractPos = Q->extractPos; 1.98 + 1.99 + if( extractPos - insertPos != 1 && 1.100 + !(insertPos == endOfData && extractPos == startOfData)) 1.101 + { *(insertPos) = in; //insert before move 1.102 + if( insertPos == endOfData ) //write new pos exactly once, correctly 1.103 + { Q->insertPos = startOfData; 1.104 + } 1.105 + else 1.106 + { Q->insertPos++; 1.107 + } 1.108 + return TRUE; 1.109 + } 1.110 + //Q is full 1.111 + return FALSE; 1.112 + } 1.113 +
