Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > Queue_impl
view PrivateQueue.c @ 11:3562716ebdbd
added numInPrivQ service
| author | Me |
|---|---|
| date | Thu, 04 Nov 2010 17:54:08 -0700 |
| parents | 62326cc8e6f4 |
| children | 3134d8a1e8e3 447e97a52426 |
line source
1 /*
2 * Copyright 2009 OpenSourceStewardshipFoundation.org
3 * Licensed under GNU General Public License version 2
4 *
5 * Author: seanhalle@yahoo.com
6 */
9 #include <stdio.h>
10 #include <string.h>
11 #include <errno.h>
12 #include <stdlib.h>
14 #include "PrivateQueue.h"
18 //===========================================================================
20 /*This kind of queue is private to a single core at a time -- has no
21 * synchronizations
22 */
24 PrivQueueStruc* makePrivQ()
25 {
26 PrivQueueStruc* retQ;
27 retQ = (PrivQueueStruc *) VMS__malloc( sizeof( PrivQueueStruc ) );
29 retQ->startOfData = VMS__malloc( 1024 * sizeof(void *) );
31 retQ->extractPos = &(retQ->startOfData[0]); //side by side == empty
32 retQ->insertPos = &(retQ->startOfData[1]); // so start pos's have to be
33 retQ->endOfData = &(retQ->startOfData[1023]);
35 return retQ;
36 }
39 void
40 enlargePrivQ( PrivQueueStruc *Q )
41 { int oldSize, newSize;
42 void **oldStartOfData;
44 oldSize = Q->endOfData - Q->startOfData;
45 newSize = 2 * oldSize;
46 oldStartOfData = Q->startOfData;
47 Q->startOfData = VMS__malloc( newSize * sizeof(void *) );
48 memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *));
49 VMS__free(oldStartOfData);
51 Q->extractPos = &(Q->startOfData[0]); //side by side == empty
52 Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be
53 Q->endOfData = &(Q->startOfData[newSize - 1]);
54 }
57 /*Returns NULL when queue is empty
58 */
59 void* readPrivQ( PrivQueueStruc* Q )
60 { void *out = 0;
61 void **startOfData = Q->startOfData;
62 void **endOfData = Q->endOfData;
64 void **insertPos = Q->insertPos;
65 void **extractPos = Q->extractPos;
67 //if not empty -- (extract is just below insert when empty)
68 if( insertPos - extractPos != 1 &&
69 !(extractPos == endOfData && insertPos == startOfData))
70 { //move before read
71 if( extractPos == endOfData ) //write new pos exactly once, correctly
72 { Q->extractPos = startOfData; //can't overrun then fix it 'cause
73 } // other thread might read bad pos
74 else
75 { Q->extractPos++;
76 }
77 out = *(Q->extractPos);
78 return out;
79 }
80 //Q is empty
81 return NULL;
82 }
84 int32
85 numInPrivQ( PrivQueueStruc *Q )
86 { int32 size, numIn;
88 if( Q->insertPos < Q->extractPos )
89 { //insert has wrapped around so numIn is:
90 // insertPos + size - extractPos -- Consider, is empty when
91 // extractPos = endOfData and insert = start -- correctly get zero
92 size = Q->endOfData - Q->startOfData;
93 numIn = Q->insertPos + size - Q->extractPos;
94 }
95 else
96 {
97 numIn = Q->insertPos - Q->extractPos -1;//-1 bec empty @ side-by-side
98 }
99 return numIn;
100 }
103 /*Expands the queue size automatically when it's full
104 */
105 void
106 writePrivQ( void * in, PrivQueueStruc* Q )
107 {
108 void **startOfData = Q->startOfData;
109 void **endOfData = Q->endOfData;
111 void **insertPos = Q->insertPos;
112 void **extractPos = Q->extractPos;
114 tryAgain:
115 //Full? (insert is just below extract when full)
116 if( extractPos - insertPos != 1 &&
117 !(insertPos == endOfData && extractPos == startOfData))
118 { *(Q->insertPos) = in; //insert before move
119 if( insertPos == endOfData ) //write new pos exactly once, correctly
120 { Q->insertPos = startOfData;
121 }
122 else
123 { Q->insertPos++;
124 }
125 return;
126 }
127 //Q is full
128 enlargePrivQ( Q );
129 goto tryAgain;
130 }
133 /*Returns false when the queue was full.
134 * have option of calling make_larger_PrivQ to make more room, then try again
135 */
136 int writeIfSpacePrivQ( void * in, PrivQueueStruc* Q )
137 {
138 void **startOfData = Q->startOfData;
139 void **endOfData = Q->endOfData;
141 void **insertPos = Q->insertPos;
142 void **extractPos = Q->extractPos;
144 if( extractPos - insertPos != 1 &&
145 !(insertPos == endOfData && extractPos == startOfData))
146 { *(Q->insertPos) = in; //insert before move
147 if( insertPos == endOfData ) //write new pos exactly once, correctly
148 { Q->insertPos = startOfData;
149 }
150 else
151 { Q->insertPos++;
152 }
153 return TRUE;
154 }
155 //Q is full
156 return FALSE;
157 }
159 void
160 freePrivQ( PrivQueueStruc *Q )
161 {
162 VMS__free( Q->startOfData );
163 VMS__free( Q );
164 }
