annotate PrivateQueue.c @ 24:677afc259a58

fix branch to compile with new folder structure
author Merten Sach <msach@mailbox.tu-berlin.de>
date Mon, 13 Feb 2012 19:32:12 +0100
parents 7c9e00ff1bf4
children
rev   line source
msach@24 1 /*
msach@24 2 * Copyright 2009 OpenSourceStewardshipFoundation.org
msach@24 3 * Licensed under GNU General Public License version 2
msach@24 4 *
msach@24 5 * Author: seanhalle@yahoo.com
msach@24 6 */
msach@24 7
msach@24 8
msach@24 9 #include <stdio.h>
msach@24 10 #include <string.h>
msach@24 11 #include <errno.h>
msach@24 12 #include <stdlib.h>
msach@24 13
msach@24 14 #include "PrivateQueue.h"
msach@24 15 #include "VMS_Implementations/VMS_impl/vmalloc.h"
msach@24 16
msach@24 17
msach@24 18
msach@24 19 //===========================================================================
msach@24 20
msach@24 21 /*This kind of queue is private to a single core at a time -- has no
msach@24 22 * synchronizations
msach@24 23 */
msach@24 24
msach@24 25 PrivQueueStruc* makePrivQ()
msach@24 26 {
msach@24 27 PrivQueueStruc *retQ;
msach@24 28 retQ = VMS_int__malloc( sizeof( PrivQueueStruc ) );
msach@24 29 retQ->startOfData = (void*)VMS_int__malloc( 1024 * sizeof(void *) );
msach@24 30 memset( retQ->startOfData, 0, 1024 );
msach@24 31
msach@24 32 retQ->extractPos = &(retQ->startOfData[0]); //side by side == empty
msach@24 33 retQ->insertPos = &(retQ->startOfData[1]); // so start pos's have to be
msach@24 34 retQ->endOfData = &(retQ->startOfData[1023]);
msach@24 35
msach@24 36 return retQ;
msach@24 37 }
msach@24 38
msach@24 39
msach@24 40 void
msach@24 41 enlargePrivQ( PrivQueueStruc *Q )
msach@24 42 { size_t oldSize, newSize;
msach@24 43 void **oldStartOfData;
msach@24 44
msach@24 45 oldSize = Q->endOfData - Q->startOfData + 1;
msach@24 46 newSize = 2 * oldSize;
msach@24 47 oldStartOfData = Q->startOfData;
msach@24 48 Q->startOfData = VMS_int__malloc( newSize * sizeof(void*));
msach@24 49 //copy second half
msach@24 50 size_t secondHalfSize = Q->endOfData - Q->extractPos + 1;
msach@24 51 memcpy(Q->startOfData,Q->extractPos, secondHalfSize * sizeof(void*));
msach@24 52 //copy first half
msach@24 53 memcpy(Q->startOfData + secondHalfSize, oldStartOfData,
msach@24 54 (oldSize-secondHalfSize) * sizeof(void*));
msach@24 55 VMS_int__free(oldStartOfData);
msach@24 56
msach@24 57 Q->extractPos = Q->startOfData;
msach@24 58 Q->insertPos = Q->startOfData + oldSize - 1;
msach@24 59 Q->endOfData = &(Q->startOfData[newSize - 1]);
msach@24 60 }
msach@24 61
msach@24 62
msach@24 63 /*Returns NULL when queue is empty
msach@24 64 */
msach@24 65 void* readPrivQ( PrivQueueStruc* Q )
msach@24 66 { void *out = 0;
msach@24 67 void **startOfData = Q->startOfData;
msach@24 68 void **endOfData = Q->endOfData;
msach@24 69
msach@24 70 void **insertPos = Q->insertPos;
msach@24 71 void **extractPos = Q->extractPos;
msach@24 72
msach@24 73 //if not empty -- (extract is just below insert when empty)
msach@24 74 if( insertPos - extractPos != 1 &&
msach@24 75 !(extractPos == endOfData && insertPos == startOfData))
msach@24 76 { //move before read
msach@24 77 if( extractPos == endOfData ) //write new pos exactly once, correctly
msach@24 78 { Q->extractPos = startOfData; //can't overrun then fix it 'cause
msach@24 79 } // other thread might read bad pos
msach@24 80 else
msach@24 81 { Q->extractPos++;
msach@24 82 }
msach@24 83 out = *(Q->extractPos);
msach@24 84 return out;
msach@24 85 }
msach@24 86 //Q is empty
msach@24 87 return NULL;
msach@24 88 }
msach@24 89
msach@24 90 int32
msach@24 91 numInPrivQ( PrivQueueStruc *Q )
msach@24 92 { int32 size, numIn;
msach@24 93
msach@24 94 if( Q->insertPos < Q->extractPos )
msach@24 95 { //insert has wrapped around so numIn is:
msach@24 96 // insertPos + size - extractPos -- Consider, is empty when
msach@24 97 // extractPos = endOfData and insert = start -- correctly get zero
msach@24 98 size = Q->endOfData - Q->startOfData;
msach@24 99 numIn = Q->insertPos + size - Q->extractPos;
msach@24 100 }
msach@24 101 else
msach@24 102 {
msach@24 103 numIn = Q->insertPos - Q->extractPos -1;//-1 bec empty @ side-by-side
msach@24 104 }
msach@24 105 return numIn;
msach@24 106 }
msach@24 107
msach@24 108
msach@24 109 /*Expands the queue size automatically when it's full
msach@24 110 */
msach@24 111 void
msach@24 112 writePrivQ( void * in, PrivQueueStruc* Q )
msach@24 113 {
msach@24 114 while(1){
msach@24 115 void **startOfData = Q->startOfData;
msach@24 116 void **endOfData = Q->endOfData;
msach@24 117
msach@24 118 void **insertPos = Q->insertPos;
msach@24 119 void **extractPos = Q->extractPos;
msach@24 120
msach@24 121 //Full? (insert is just below extract when full)
msach@24 122 if( extractPos - insertPos != 1 &&
msach@24 123 !(insertPos == endOfData && extractPos == startOfData))
msach@24 124 { *(Q->insertPos) = in; //insert before move
msach@24 125 if( insertPos == endOfData ) //write new pos exactly once, correctly
msach@24 126 { Q->insertPos = startOfData;
msach@24 127 }
msach@24 128 else
msach@24 129 { Q->insertPos++;
msach@24 130 }
msach@24 131 return;
msach@24 132 }
msach@24 133 //Q is full
msach@24 134 enlargePrivQ( Q );
msach@24 135 }
msach@24 136 }
msach@24 137
msach@24 138
msach@24 139 /*Returns false when the queue was full.
msach@24 140 * have option of calling make_larger_PrivQ to make more room, then try again
msach@24 141 */
msach@24 142 int writeIfSpacePrivQ( void * in, PrivQueueStruc* Q )
msach@24 143 {
msach@24 144 void **startOfData = Q->startOfData;
msach@24 145 void **endOfData = Q->endOfData;
msach@24 146
msach@24 147 void **insertPos = Q->insertPos;
msach@24 148 void **extractPos = Q->extractPos;
msach@24 149
msach@24 150 if( extractPos - insertPos != 1 &&
msach@24 151 !(insertPos == endOfData && extractPos == startOfData))
msach@24 152 { *(Q->insertPos) = in; //insert before move
msach@24 153 if( insertPos == endOfData ) //write new pos exactly once, correctly
msach@24 154 { Q->insertPos = startOfData;
msach@24 155 }
msach@24 156 else
msach@24 157 { Q->insertPos++;
msach@24 158 }
msach@24 159 return TRUE;
msach@24 160 }
msach@24 161 //Q is full
msach@24 162 return FALSE;
msach@24 163 }
msach@24 164
msach@24 165 /*Treats queue as a stack -- no matter contents, if read done right after
msach@24 166 * a push, then the pushed item is what comes out.
msach@24 167 * Expands the queue size automatically when it's full.
msach@24 168 */
msach@24 169 void
msach@24 170 pushPrivQ( void * in, PrivQueueStruc* Q )
msach@24 171 {
msach@24 172 while(1){
msach@24 173 void **startOfData = Q->startOfData;
msach@24 174 void **endOfData = Q->endOfData;
msach@24 175
msach@24 176 void **insertPos = Q->insertPos;
msach@24 177 void **extractPos = Q->extractPos;
msach@24 178
msach@24 179 //Full? (insert is just below extract when full)
msach@24 180 if( extractPos - insertPos != 1 &&
msach@24 181 !(insertPos == endOfData && extractPos == startOfData))
msach@24 182 { //insert -- but go backwards, inserting at read position then
msach@24 183 // move read pos backwards
msach@24 184 *(Q->extractPos) = in;
msach@24 185 if( extractPos == startOfData ) //write new pos exactly once, correctly
msach@24 186 { Q->extractPos = endOfData; //can't overrun then fix it 'cause
msach@24 187 } // other thread might read bad pos
msach@24 188 else
msach@24 189 { Q->extractPos--;
msach@24 190 }
msach@24 191 return;
msach@24 192 }
msach@24 193 //Q is full
msach@24 194 enlargePrivQ( Q );
msach@24 195 }
msach@24 196 }
msach@24 197
msach@24 198 void
msach@24 199 freePrivQ( PrivQueueStruc *Q )
msach@24 200 {
msach@24 201 VMS_int__free( Q->startOfData );
msach@24 202 VMS_int__free( Q );
Me@9 203 }