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

#ifndef _VCilk_H
#define	_VCilk_H

#include "VMS/Queue_impl/PrivateQueue.h"
#include "VMS/Hash_impl/PrivateHash.h"
#include "VMS/VMS.h"



/*This header defines everything specific to the VCilk semantic plug-in
 */

//===========================================================================
#define NUM_STRUCS_IN_SEM_ENV 1000

//===========================================================================
typedef struct _VCilkSemReq   VCilkSemReq;
typedef void  (*PtrToAtomicFn )   ( void * ); //executed atomically in master

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


/*Semantic layer-specific data sent inside a request from lib called in app
 * to request handler called in MasterLoop
 */
enum VCilkReqType
 {
   syncReq = 1,
   mallocReq,
   freeReq,
   singleton,
   atomic,
   trans_start,
   trans_end
 };

struct _VCilkSemReq
 { enum VCilkReqType    reqType;
   VirtProcr           *requestingPr;
   
   int32                sizeToMalloc;
   void                *ptrToFree;
   
   VirtProcrFnPtr       fnPtr;
   void                *initData;
   int32                coreToSpawnOnto;

   int32              singletonID;
   void              *endJumpPt;

   PtrToAtomicFn      fnToExecInMaster;
   void              *dataForFn;

   int32              transID;
 }
/* VCilkSemReq */;

typedef struct
 {
   VirtProcr      *VPCurrentlyExecuting;
   PrivQueueStruc *waitingVPQ;
 }
VCilkTrans;

typedef struct
 {
   PrivQueueStruc **readyVPQs;
   HashTable       *commHashTbl;
   int32            numVirtPr;
   int32            nextCoreToGetNewPr;
   int32            primitiveStartTime;

                       //fix limit on num with dynArray
   int32            singletonHasBeenExecutedFlags[NUM_STRUCS_IN_SEM_ENV];
   VCilkTrans       transactionStrucs[NUM_STRUCS_IN_SEM_ENV];
 }
VCilkSemEnv;

typedef struct _TransListElem TransListElem;
struct _TransListElem
 {
   int32          transID;
   TransListElem *nextTrans;
 };
//TransListElem

typedef struct
 {
   int32          syncPending;
   int32          numLiveChildren;
   VirtProcr     *parentPr;
   
   int32          highestTransEntered;
   TransListElem *lastTransEntered;
 }
VCilkSemData;

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

void
VCilk__create_seed_procr_and_do_work( VirtProcrFnPtr fn, void *initData );

int32
VCilk__giveMinWorkUnitCycles( float32 percentOverhead );

void inline
VCilk__start_primitive();

int32 inline
VCilk__end_primitive_and_give_cycles();

int32
VCilk__giveIdealNumWorkUnits();

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

void
VCilk__init();

void
VCilk__cleanup_at_end_of_shutdown();

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

void inline
VCilk__spawn( int32  coreToSpawnOnto, VirtProcrFnPtr  fnPtr,
              void  *initData,        VirtProcr      *creatingPr );

int32
VCilk__give_number_of_cores_to_spawn_onto();

void
VCilk__sync( VirtProcr *animatingPr );

void *
VCilk__malloc( int32 sizeToMalloc, VirtProcr *animPr );

void
VCilk__free( void *ptrToFree, VirtProcr *animPr );

void
VCilk__dissipate_procr( VirtProcr *procrToDissipate );


//======================= Concurrency Stuff ======================
void
VCilk__start_singleton( int32 singletonID, void *endSingletonLabelAddr,
                        VirtProcr *animPr );

void
VCilk__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster,
                                      void *data, VirtProcr *animPr );

void
VCilk__start_transaction( int32 transactionID, VirtProcr *animPr );

void
VCilk__end_transaction( int32 transactionID, VirtProcr *animPr );


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

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


#endif	/* _VCilk_H */

