Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > Queue_impl
view PrivateQueue.c @ 0:85af604dee9b
initial add
| author | Me |
|---|---|
| date | Sat, 22 May 2010 19:51:09 -0700 |
| parents | |
| children | f4d50d8a1a38 |
line source
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 */
11 #include <stdio.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <stdlib.h>
16 #include "PrivateQueue.h"
20 //===========================================================================
22 /*This kind of queue is private to a single core at a time -- has no
23 * synchronizations
24 */
26 PrivQueueStruc* makePrivQ()
27 {
28 PrivQueueStruc* retQ;
29 retQ = (PrivQueueStruc *) malloc( sizeof( PrivQueueStruc ) );
31 retQ->startOfData = malloc( 1024 * sizeof(void *) );
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]);
37 return retQ;
38 }
40 PrivQueueStruc* make_larger_PrivQ( PrivQueueStruc *Q )
41 { int oldSize, newSize;
42 void **oldStartOfData;
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);
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]);
54 return Q;
55 }
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;
65 volatile int insertPos = Q->insertPos;
66 volatile int extractPos = Q->extractPos;
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 }
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;
93 volatile int insertPos = Q->insertPos;
94 volatile int extractPos = Q->extractPos;
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 }
