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

#ifndef _VMS_H
#define	_VMS_H

#include "VMS_primitive_data_types.h"
#include "Queue_impl/BlockingQueue.h"

//This value is the number of hardware threads in the shared memory
// machine -- make double that number scheduling slots, plus extra for master
#define NUM_WORKERS      4
#define NUM_SCHED_SLOTS  9

#define SUCCESS 0

#define thdAttrs NULL

typedef struct _WorkUnit   WorkUnit;
typedef struct _VirtProcr  VirtProcr;
typedef struct _SlaveReqst SlaveReqst;
typedef struct _SchedSlot  SchedSlot;

typedef bool8 (*SlaveScheduler)  ( SchedSlot *, void * );
typedef void  (*RequestHandler)  ( SlaveReqst * );
typedef void  (*VirtProcrFnPtr)  ( void *, VirtProcr * );
typedef void  VirtProcrFn( void *, VirtProcr * );

typedef struct
 {
   QueueStruc     *workQ;
   unsigned int    id;
 }
ThdParams;

struct _SchedSlot
 {
   int         workIsDone;
   int         needsProcrAssigned;
   VirtProcr  *procrAssignedToSlot;
 };


struct _VirtProcr
 {
   void       *stackPtr;
   void       *framePtr;
   void       *nextInstrPt;
   void       *coreLoopStartPt;  //allows proto-runtime to be linked later

   void       *initialData;

   SchedSlot  *schedSlot;
   SlaveReqst *requests;

   void       *semanticData;
 };


//When optimize make a separate flat array in here for each flag in SchedSlot
//So that polling done flags is fast..  not sure even worth it, though..
typedef struct
 {
   SlaveScheduler   slaveScheduler;
   RequestHandler   requestHandler;
   
   SchedSlot **schedSlots;
   SchedSlot **filledSlots;
   int         numFilled;
   
   int         stillRunning;
   
   VirtProcr  *masterVirtPr;
   void       *semanticEnv;
   void       *OSEventStruc;    //for future, when add I/O to BLIS
 }
MasterEnv;



struct _SlaveReqst
 {
   VirtProcr   *slaveFrom;
   int          reqType;   //for future when have I/O and OS services
   void        *semReqData;

   SlaveReqst  *nextRequest;
 };



void * coreLoop( void *paramsIn );  //standard PThreads fn prototype


//=====================  Global Vars ===================


pthread_t      coreLoopThds[ NUM_WORKERS ];  // std struc, holds thread info
ThdParams      thdParams[ NUM_WORKERS ];

volatile MasterEnv     *_VMSMasterEnv;

   //workQ is global, static, and volatile so that core loop has its location
   // hard coded, and reloads every time through the loop -- that way don't
   // need to save any regs used by core loop (will see if this really works)
volatile QueueStruc    *_VMSWorkQ;


#endif	/* _VMS_H */

