view PrivateQueue.c @ 22:59781a4c9cf1

updated VMS__malloc to VMS_int__malloc
author Me@portablequad
date Sun, 12 Feb 2012 01:43:39 -0800
parents b5ae7fbb1f01
children bd38feb38c80
line source
1 /*
2 * Copyright 2009 OpenSourceStewardshipFoundation.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 *) VMS_int__malloc( sizeof( PrivQueueStruc ) );
31 retQ->startOfData = VMS_int__malloc( 1024 * sizeof(void *) );
32 memset( retQ->startOfData, 0, 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 }
41 void
42 enlargePrivQ( PrivQueueStruc *Q )
43 { int oldSize, newSize;
44 void **oldStartOfData;
46 oldSize = Q->endOfData - Q->startOfData;
47 newSize = 2 * oldSize;
48 oldStartOfData = Q->startOfData;
49 Q->startOfData = VMS_int__malloc( newSize * sizeof(void *) );
50 memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *));
51 VMS_int__free(oldStartOfData);
53 Q->extractPos = &(Q->startOfData[0]); //side by side == empty
54 Q->insertPos = &(Q->startOfData[1]); // so start pos's have to be
55 Q->endOfData = &(Q->startOfData[newSize - 1]);
56 }
59 /*Returns NULL when queue is empty
60 */
61 void* readPrivQ( PrivQueueStruc* Q )
62 { void *out = 0;
63 void **startOfData = Q->startOfData;
64 void **endOfData = Q->endOfData;
66 void **insertPos = Q->insertPos;
67 void **extractPos = Q->extractPos;
69 //if not empty -- (extract is just below insert when empty)
70 if( insertPos - extractPos != 1 &&
71 !(extractPos == endOfData && insertPos == startOfData))
72 { //move before read
73 if( extractPos == endOfData ) //write new pos exactly once, correctly
74 { Q->extractPos = startOfData; //can't overrun then fix it 'cause
75 } // other thread might read bad pos
76 else
77 { Q->extractPos++;
78 }
79 out = *(Q->extractPos);
80 return out;
81 }
82 //Q is empty
83 return NULL;
84 }
87 /*Expands the queue size automatically when it's full
88 */
89 void
90 writePrivQ( void * in, PrivQueueStruc* Q )
91 {
92 void **startOfData = Q->startOfData;
93 void **endOfData = Q->endOfData;
95 void **insertPos = Q->insertPos;
96 void **extractPos = Q->extractPos;
98 tryAgain:
99 //Full? (insert is just below extract when full)
100 if( extractPos - insertPos != 1 &&
101 !(insertPos == endOfData && extractPos == startOfData))
102 { *(Q->insertPos) = in; //insert before move
103 if( insertPos == endOfData ) //write new pos exactly once, correctly
104 { Q->insertPos = startOfData;
105 }
106 else
107 { Q->insertPos++;
108 }
109 return;
110 }
111 //Q is full
112 enlargePrivQ( Q );
113 goto tryAgain;
114 }
117 /*Returns false when the queue was full.
118 * have option of calling make_larger_PrivQ to make more room, then try again
119 */
120 int writeIfSpacePrivQ( void * in, PrivQueueStruc* Q )
121 {
122 void **startOfData = Q->startOfData;
123 void **endOfData = Q->endOfData;
125 void **insertPos = Q->insertPos;
126 void **extractPos = Q->extractPos;
128 if( extractPos - insertPos != 1 &&
129 !(insertPos == endOfData && extractPos == startOfData))
130 { *(Q->insertPos) = in; //insert before move
131 if( insertPos == endOfData ) //write new pos exactly once, correctly
132 { Q->insertPos = startOfData;
133 }
134 else
135 { Q->insertPos++;
136 }
137 return TRUE;
138 }
139 //Q is full
140 return FALSE;
141 }