/*
 *  Copyright 2009 OpenSourceResearchInstitute.org
 *  Licensed under GNU General Public License version 2
 *
 * Author: seanhalle@yahoo.com
 */

#ifndef _PRQUEUE_H
#define	_PRQUEUE_H

#include <PR__include/PR__primitive_data_types.h>
#include <pthread.h>

#define TRUE     1
#define FALSE    0

//==================  Private Queue stuff ===================
/* It is the data that is shared so only need one mutex. */
typedef struct
 { void      **insertPos;
   void      **extractPos;
   void      **startOfData;  //data is pointers
   void      **endOfData;    //set when alloc data
 }
PrivQueueStruc;

typedef void  (*DynArrayFnPtr)  ( void * );  //fn has to cast void *

PrivQueueStruc*  makePrivQ ( );
bool32           isEmptyPrivQ ( PrivQueueStruc *Q ); //ret TRUE if empty
void*            peekPrivQ ( PrivQueueStruc *Q ); //ret NULL if empty
void*            readPrivQ ( PrivQueueStruc *Q ); //ret NULL if empty
void             writePrivQ( void *in, PrivQueueStruc *Q );
                    //return false when full
bool32           writeIfSpacePrivQ( void * in, PrivQueueStruc* Q );
int32            numInPrivQ( PrivQueueStruc *Q );
void             pushPrivQ( void * in, PrivQueueStruc* Q );
void             freePrivQ( PrivQueueStruc *Q );


//====================== Parallel Queue Stuff ====================

//========== pThreads based queue ==========
/* It is the data that is shared so only need one mutex. */
typedef
struct
 { pthread_mutex_t  mutex_t;
   pthread_cond_t   cond_w_t;
   pthread_cond_t   cond_r_t;
   int32            count;
   int32            readPos;
   int32            writePos;
   void*            data[1024];  //an array of pointers
   int w_empty;
   int w_full;
 }
PThdQueueStruc;

PThdQueueStruc*     makePThdQ();
void* readPThdQ( PThdQueueStruc *Q );
void writePThdQ( void *in, PThdQueueStruc *Q );


//========== CAS based queue ==========
typedef
struct
 { volatile int32   insertLock;
   volatile int32   extractLock;
   volatile void*  *insertPos;
   volatile void*  *extractPos;
   void*   startOfData[1024];  //data is pointers
   void*  *endOfData;          //set when make queue
 }
CASQueueStruc;

CASQueueStruc*  makeCASQ();
void* readCASQ( CASQueueStruc *Q );
void writeCASQ( void *in, CASQueueStruc *Q );


//========= non-atomic instr based queue ===========
typedef
struct
 { void*  *insertPos;
   void*  *extractPos;
   void*   startOfData[1024];  //data is pointers
   void*  *endOfData;          //set when make queue
 }
SRSWQueueStruc;

SRSWQueueStruc* makeSRSWQ();
void  freeSRSWQ( SRSWQueueStruc* Q );
void* readSRSWQ( SRSWQueueStruc *Q );
void  writeSRSWQ( void *in, SRSWQueueStruc *Q );


//========= non-atomic instr S R M W queue ===========
typedef
struct
 { int32            lastQReadFrom;
   int32            numInternalQs;
   int32            internalQsSz;
   SRSWQueueStruc* *internalQs;
 }
SRMWQueueStruc;

SRMWQueueStruc* makeSRMWQ();
int addWriterToSRMWQ( SRMWQueueStruc *Q );
void* readSRMWQ( SRMWQueueStruc *Q );
void writeSRMWQ( void *in, SRMWQueueStruc *Q, int writerID );


#endif	/* _PRIVATE_QUEUE_H */

