diff PR.h @ 260:999f2966a3e5

new branch -- Dev_ML -- for making VMS take langlets whose constructs can be mixed
author Sean Halle <seanhalle@yahoo.com>
date Wed, 19 Sep 2012 23:12:44 -0700
parents
children dafae55597ce
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/PR.h	Wed Sep 19 23:12:44 2012 -0700
     1.3 @@ -0,0 +1,442 @@
     1.4 +/*
     1.5 + *  Copyright 2009 OpenSourceStewardshipFoundation.org
     1.6 + *  Licensed under GNU General Public License version 2
     1.7 + *
     1.8 + * Author: seanhalle@yahoo.com
     1.9 + * 
    1.10 + */
    1.11 +
    1.12 +#ifndef _PR_H
    1.13 +#define	_PR_H
    1.14 +#define _GNU_SOURCE
    1.15 +
    1.16 +#include "DynArray/DynArray.h"
    1.17 +#include "Hash_impl/PrivateHash.h"
    1.18 +#include "Histogram/Histogram.h"
    1.19 +#include "Queue_impl/PrivateQueue.h"
    1.20 +
    1.21 +#include "PR_primitive_data_types.h"
    1.22 +#include "Services_Offered_by_PR/Memory_Handling/vmalloc.h"
    1.23 +
    1.24 +#include <pthread.h>
    1.25 +#include <sys/time.h>
    1.26 +
    1.27 +//=================  Defines: included from separate files  =================
    1.28 +//
    1.29 +// Note: ALL defines are in other files, none are in here
    1.30 +//
    1.31 +#include "Defines/PR_defs.h"
    1.32 +
    1.33 +
    1.34 +//================================ Typedefs =================================
    1.35 +//
    1.36 +typedef unsigned long long    TSCount;
    1.37 +
    1.38 +typedef struct _AnimSlot     AnimSlot;
    1.39 +typedef struct _PRReqst      PRReqst;
    1.40 +typedef struct _SlaveVP       SlaveVP;
    1.41 +typedef struct _MasterVP      MasterVP;
    1.42 +typedef struct _IntervalProbe IntervalProbe;
    1.43 +
    1.44 +
    1.45 +typedef SlaveVP *(*SlaveAssigner)  ( void *, AnimSlot*); //semEnv, slot for HW info
    1.46 +typedef void     (*RequestHandler) ( SlaveVP *, void * ); //prWReqst, semEnv
    1.47 +typedef void     (*TopLevelFnPtr)  ( void *, SlaveVP * ); //initData, animSlv
    1.48 +typedef void       TopLevelFn      ( void *, SlaveVP * ); //initData, animSlv
    1.49 +typedef void     (*ResumeSlvFnPtr) ( SlaveVP *, void * );
    1.50 +      //=========== MEASUREMENT STUFF ==========
    1.51 +        MEAS__Insert_Counter_Handler
    1.52 +      //========================================
    1.53 +
    1.54 +//============================ HW Dependent Fns ================================
    1.55 +
    1.56 +#include "HW_Dependent_Primitives/PR__HW_measurement.h"
    1.57 +#include "HW_Dependent_Primitives/PR__primitives.h"
    1.58 +
    1.59 +
    1.60 +//============= Request Related ===========
    1.61 +//
    1.62 +
    1.63 +enum PRReqstType   //avoid starting enums at 0, for debug reasons
    1.64 + {
    1.65 +   semantic = 1,
    1.66 +   createReq,
    1.67 +   dissipate,
    1.68 +   PRSemantic      //goes with PRSemReqst below
    1.69 + };
    1.70 +
    1.71 +struct _PRReqst
    1.72 + {
    1.73 +   enum PRReqstType  reqType;//used for dissipate and in future for IO requests
    1.74 +   void              *semReqData;
    1.75 +
    1.76 +   PRReqst *nextReqst;
    1.77 + };
    1.78 +//PRReqst
    1.79 +
    1.80 +enum PRSemReqstType   //These are equivalent to semantic requests, but for
    1.81 + {                     // PR's services available directly to app, like OS
    1.82 +   make_probe = 1,    // and probe services -- like a PR-wide built-in lang
    1.83 +   throw_excp,
    1.84 +   openFile,
    1.85 +   otherIO
    1.86 + };
    1.87 +
    1.88 +typedef struct
    1.89 + { enum PRSemReqstType reqType;
    1.90 +   SlaveVP             *requestingSlv;
    1.91 +   char                *nameStr;  //for create probe
    1.92 +   char                *msgStr;   //for exception
    1.93 +   void                *exceptionData;
    1.94 + }
    1.95 + PRSemReq;
    1.96 +
    1.97 +
    1.98 +//====================  Core data structures  ===================
    1.99 +
   1.100 +typedef struct
   1.101 + {
   1.102 +   //for future expansion
   1.103 + }
   1.104 +SlotPerfInfo;
   1.105 +
   1.106 +struct _AnimSlot
   1.107 + {
   1.108 +   int           workIsDone;
   1.109 +   int           needsSlaveAssigned;
   1.110 +   SlaveVP      *slaveAssignedToSlot;
   1.111 +   
   1.112 +   int           slotIdx;  //needed by Holistic Model's data gathering
   1.113 +   int           coreSlotIsOn;
   1.114 +   SlotPerfInfo *perfInfo; //used by assigner to pick best slave for core
   1.115 + };
   1.116 +//AnimSlot
   1.117 +
   1.118 +enum VPtype 
   1.119 + { TaskSlotSlv = 1,//Slave tied to an anim slot, only animates tasks
   1.120 +   TaskExtraSlv,   //When a suspended task ends, the slave becomes this
   1.121 +   PersistentSlv,  //the VP is explicitly seen in the app code, or task suspends
   1.122 +   Slave, //to be removed
   1.123 +   Master,
   1.124 +   Shutdown,
   1.125 +   Idle
   1.126 + };
   1.127 + 
   1.128 +/*This structure embodies the state of a slaveVP.  It is reused for masterVP
   1.129 + * and shutdownVPs.
   1.130 + */
   1.131 +struct _SlaveVP
   1.132 + {    //The offsets of these fields are hard-coded into assembly
   1.133 +   void       *stackPtr;         //save the core's stack ptr when suspend
   1.134 +   void       *framePtr;         //save core's frame ptr when suspend
   1.135 +   void       *resumeInstrPtr;   //save core's program-counter when suspend
   1.136 +   void       *coreCtlrFramePtr; //restore before jmp back to core controller
   1.137 +   void       *coreCtlrStackPtr; //restore before jmp back to core controller
   1.138 +   
   1.139 +      //============ below this, no fields are used in asm =============
   1.140 +   
   1.141 +   int         slaveID;       //each slave given a globally unique ID
   1.142 +   int         coreAnimatedBy; 
   1.143 +   void       *startOfStack;  //used to free, and to point slave to Fn
   1.144 +   enum VPtype typeOfVP;      //Slave vs Master vs Shutdown..
   1.145 +   int         assignCount;   //Each assign is for one work-unit, so IDs it
   1.146 +      //note, a scheduling decision is uniquely identified by the triple:
   1.147 +      // <slaveID, coreAnimatedBy, assignCount> -- used in record & replay
   1.148 +   
   1.149 +      //for comm -- between master and coreCtlr & btwn wrapper lib and plugin
   1.150 +   AnimSlot   *animSlotAssignedTo;
   1.151 +   PRReqst   *request;      //wrapper lib puts in requests, plugin takes out
   1.152 +   void       *dataRetFromReq;//Return vals from plugin to Wrapper Lib
   1.153 +
   1.154 +      //For using Slave as carrier for data
   1.155 +   void       *semanticData;  //Lang saves lang-specific things in slave here
   1.156 +
   1.157 +        //=========== MEASUREMENT STUFF ==========
   1.158 +         MEAS__Insert_Meas_Fields_into_Slave;
   1.159 +         float64     createPtInSecs;  //time VP created, in seconds
   1.160 +        //========================================
   1.161 + };
   1.162 +//SlaveVP
   1.163 +
   1.164 + 
   1.165 +/* The one and only global variable, holds many odds and ends
   1.166 + */
   1.167 +typedef struct
   1.168 + {    //The offsets of these fields are hard-coded into assembly
   1.169 +   void            *coreCtlrReturnPt;    //offset to this field used in asm
   1.170 +   int8             falseSharePad1[256 - sizeof(void*)];
   1.171 +   int32            masterLock;          //offset to this field used in asm
   1.172 +   int8             falseSharePad2[256 - sizeof(int32)];
   1.173 +      //============ below this, no fields are used in asm =============
   1.174 +
   1.175 +      //Basic PR infrastructure
   1.176 +   SlaveVP        **masterVPs;
   1.177 +   AnimSlot      ***allAnimSlots;
   1.178 +   
   1.179 +      //plugin related
   1.180 +   PRSemEnv       **langlets;
   1.181 +   
   1.182 +      //Slave creation -- global count of slaves existing, across langs and processes
   1.183 +   int32            numSlavesCreated;  //used to give unique ID to processor
   1.184 +//no reasonable way to do fail-safe when have mult langlets and processes.. have to detect for each langlet separately
   1.185 +//   int32            numSlavesAlive;    //used to detect fail-safe shutdown
   1.186 +
   1.187 +      //Initialization related
   1.188 +   int32            setupComplete;      //use while starting up coreCtlr
   1.189 +
   1.190 +      //Memory management related
   1.191 +   MallocArrays    *freeLists;
   1.192 +   int32            amtOfOutstandingMem;//total currently allocated
   1.193 +
   1.194 +      //Random number seeds -- random nums used in various places  
   1.195 +   uint32_t seed1;
   1.196 +   uint32_t seed2;
   1.197 +
   1.198 +      //=========== MEASUREMENT STUFF =============
   1.199 +       IntervalProbe   **intervalProbes;
   1.200 +       PtrToPrivDynArray *dynIntervalProbesInfo;
   1.201 +       HashTable        *probeNameHashTbl;
   1.202 +       int32             masterCreateProbeID;
   1.203 +       float64           createPtInSecs; //real-clock time PR initialized
   1.204 +       Histogram       **measHists;
   1.205 +       PtrToPrivDynArray *measHistsInfo;
   1.206 +       MEAS__Insert_Susp_Meas_Fields_into_MasterEnv;
   1.207 +       MEAS__Insert_Master_Meas_Fields_into_MasterEnv;
   1.208 +       MEAS__Insert_Master_Lock_Meas_Fields_into_MasterEnv;
   1.209 +       MEAS__Insert_Malloc_Meas_Fields_into_MasterEnv;
   1.210 +       MEAS__Insert_Plugin_Meas_Fields_into_MasterEnv;
   1.211 +       MEAS__Insert_System_Meas_Fields_into_MasterEnv;
   1.212 +       MEAS__Insert_Counter_Meas_Fields_into_MasterEnv;
   1.213 +      //==========================================
   1.214 + }
   1.215 +MasterEnv;
   1.216 +
   1.217 +//=====================
   1.218 +typedef struct
   1.219 + { int32   langletID; //acts as index into array of langlets in master env
   1.220 +   void   *langletSemEnv;
   1.221 +   int32   langMagicNumber;
   1.222 +   SlaveAssigner    slaveAssigner;
   1.223 +   RequestHandler   requestHandler;
   1.224 +   EndTaskHandler   endTaskHandler;
   1.225 +   
   1.226 +      //Tack slaves created, separately for each langlet (in each process)
   1.227 +   int32            numSlavesCreated;  //gives ordering to processor creation
   1.228 +   int32            numSlavesAlive;    //used to detect fail-safe shutdown
   1.229 +   
   1.230 +      //when multi-lang, master polls sem env's to find one with work in it..
   1.231 +      // in single-lang case, flag ignored, master always asks lang for work
   1.232 +   int32   hasWork;    
   1.233 + }
   1.234 +PRSemEnv;
   1.235 +
   1.236 +//=====================  Top Processor level Data Strucs  ======================
   1.237 +typedef struct
   1.238 + { 
   1.239 +   
   1.240 + }
   1.241 +PRProcess;
   1.242 +/*This structure holds all the information PR needs to manage a program.  PR
   1.243 + * stores information about what percent of CPU time the program is getting, 
   1.244 + * 
   1.245 + */
   1.246 +typedef struct
   1.247 + { //void               *semEnv;
   1.248 +   //RequestHdlrFnPtr    requestHandler;
   1.249 +   //SlaveAssignerFnPtr  slaveAssigner;
   1.250 +   int32               numSlavesLive;
   1.251 +   void               *resultToReturn;
   1.252 +  
   1.253 +   SlaveVP        *seedSlv;   
   1.254 +   
   1.255 +      //These are used to coordinate within the main function..?
   1.256 +   bool32          executionIsComplete;
   1.257 +   pthread_mutex_t doneLock; //? not sure need these..?
   1.258 +   pthread_cond_t  doneCond;
   1.259 + }
   1.260 +PRProcess;
   1.261 +
   1.262 +
   1.263 +//=========================  Extra Stuff Data Strucs  =======================
   1.264 +typedef struct
   1.265 + {
   1.266 +
   1.267 + }
   1.268 +PRExcp; //exception
   1.269 +
   1.270 +//=======================  OS Thread related  ===============================
   1.271 +
   1.272 +void * coreController( void *paramsIn );  //standard PThreads fn prototype
   1.273 +void * coreCtlr_Seq( void *paramsIn );  //standard PThreads fn prototype
   1.274 +void animationMaster( void *initData, SlaveVP *masterVP );
   1.275 +
   1.276 +
   1.277 +typedef struct
   1.278 + {
   1.279 +   void           *endThdPt;
   1.280 +   unsigned int    coreNum;
   1.281 + }
   1.282 +ThdParams;
   1.283 +
   1.284 +//=============================  Global Vars ================================
   1.285 +
   1.286 +volatile MasterEnv      *_PRMasterEnv __align_to_cacheline__;
   1.287 +
   1.288 +   //these are global, but only used for startup and shutdown
   1.289 +pthread_t       coreCtlrThdHandles[ NUM_CORES ]; //pthread's virt-procr state
   1.290 +ThdParams      *coreCtlrThdParams [ NUM_CORES ];
   1.291 +
   1.292 +pthread_mutex_t suspendLock;
   1.293 +pthread_cond_t  suspendCond;
   1.294 +
   1.295 +//=========================  Function Prototypes  ===========================
   1.296 +/* MEANING OF   WL  PI  SS  int PROS
   1.297 + * These indicate which places the function is safe to use.  They stand for:
   1.298 + * 
   1.299 + * WL   Wrapper Library -- wrapper lib code should only use these
   1.300 + * PI   Plugin          -- plugin code should only use these
   1.301 + * SS   Startup and Shutdown -- designates these relate to startup & shutdown
   1.302 + * int  internal to PR -- should not be used in wrapper lib or plugin
   1.303 + * PROS means "OS functions for applications to use"
   1.304 + * 
   1.305 + * PR_int__ functions touch internal PR data structs and are only safe
   1.306 + *  to be used inside the master lock.  However, occasionally, they appear
   1.307 + * in wrapper-lib or plugin code.  In those cases, very careful analysis
   1.308 + * has been done to be sure no concurrency issues could arise.
   1.309 + * 
   1.310 + * PR_WL__ functions are all safe for use outside the master lock.
   1.311 + * 
   1.312 + * PROS are only safe for applications to use -- they're like a second
   1.313 + * language mixed in -- but they can't be used inside plugin code, and
   1.314 + * aren't meant for use in wrapper libraries, because they are themselves
   1.315 + * wrapper-library calls!
   1.316 + */
   1.317 +//========== Startup and shutdown ==========
   1.318 +void
   1.319 +PR__start();
   1.320 +
   1.321 +void
   1.322 +PR_SS__start_the_work_then_wait_until_done();
   1.323 +
   1.324 +SlaveVP* 
   1.325 +PR_SS__create_shutdown_slave();
   1.326 +
   1.327 +void
   1.328 +PR_SS__shutdown();
   1.329 +
   1.330 +void
   1.331 +PR_SS__cleanup_at_end_of_shutdown();
   1.332 +
   1.333 +void
   1.334 +PR_SS__register_langlets_semEnv( PRSemEnv *semEnv, int32 VSs_MAGIC_NUMBER, 
   1.335 +                              SlaveVP  *seedVP );
   1.336 +
   1.337 +
   1.338 +//==============    ===============
   1.339 +
   1.340 +inline SlaveVP *
   1.341 +PR_int__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam );
   1.342 +#define PR_PI__create_slaveVP PR_int__create_slaveVP
   1.343 +#define PR_WL__create_slaveVP PR_int__create_slaveVP
   1.344 +
   1.345 +   //Use this to create processor inside entry point & other places outside
   1.346 +   // the PR system boundary (IE, don't animate with a SlaveVP or MasterVP)
   1.347 +SlaveVP *
   1.348 +PR_ext__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam );
   1.349 +
   1.350 +inline SlaveVP *
   1.351 +PR_int__create_slaveVP_helper( SlaveVP *newSlv,       TopLevelFnPtr  fnPtr,
   1.352 +                                void      *dataParam, void           *stackLocs );
   1.353 +
   1.354 +inline void
   1.355 +PR_int__reset_slaveVP_to_TopLvlFn( SlaveVP *slaveVP, TopLevelFnPtr fnPtr,
   1.356 +                              void    *dataParam);
   1.357 +
   1.358 +inline void
   1.359 +PR_int__point_slaveVP_to_OneParamFn( SlaveVP *slaveVP, void *fnPtr,
   1.360 +                              void    *param);
   1.361 +
   1.362 +inline void
   1.363 +PR_int__point_slaveVP_to_TwoParamFn( SlaveVP *slaveVP, void *fnPtr,
   1.364 +                              void    *param1, void *param2);
   1.365 +
   1.366 +void
   1.367 +PR_int__dissipate_slaveVP( SlaveVP *slaveToDissipate );
   1.368 +#define PR_PI__dissipate_slaveVP PR_int__dissipate_slaveVP
   1.369 +//WL: dissipate a SlaveVP by sending a request
   1.370 +
   1.371 +void
   1.372 +PR_ext__dissipate_slaveVP( SlaveVP *slaveToDissipate );
   1.373 +
   1.374 +void
   1.375 +PR_int__throw_exception( char *msgStr, SlaveVP *reqstSlv, PRExcp *excpData );
   1.376 +#define PR_PI__throw_exception  PR_int__throw_exception
   1.377 +void
   1.378 +PR_WL__throw_exception( char *msgStr, SlaveVP *reqstSlv,  PRExcp *excpData );
   1.379 +#define PR_App__throw_exception PR_WL__throw_exception
   1.380 +
   1.381 +void *
   1.382 +PR_int__give_sem_env_for( SlaveVP *animSlv );
   1.383 +#define PR_PI__give_sem_env_for  PR_int__give_sem_env_for
   1.384 +#define PR_SS__give_sem_env_for  PR_int__give_sem_env_for
   1.385 +//No WL version -- not safe!  if use in WL, be sure data rd & wr is stable
   1.386 +
   1.387 +
   1.388 +inline void
   1.389 +PR_int__get_master_lock();
   1.390 +
   1.391 +#define PR_int__release_master_lock() _PRMasterEnv->masterLock = UNLOCKED
   1.392 +
   1.393 +inline uint32_t
   1.394 +PR_int__randomNumber();
   1.395 +
   1.396 +//==============  Request Related  ===============
   1.397 +
   1.398 +void
   1.399 +PR_int__suspend_slaveVP_and_send_req( SlaveVP *callingSlv );
   1.400 +
   1.401 +inline void
   1.402 +PR_WL__add_sem_request_in_mallocd_PRReqst( void *semReqData, SlaveVP *callingSlv );
   1.403 +
   1.404 +inline void
   1.405 +PR_WL__send_sem_request( void *semReqData, SlaveVP *callingSlv );
   1.406 +
   1.407 +void
   1.408 +PR_WL__send_create_slaveVP_req( void *semReqData, SlaveVP *reqstingSlv );
   1.409 +
   1.410 +void inline
   1.411 +PR_WL__send_dissipate_req( SlaveVP *prToDissipate );
   1.412 +
   1.413 +inline void
   1.414 +PR_WL__send_PRSem_request( void *semReqData, SlaveVP *callingSlv );
   1.415 +
   1.416 +PRReqst *
   1.417 +PR_PI__take_next_request_out_of( SlaveVP *slaveWithReq );
   1.418 +//#define PR_PI__take_next_request_out_of( slave ) slave->requests
   1.419 +
   1.420 +//inline void *
   1.421 +//PR_PI__take_sem_reqst_from( PRReqst *req );
   1.422 +#define PR_PI__take_sem_reqst_from( req ) req->semReqData
   1.423 +
   1.424 +void inline
   1.425 +PR_PI__handle_PRSemReq( PRReqst *req, SlaveVP *requestingSlv, void *semEnv,
   1.426 +                       ResumeSlvFnPtr resumeSlvFnPtr );
   1.427 +
   1.428 +//======================== MEASUREMENT ======================
   1.429 +uint64
   1.430 +PR_WL__give_num_plugin_cycles();
   1.431 +uint32
   1.432 +PR_WL__give_num_plugin_animations();
   1.433 +
   1.434 +
   1.435 +//========================= Utilities =======================
   1.436 +inline char *
   1.437 +PR_int__strDup( char *str );
   1.438 +
   1.439 +
   1.440 +//========================= Probes =======================
   1.441 +#include "Services_Offered_by_PR/Measurement_and_Stats/probes.h"
   1.442 +
   1.443 +//================================================
   1.444 +#endif	/* _PR_H */
   1.445 +