annotate PrivateQueue.c @ 2:f4d50d8a1a38

Full VMS test -- works
author Me
date Wed, 30 Jun 2010 13:10:42 -0700
parents 85af604dee9b
children 174a7c2ca340
rev   line source
Me@0 1 /*
Me@0 2 * Copyright 2009 OpenSourceCodeStewardshipFoundation.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@0 32
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@0 48 Q->startOfData = malloc( newSize * sizeof(void *) );
Me@0 49 memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *));
Me@0 50 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@0 68 //if not empty -- extract 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@2 85
Me@2 86 /*Expands the queue size automatically when it's full
Me@2 87 */
Me@2 88 void
Me@2 89 writeAndEnlargePrivQ( void * in, PrivQueueStruc* Q )
Me@2 90 {
Me@2 91 void **startOfData = Q->startOfData;
Me@2 92 void **endOfData = Q->endOfData;
Me@2 93
Me@2 94 void **insertPos = Q->insertPos;
Me@2 95 void **extractPos = Q->extractPos;
Me@2 96
Me@2 97 tryAgain:
Me@2 98 if( extractPos - insertPos != 1 &&
Me@2 99 !(insertPos == endOfData && extractPos == startOfData))
Me@2 100 { *(Q->insertPos) = in; //insert before move
Me@2 101 if( insertPos == endOfData ) //write new pos exactly once, correctly
Me@2 102 { Q->insertPos = startOfData;
Me@2 103 }
Me@2 104 else
Me@2 105 { Q->insertPos++;
Me@2 106 }
Me@2 107 return;
Me@2 108 }
Me@2 109 //Q is full
Me@2 110 enlargePrivQ( Q );
Me@2 111 goto tryAgain;
Me@2 112 }
Me@2 113
Me@2 114
Me@0 115 /*Returns false when the queue was full.
Me@0 116 * have option of calling make_larger_PrivQ to make more room, then try again
Me@0 117 */
Me@2 118 int writeAndFailPrivQ( void * in, PrivQueueStruc* Q )
Me@0 119 {
Me@2 120 void **startOfData = Q->startOfData;
Me@2 121 void **endOfData = Q->endOfData;
Me@2 122
Me@2 123 void **insertPos = Q->insertPos;
Me@2 124 void **extractPos = Q->extractPos;
Me@0 125
Me@0 126 if( extractPos - insertPos != 1 &&
Me@0 127 !(insertPos == endOfData && extractPos == startOfData))
Me@2 128 { *(Q->insertPos) = in; //insert before move
Me@0 129 if( insertPos == endOfData ) //write new pos exactly once, correctly
Me@0 130 { Q->insertPos = startOfData;
Me@0 131 }
Me@0 132 else
Me@0 133 { Q->insertPos++;
Me@0 134 }
Me@0 135 return TRUE;
Me@0 136 }
Me@0 137 //Q is full
Me@0 138 return FALSE;
Me@0 139 }