annotate PrivateQueue.c @ 14:447e97a52426

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