diff PrivateQueue.c @ 0:85af604dee9b

initial add
author Me
date Sat, 22 May 2010 19:51:09 -0700
parents
children f4d50d8a1a38
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/PrivateQueue.c	Sat May 22 19:51:09 2010 -0700
     1.3 @@ -0,0 +1,110 @@
     1.4 +/*
     1.5 + *  Copyright 2009 OpenSourceCodeStewardshipFoundation.org
     1.6 + *  Licensed under GNU General Public License version 2
     1.7 + *
     1.8 + * NOTE: this version of SRSW correct as of April 25, 2010
     1.9 + *
    1.10 + * Author: seanhalle@yahoo.com
    1.11 + */
    1.12 +
    1.13 +
    1.14 +#include <stdio.h>
    1.15 +#include <string.h>
    1.16 +#include <errno.h>
    1.17 +#include <stdlib.h>
    1.18 +
    1.19 +#include "PrivateQueue.h"
    1.20 +
    1.21 +
    1.22 +
    1.23 +//===========================================================================
    1.24 +
    1.25 +/*This kind of queue is private to a single core at a time -- has no
    1.26 + * synchronizations 
    1.27 + */
    1.28 +
    1.29 +PrivQueueStruc* makePrivQ()
    1.30 + {
    1.31 +   PrivQueueStruc* retQ;
    1.32 +   retQ = (PrivQueueStruc *) malloc( sizeof( PrivQueueStruc ) );
    1.33 +
    1.34 +   retQ->startOfData = malloc( 1024 * sizeof(void *) );
    1.35 +   
    1.36 +   retQ->extractPos = &(retQ->startOfData[0]); //side by side == empty
    1.37 +   retQ->insertPos  = &(retQ->startOfData[1]); // so start pos's have to be
    1.38 +   retQ->endOfData  = &(retQ->startOfData[1023]);
    1.39 +
    1.40 +   return retQ;
    1.41 + }
    1.42 +
    1.43 +PrivQueueStruc* make_larger_PrivQ( PrivQueueStruc *Q )
    1.44 + { int    oldSize, newSize;
    1.45 +   void **oldStartOfData;
    1.46 +
    1.47 +   oldSize           = Q->endOfData - Q->startOfData;
    1.48 +   newSize           = 2 * oldSize;
    1.49 +   Q->startOfData = malloc( newSize * sizeof(void *) );
    1.50 +   memcpy(Q->startOfData, oldStartOfData, oldSize * sizeof(void *));
    1.51 +   free(oldStartOfData);
    1.52 +   
    1.53 +   Q->extractPos  = &(Q->startOfData[0]); //side by side == empty
    1.54 +   Q->insertPos   = &(Q->startOfData[1]); // so start pos's have to be
    1.55 +   Q->endOfData   = &(Q->startOfData[newSize - 1]);
    1.56 +
    1.57 +   return Q;
    1.58 + }
    1.59 +
    1.60 +
    1.61 +/*Returns NULL when queue is empty
    1.62 + */
    1.63 +void* readPrivQ( PrivQueueStruc* Q )
    1.64 + { void *out    = 0;
    1.65 +   int  startOfData = Q->startOfData;
    1.66 +   int  endOfData   = Q->endOfData;
    1.67 +
    1.68 +   volatile int insertPos  = Q->insertPos;
    1.69 +   volatile int extractPos = Q->extractPos;
    1.70 +
    1.71 +      //if not empty -- extract just below insert when empty
    1.72 +   if( insertPos - extractPos != 1 &&
    1.73 +       !(extractPos == endOfData && insertPos == startOfData))
    1.74 +    {    //move before read
    1.75 +      if( extractPos == endOfData ) //write new pos exactly once, correctly
    1.76 +       { Q->extractPos = startOfData; //can't overrun then fix it 'cause
    1.77 +       }                              // other thread might read bad pos
    1.78 +      else
    1.79 +       { Q->extractPos++;
    1.80 +       }
    1.81 +      out = *(Q->extractPos);
    1.82 +      return out;
    1.83 +    }
    1.84 +      //Q is empty
    1.85 +   return NULL;
    1.86 + }
    1.87 +
    1.88 +/*Returns false when the queue was full.
    1.89 + * have option of calling make_larger_PrivQ to make more room, then try again
    1.90 + */
    1.91 +bool8 writePrivQ( void * in, PrivQueueStruc* Q )
    1.92 + {
    1.93 +   int  startOfData = Q->startOfData;
    1.94 +   int  endOfData   = Q->endOfData;
    1.95 +   
    1.96 +   volatile int insertPos  = Q->insertPos;
    1.97 +   volatile int extractPos = Q->extractPos;
    1.98 +
    1.99 +   if( extractPos - insertPos != 1 &&
   1.100 +       !(insertPos == endOfData && extractPos == startOfData))
   1.101 +    { *(insertPos) = in;   //insert before move
   1.102 +      if( insertPos == endOfData ) //write new pos exactly once, correctly
   1.103 +       { Q->insertPos = startOfData;
   1.104 +       }
   1.105 +      else
   1.106 +       { Q->insertPos++;
   1.107 +       }
   1.108 +      return TRUE;
   1.109 +    }
   1.110 +      //Q is full
   1.111 +   return FALSE;
   1.112 + }
   1.113 +