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

#ifndef _VPThread_H
#define	_VPThread_H

#include "VMS/VMS.h"
#include "VMS/Queue_impl/PrivateQueue.h"
#include "VMS/DynArray/DynArray.h"


//===========================================================================
#define INIT_NUM_MUTEX 10000
#define INIT_NUM_COND  10000
//===========================================================================

/*This header defines everything specific to the VPThread semantic plug-in
 */
typedef struct _VPThreadSemReq   VPThreadSemReq;


/*Semantic layer-specific data sent inside a request from lib called in app
 * to request handler called in MasterLoop
 */
enum VPThreadReqType
 {
   make_mutex = 1,
   mutex_lock,
   mutex_unlock,
   make_cond,
   cond_wait,
   cond_signal,
   make_procr
 };

struct _VPThreadSemReq
 { enum VPThreadReqType reqType;
   VirtProcr           *requestingPr;
   int32                mutexIdx;
   int32                condIdx;
   void                *initData;
   VirtProcrFnPtr       fnPtr;
 }
/* VPThreadSemReq */;

typedef struct
 {
      //Standard stuff will be in most every semantic env
   PrivQueueStruc **readyVPQs;
   int32            numVirtPr;
   int32            nextCoreToGetNewPr;

      //Specific to this semantic layer
   int32            currMutexIdx;
   DynArray32      *mutexDynArray;
   
   int32            currCondIdx;
   DynArray32      *condDynArray;

   void            *applicationGlobals;
 }
VPThreadSemEnv;


typedef struct
 {
   int32           mutexIdx;
   VirtProcr      *holderOfLock;
   PrivQueueStruc *waitingQueue;
 }
VPTMutex;


typedef struct
 {
   int32           condIdx;
   PrivQueueStruc *waitingQueue;
   VPTMutex       *partnerMutex;
 }
VPTCond;


//===========================================================================

void
VPThread__create_seed_procr_and_do_work( VirtProcrFnPtr fn, void *initData );

//=======================

inline VirtProcr *
VPThread__create_thread( VirtProcrFnPtr fnPtr, void *initData,
                          VirtProcr *creatingPr );

void
VPThread__dissipate_thread( VirtProcr *procrToDissipate );

//=======================
void
VPThread__set_globals_to( void *globals );

void *
VPThread__give_globals();

//=======================
int32
VPThread__make_mutex( VirtProcr *animPr );

void
VPThread__mutex_lock( int32 mutexIdx, VirtProcr *acquiringPr );
                                                    
void
VPThread__mutex_unlock( int32 mutexIdx, VirtProcr *releasingPr );


//=======================
int32
VPThread__make_cond( int32 ownedMutexIdx, VirtProcr *animPr);

void
VPThread__cond_wait( int32 condIdx, VirtProcr *waitingPr);

void *
VPThread__cond_signal( int32 condIdx, VirtProcr *signallingPr );




//=========================  Internal use only  =============================
void
VPThread__Request_Handler( VirtProcr *requestingPr, void *_semEnv );

VirtProcr *
VPThread__schedule_virt_procr( void *_semEnv, int coreNum );

//=======================
void
VPThread__free_semantic_request( VPThreadSemReq *semReq );

//=======================

void
VPThread__init();

void
VPThread__cleanup_after_shutdown();

#endif	/* _VPThread_H */

