annotate PrivateQueue.c @ 13:53c614b781ce

Added initializing the queue contents to zero
author Me
date Thu, 04 Nov 2010 17:50:29 -0700
parents 93bf3ffcc1fb
children 1ed562d601d9
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 }