/*
 *  Copyright 2009 OpenSourceStewardshipFoundation.org
 *  Licensed under GNU General Public License version 2
 *
 * Author: seanhalle@yahoo.com
 * 
 */
#ifndef _ProcrContext_H
#define	_ProcrContext_H
#define _GNU_SOURCE

typedef struct _VirtProcr VirtProcr;
typedef struct _VMSReqst  VMSReqst;
typedef void  (*VirtProcrFnPtr)  ( void *, VirtProcr * ); //initData, animPr


#include "VMS_primitive_data_types.h"
#include "scheduling.h"

/*WARNING: re-arranging this data structure could cause VP switching
 *         assembly code to fail -- hard-codes offsets of fields
 */
struct _VirtProcr
 { int         procrID;  //for debugging -- count up each time create
   int         coreAnimatedBy;
   void       *startOfStack;
   void       *stackPtr;
   void       *framePtr;
   void       *nextInstrPt;
   
   void       *coreLoopStartPt;  //allows proto-runtime to be linked later
   void       *coreLoopFramePtr; //restore before jmp back to core loop
   void       *coreLoopStackPtr; //restore before jmp back to core loop

   void       *initialData;
   
   SchedSlot  *schedSlot;
   VMSReqst   *requests;

   void       *semanticData;
   void       *dataRetFromReq; //values returned from plugin to VP go here

      //=========== MEASUREMENT STUFF ==========
   #ifdef MEAS__TIME_STAMP_SUSP
   unsigned int preSuspTSCLow;
   unsigned int postSuspTSCLow;
   #endif
   #ifdef MEAS__TIME_MASTER /* in VirtProcr because multiple masterVPs*/
   unsigned int startMasterTSCLow;USE_GNU
   unsigned int endMasterTSCLow;
   #endif
      //========================================
   
   float64      createPtInSecs;  //have space but don't use on some configs
 };
//VirtProcr

void saveCoreLoopReturnAddr(void **returnAddress);

void switchToVP(VirtProcr *nextProcr);

void switchToCoreLoop(VirtProcr *nextProcr);

void masterSwitchToCoreLoop(VirtProcr *nextProcr);

void startVirtProcrFn();

void asmTerminateCoreLoop(VirtProcr *currPr);

void asmTerminateCoreLoopSeq(VirtProcr *currPr);

#define flushRegisters() \
        asm volatile ("":::"%rbx", "%r12", "%r13","%r14","%r15");

inline VirtProcr *
create_procr_helper( VirtProcr *newPr,       VirtProcrFnPtr  fnPtr,
                     void      *initialData, void           *stackLocs );

#endif	/* _ProcrContext_H */

