| rev |
line source |
|
Me@0
|
1 /*
|
|
Me@8
|
2 * Copyright 2009 OpenSourceStewardshipFoundation.org
|
|
Me@0
|
3 * Licensed under GNU General Public License version 2
|
|
Me@0
|
4 *
|
|
Me@0
|
5 * NOTE: this version of SRSW correct as of April 25, 2010
|
|
Me@0
|
6 *
|
|
Me@0
|
7 * Author: seanhalle@yahoo.com
|
|
Me@0
|
8 */
|
|
Me@0
|
9
|
|
Me@0
|
10
|
|
Me@0
|
11 #include <stdio.h>
|
|
Me@0
|
12 #include <string.h>
|
|
Me@0
|
13 #include <errno.h>
|
|
Me@0
|
14 #include <stdlib.h>
|
|
Me@0
|
15
|
|
Me@0
|
16 #include "PrivateQueue.h"
|
|
Me@0
|
17
|
|
Me@0
|
18
|
|
Me@0
|
19
|
|
Me@0
|
20 //===========================================================================
|
|
Me@0
|
21
|
|
Me@0
|
22 /*This kind of queue is private to a single core at a time -- has no
|
|
Me@0
|
23 * synchronizations
|
|
Me@0
|
24 */
|
|
Me@0
|
25
|
|
Me@0
|
26 PrivQueueStruc* makePrivQ()
|
|
Me@0
|
27 {
|
|
Me@0
|
28 PrivQueueStruc* retQ;
|
|
Me@0
|
29 retQ = (PrivQueueStruc *) malloc( sizeof( PrivQueueStruc ) );
|
|
Me@0
|
30
|
|
Me@0
|
31 retQ->startOfData = malloc( 1024 * sizeof(void *) );
|
|
Me@13
|
32 memset( retQ->startOfData, 0, 1024 * sizeof(void *) );
|
|
Me@0
|
33 retQ->extractPos = &(retQ->startOfData[0]); //side by side == empty
|
|
Me@0
|
34 retQ->insertPos = &(retQ->startOfData[1]); // so start pos's have to be
|
|
Me@0
|
35 retQ->endOfData = &(retQ->startOfData[1023]);
|
|
Me@0
|
36
|
|
Me@0
|
37 return retQ;
|
|
Me@0
|
38 }
|
|
Me@0
|
39
|
|
Me@2
|
40
|
|
Me@2
|
41 void
|
|
Me@2
|
42 enlargePrivQ( PrivQueueStruc *Q )
|
|
Me@0
|
43 { int oldSize, newSize;
|
|
Me@0
|
44 void **oldStartOfData;
|
|
Me@0
|
45
|
|
Me@0
|
46 oldSize = Q->endOfData - Q->startOfData;
|
|
Me@0
|
47 newSize = 2 * oldSize;
|
|
Me@6
|
48 oldStartOfData = Q->startOfData;
|
|
Me@0
|
49 Q->startOfData = malloc( newSize * sizeof(void *) );
|
|
Me@0
|
50 memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *));
|
|
Me@0
|
51 free(oldStartOfData);
|
|
Me@0
|
52
|
|
Me@0
|
53 Q->extractPos = &(Q->startOfData[0]); //side by side == empty
|
|
Me@0
|
54 Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be
|
|
Me@0
|
55 Q->endOfData = &(Q->startOfData[newSize - 1]);
|
|
Me@0
|
56 }
|
|
Me@0
|
57
|
|
Me@0
|
58
|
|
Me@0
|
59 /*Returns NULL when queue is empty
|
|
Me@0
|
60 */
|
|
Me@0
|
61 void* readPrivQ( PrivQueueStruc* Q )
|
|
Me@0
|
62 { void *out = 0;
|
|
Me@2
|
63 void **startOfData = Q->startOfData;
|
|
Me@2
|
64 void **endOfData = Q->endOfData;
|
|
Me@0
|
65
|
|
Me@2
|
66 void **insertPos = Q->insertPos;
|
|
Me@2
|
67 void **extractPos = Q->extractPos;
|
|
Me@0
|
68
|
|
Me@6
|
69 //if not empty -- (extract is just below insert when empty)
|
|
Me@0
|
70 if( insertPos - extractPos != 1 &&
|
|
Me@0
|
71 !(extractPos == endOfData && insertPos == startOfData))
|
|
Me@0
|
72 { //move before read
|
|
Me@0
|
73 if( extractPos == endOfData ) //write new pos exactly once, correctly
|
|
Me@0
|
74 { Q->extractPos = startOfData; //can't overrun then fix it 'cause
|
|
Me@0
|
75 } // other thread might read bad pos
|
|
Me@0
|
76 else
|
|
Me@0
|
77 { Q->extractPos++;
|
|
Me@0
|
78 }
|
|
Me@0
|
79 out = *(Q->extractPos);
|
|
Me@0
|
80 return out;
|
|
Me@0
|
81 }
|
|
Me@0
|
82 //Q is empty
|
|
Me@0
|
83 return NULL;
|
|
Me@0
|
84 }
|
|
Me@0
|
85
|
|
Me@2
|
86
|
|
Me@2
|
87 /*Expands the queue size automatically when it's full
|
|
Me@2
|
88 */
|
|
Me@2
|
89 void
|
|
Me@6
|
90 writePrivQ( void * in, PrivQueueStruc* Q )
|
|
Me@2
|
91 {
|
|
Me@2
|
92 void **startOfData = Q->startOfData;
|
|
Me@2
|
93 void **endOfData = Q->endOfData;
|
|
Me@2
|
94
|
|
Me@2
|
95 void **insertPos = Q->insertPos;
|
|
Me@2
|
96 void **extractPos = Q->extractPos;
|
|
Me@2
|
97
|
|
Me@2
|
98 tryAgain:
|
|
Me@6
|
99 //Full? (insert is just below extract when full)
|
|
Me@2
|
100 if( extractPos - insertPos != 1 &&
|
|
Me@2
|
101 !(insertPos == endOfData && extractPos == startOfData))
|
|
Me@2
|
102 { *(Q->insertPos) = in; //insert before move
|
|
Me@2
|
103 if( insertPos == endOfData ) //write new pos exactly once, correctly
|
|
Me@2
|
104 { Q->insertPos = startOfData;
|
|
Me@2
|
105 }
|
|
Me@2
|
106 else
|
|
Me@2
|
107 { Q->insertPos++;
|
|
Me@2
|
108 }
|
|
Me@2
|
109 return;
|
|
Me@2
|
110 }
|
|
Me@2
|
111 //Q is full
|
|
Me@2
|
112 enlargePrivQ( Q );
|
|
Me@2
|
113 goto tryAgain;
|
|
Me@2
|
114 }
|
|
Me@2
|
115
|
|
Me@2
|
116
|
|
Me@0
|
117 /*Returns false when the queue was full.
|
|
Me@0
|
118 * have option of calling make_larger_PrivQ to make more room, then try again
|
|
Me@0
|
119 */
|
|
Me@6
|
120 int writeIfSpacePrivQ( void * in, PrivQueueStruc* Q )
|
|
Me@0
|
121 {
|
|
Me@2
|
122 void **startOfData = Q->startOfData;
|
|
Me@2
|
123 void **endOfData = Q->endOfData;
|
|
Me@2
|
124
|
|
Me@2
|
125 void **insertPos = Q->insertPos;
|
|
Me@2
|
126 void **extractPos = Q->extractPos;
|
|
Me@0
|
127
|
|
Me@0
|
128 if( extractPos - insertPos != 1 &&
|
|
Me@0
|
129 !(insertPos == endOfData && extractPos == startOfData))
|
|
Me@2
|
130 { *(Q->insertPos) = in; //insert before move
|
|
Me@0
|
131 if( insertPos == endOfData ) //write new pos exactly once, correctly
|
|
Me@0
|
132 { Q->insertPos = startOfData;
|
|
Me@0
|
133 }
|
|
Me@0
|
134 else
|
|
Me@0
|
135 { Q->insertPos++;
|
|
Me@0
|
136 }
|
|
Me@0
|
137 return TRUE;
|
|
Me@0
|
138 }
|
|
Me@0
|
139 //Q is full
|
|
Me@0
|
140 return FALSE;
|
|
Me@0
|
141 }
|