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

#ifndef _SSR_H
#define	_SSR_H

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


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

//===========================================================================
/*This header defines everything specific to the SSR semantic plug-in
 */
typedef struct _SSRSemReq   SSRSemReq;
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
 */

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

/*WARNING: assembly hard-codes position of endInstrAddr as first field
 */
typedef struct
 {
   void           *endInstrAddr;
   int32           hasBeenStarted;
   int32           hasFinished;
   PrivQueueStruc *waitQ;
 }
SSRSingleton;

enum SSRReqType
 {
   send_type = 1,
   send_from_to,
   receive_any,    //order and grouping matter -- send before receive
   receive_type,   // and receive_any first of the receives -- Handlers
   receive_from_to,// rely upon this ordering of enum
   transfer_to,
   transfer_out,
   malloc_req,
   free_req,
   singleton_fn_start,
   singleton_fn_end,
   singleton_data_start,
   singleton_data_end,
   atomic,
   trans_start,
   trans_end
 };

struct _SSRSemReq
 { enum SSRReqType    reqType;
   VirtProcr         *sendPr;
   VirtProcr         *receivePr;
   int32              msgType;
   void              *msg;
   SSRSemReq         *nextReqInHashEntry;

   void              *initData;
   VirtProcrFnPtr     fnPtr;
   int32              coreToScheduleOnto;

   int32              sizeToMalloc;
   void              *ptrToFree;

   int32              singletonID;
   SSRSingleton     **singletonPtrAddr;

   PtrToAtomicFn      fnToExecInMaster;
   void              *dataForFn;

   int32              transID;
 }
/* SSRSemReq */;


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

                       //fix limit on num with dynArray
   SSRSingleton     fnSingletons[NUM_STRUCS_IN_SEM_ENV];
   SSRTrans         transactionStrucs[NUM_STRUCS_IN_SEM_ENV];
 }
SSRSemEnv;


typedef struct _TransListElem TransListElem;
struct _TransListElem
 {
   int32          transID;
   TransListElem *nextTrans;
 };
//TransListElem
 
typedef struct
 {
   int32          highestTransEntered;
   TransListElem *lastTransEntered;
 }
SSRSemData;
 
//===========================================================================

void
SSR__create_seed_procr_and_do_work( VirtProcrFnPtr fn, void *initData );

int32
SSR__giveMinWorkUnitCycles( float32 percentOverhead );

void
SSR__start_primitive();

int32
SSR__end_primitive_and_give_cycles();

int32
SSR__giveIdealNumWorkUnits();

int32
SSR__give_number_of_cores_to_schedule_onto();

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

void
SSR__init();

void
SSR__cleanup_after_shutdown();

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

  VirtProcr *
SSR__create_procr_with( VirtProcrFnPtr fnPtr, void *initData,
                          VirtProcr *creatingPr );

  VirtProcr *
SSR__create_procr_with_affinity( VirtProcrFnPtr fnPtr,    void *initData,
                            VirtProcr *creatingPr, int32 coreToScheduleOnto);

void
SSR__dissipate_procr( VirtProcr *procrToDissipate );

//=======================
void *
SSR__malloc_to( int numBytes, VirtProcr *ownerPr );

void
SSR__free( void *ptrToFree, VirtProcr *owningPr );

void
SSR__transfer_ownership_of_from_to( void *data, VirtProcr *oldOwnerPr,
                                                    VirtProcr *newOwnerPr );
                                                    
void
SSR__add_ownership_by_to( VirtProcr *newOwnerPr, void *data );

void
SSR__remove_ownership_by_from( VirtProcr *loserPr, void *dataLosing );

void
SSR__transfer_ownership_to_outside( void *dataToTransferOwnershipOf );



//=======================
void
SSR__send_of_type_to( VirtProcr *sendPr, void *msg, const int type,
                        VirtProcr *receivePr);

void
SSR__send_from_to( void *msg, VirtProcr *sendPr, VirtProcr *receivePr);

void *
SSR__receive_type_to( const int type, VirtProcr *receivePr );

void *
SSR__receive_from_to( VirtProcr *sendPr, VirtProcr *receivePr );


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

void
SSR__end_fn_singleton( int32 singletonID, VirtProcr *animPr );

void
SSR__start_data_singleton( SSRSingleton **singeltonAddr, VirtProcr *animPr );

void
SSR__end_data_singleton( SSRSingleton **singletonAddr, VirtProcr *animPr );

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

void
SSR__start_transaction( int32 transactionID, VirtProcr *animPr );

void
SSR__end_transaction( int32 transactionID, VirtProcr *animPr );


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

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

VirtProcr*
SSR__create_procr_helper( VirtProcrFnPtr fnPtr, void *initData,
                          SSRSemEnv *semEnv,    int32 coreToScheduleOnto );

#endif	/* _SSR_H */

