Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > Queue_impl
comparison PrivateQueue.c @ 0:85af604dee9b
initial add
| author | Me |
|---|---|
| date | Sat, 22 May 2010 19:51:09 -0700 |
| parents | |
| children | f4d50d8a1a38 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:7202babe6f9e |
|---|---|
| 1 /* | |
| 2 * Copyright 2009 OpenSourceCodeStewardshipFoundation.org | |
| 3 * Licensed under GNU General Public License version 2 | |
| 4 * | |
| 5 * NOTE: this version of SRSW correct as of April 25, 2010 | |
| 6 * | |
| 7 * Author: seanhalle@yahoo.com | |
| 8 */ | |
| 9 | |
| 10 | |
| 11 #include <stdio.h> | |
| 12 #include <string.h> | |
| 13 #include <errno.h> | |
| 14 #include <stdlib.h> | |
| 15 | |
| 16 #include "PrivateQueue.h" | |
| 17 | |
| 18 | |
| 19 | |
| 20 //=========================================================================== | |
| 21 | |
| 22 /*This kind of queue is private to a single core at a time -- has no | |
| 23 * synchronizations | |
| 24 */ | |
| 25 | |
| 26 PrivQueueStruc* makePrivQ() | |
| 27 { | |
| 28 PrivQueueStruc* retQ; | |
| 29 retQ = (PrivQueueStruc *) malloc( sizeof( PrivQueueStruc ) ); | |
| 30 | |
| 31 retQ->startOfData = malloc( 1024 * sizeof(void *) ); | |
| 32 | |
| 33 retQ->extractPos = &(retQ->startOfData[0]); //side by side == empty | |
| 34 retQ->insertPos = &(retQ->startOfData[1]); // so start pos's have to be | |
| 35 retQ->endOfData = &(retQ->startOfData[1023]); | |
| 36 | |
| 37 return retQ; | |
| 38 } | |
| 39 | |
| 40 PrivQueueStruc* make_larger_PrivQ( PrivQueueStruc *Q ) | |
| 41 { int oldSize, newSize; | |
| 42 void **oldStartOfData; | |
| 43 | |
| 44 oldSize = Q->endOfData - Q->startOfData; | |
| 45 newSize = 2 * oldSize; | |
| 46 Q->startOfData = malloc( newSize * sizeof(void *) ); | |
| 47 memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *)); | |
| 48 free(oldStartOfData); | |
| 49 | |
| 50 Q->extractPos = &(Q->startOfData[0]); //side by side == empty | |
| 51 Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be | |
| 52 Q->endOfData = &(Q->startOfData[newSize - 1]); | |
| 53 | |
| 54 return Q; | |
| 55 } | |
| 56 | |
| 57 | |
| 58 /*Returns NULL when queue is empty | |
| 59 */ | |
| 60 void* readPrivQ( PrivQueueStruc* Q ) | |
| 61 { void *out = 0; | |
| 62 int startOfData = Q->startOfData; | |
| 63 int endOfData = Q->endOfData; | |
| 64 | |
| 65 volatile int insertPos = Q->insertPos; | |
| 66 volatile int extractPos = Q->extractPos; | |
| 67 | |
| 68 //if not empty -- extract just below insert when empty | |
| 69 if( insertPos - extractPos != 1 && | |
| 70 !(extractPos == endOfData && insertPos == startOfData)) | |
| 71 { //move before read | |
| 72 if( extractPos == endOfData ) //write new pos exactly once, correctly | |
| 73 { Q->extractPos = startOfData; //can't overrun then fix it 'cause | |
| 74 } // other thread might read bad pos | |
| 75 else | |
| 76 { Q->extractPos++; | |
| 77 } | |
| 78 out = *(Q->extractPos); | |
| 79 return out; | |
| 80 } | |
| 81 //Q is empty | |
| 82 return NULL; | |
| 83 } | |
| 84 | |
| 85 /*Returns false when the queue was full. | |
| 86 * have option of calling make_larger_PrivQ to make more room, then try again | |
| 87 */ | |
| 88 bool8 writePrivQ( void * in, PrivQueueStruc* Q ) | |
| 89 { | |
| 90 int startOfData = Q->startOfData; | |
| 91 int endOfData = Q->endOfData; | |
| 92 | |
| 93 volatile int insertPos = Q->insertPos; | |
| 94 volatile int extractPos = Q->extractPos; | |
| 95 | |
| 96 if( extractPos - insertPos != 1 && | |
| 97 !(insertPos == endOfData && extractPos == startOfData)) | |
| 98 { *(insertPos) = in; //insert before move | |
| 99 if( insertPos == endOfData ) //write new pos exactly once, correctly | |
| 100 { Q->insertPos = startOfData; | |
| 101 } | |
| 102 else | |
| 103 { Q->insertPos++; | |
| 104 } | |
| 105 return TRUE; | |
| 106 } | |
| 107 //Q is full | |
| 108 return FALSE; | |
| 109 } | |
| 110 |
