Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
diff PR.h @ 261:dafae55597ce
Getting closer -- added PRServ as built-in langlet (but still just copy)
about to rework a lot of the Master code.. possibly eliminate core controller
| author | Sean Halle <seanhalle@yahoo.com> |
|---|---|
| date | Tue, 23 Oct 2012 23:46:17 -0700 |
| parents | 999f2966a3e5 |
| children | a5fa1e087c7e |
line diff
1.1 --- a/PR.h Wed Sep 19 23:12:44 2012 -0700 1.2 +++ b/PR.h Tue Oct 23 23:46:17 2012 -0700 1.3 @@ -32,15 +32,17 @@ 1.4 // 1.5 typedef unsigned long long TSCount; 1.6 1.7 -typedef struct _AnimSlot AnimSlot; 1.8 -typedef struct _PRReqst PRReqst; 1.9 +typedef struct _AnimSlot AnimSlot; 1.10 +typedef struct _PRReqst PRReqst; 1.11 typedef struct _SlaveVP SlaveVP; 1.12 typedef struct _MasterVP MasterVP; 1.13 typedef struct _IntervalProbe IntervalProbe; 1.14 +typedef struct _PRMetaTask PRMetaTask; 1.15 1.16 1.17 typedef SlaveVP *(*SlaveAssigner) ( void *, AnimSlot*); //semEnv, slot for HW info 1.18 typedef void (*RequestHandler) ( SlaveVP *, void * ); //prWReqst, semEnv 1.19 +typedef void (*IndivReqHandler)( SlaveVP *, void * ); //prWReqst, semEnv 1.20 typedef void (*TopLevelFnPtr) ( void *, SlaveVP * ); //initData, animSlv 1.21 typedef void TopLevelFn ( void *, SlaveVP * ); //initData, animSlv 1.22 typedef void (*ResumeSlvFnPtr) ( SlaveVP *, void * ); 1.23 @@ -57,25 +59,41 @@ 1.24 //============= Request Related =========== 1.25 // 1.26 1.27 -enum PRReqstType //avoid starting enums at 0, for debug reasons 1.28 +enum PRReqstType //avoid starting enums at 0, for debug reasons 1.29 { 1.30 - semantic = 1, 1.31 - createReq, 1.32 - dissipate, 1.33 - PRSemantic //goes with PRSemReqst below 1.34 + TaskCreate = 1, 1.35 + TaskEnd, 1.36 + SlvCreate, 1.37 + SlvDissipate, 1.38 + Language, 1.39 + Service, //To invoke a PR provided equivalent of a language request (ex: probe) 1.40 + Hardware, 1.41 + IO, 1.42 + OSCall 1.43 }; 1.44 1.45 struct _PRReqst 1.46 { 1.47 - enum PRReqstType reqType;//used for dissipate and in future for IO requests 1.48 - void *semReqData; 1.49 - 1.50 + enum PRReqstType reqType;//used for special forms that have PR behavior 1.51 + void *semReq; 1.52 + PRProcess *processReqIsIn; 1.53 + int32 langMagicNumber; 1.54 + PRMetaTask *metaTask; 1.55 + TopLevelFn topLevelFn; 1.56 + void *initData; 1.57 + int32 *ID; 1.58 + 1.59 + //The request handling structure is a bit messy.. for special forms, 1.60 + // such as create and dissipate, the language inserts pointer to handler 1.61 + // fn directly into the request.. might change to this for all requests 1.62 + IndivReqHandler handler; //pointer to handler fn for create, dissip, etc 1.63 + 1.64 PRReqst *nextReqst; 1.65 }; 1.66 //PRReqst 1.67 1.68 -enum PRSemReqstType //These are equivalent to semantic requests, but for 1.69 - { // PR's services available directly to app, like OS 1.70 +enum PRServReqType //These are equivalent to semantic requests, but for 1.71 + { // PR's services available directly to app, like OS 1.72 make_probe = 1, // and probe services -- like a PR-wide built-in lang 1.73 throw_excp, 1.74 openFile, 1.75 @@ -83,13 +101,13 @@ 1.76 }; 1.77 1.78 typedef struct 1.79 - { enum PRSemReqstType reqType; 1.80 + { enum PRServReqType reqType; 1.81 SlaveVP *requestingSlv; 1.82 char *nameStr; //for create probe 1.83 char *msgStr; //for exception 1.84 void *exceptionData; 1.85 } 1.86 - PRSemReq; 1.87 +PRServReq; 1.88 1.89 1.90 //==================== Core data structures =================== 1.91 @@ -114,9 +132,8 @@ 1.92 1.93 enum VPtype 1.94 { TaskSlotSlv = 1,//Slave tied to an anim slot, only animates tasks 1.95 - TaskExtraSlv, //When a suspended task ends, the slave becomes this 1.96 - PersistentSlv, //the VP is explicitly seen in the app code, or task suspends 1.97 - Slave, //to be removed 1.98 + TaskFreeSlv, //When a suspended task ends, the slave becomes this 1.99 + GenericSlv, //the VP is explicitly seen in the app code, or task suspends 1.100 Master, 1.101 Shutdown, 1.102 Idle 1.103 @@ -135,22 +152,27 @@ 1.104 1.105 //============ below this, no fields are used in asm ============= 1.106 1.107 + void *startOfStack; //used to free, and to point slave to Fn 1.108 + PRProcess *processSlaveIsIn; 1.109 + PRMetaTask *metaTask; 1.110 + enum VPtype typeOfVP; //Slave vs Master vs Shutdown.. 1.111 int slaveID; //each slave given a globally unique ID 1.112 int coreAnimatedBy; 1.113 - void *startOfStack; //used to free, and to point slave to Fn 1.114 - enum VPtype typeOfVP; //Slave vs Master vs Shutdown.. 1.115 - int assignCount; //Each assign is for one work-unit, so IDs it 1.116 + int numTimesAssignedToASlot; //Each assign is for one work-unit, so is an ID 1.117 //note, a scheduling decision is uniquely identified by the triple: 1.118 - // <slaveID, coreAnimatedBy, assignCount> -- used in record & replay 1.119 + // <slaveID, coreAnimatedBy, numTimesAssignedToASlot> -- used in record & replay 1.120 1.121 //for comm -- between master and coreCtlr & btwn wrapper lib and plugin 1.122 AnimSlot *animSlotAssignedTo; 1.123 - PRReqst *request; //wrapper lib puts in requests, plugin takes out 1.124 + PRReqst *request; //wrapper lib puts in requests, plugin takes out 1.125 void *dataRetFromReq;//Return vals from plugin to Wrapper Lib 1.126 1.127 - //For using Slave as carrier for data 1.128 + //For language specific data that needs to be in the slave 1.129 void *semanticData; //Lang saves lang-specific things in slave here 1.130 1.131 + //Task related stuff 1.132 + bool needsTaskAssigned; 1.133 + 1.134 //=========== MEASUREMENT STUFF ========== 1.135 MEAS__Insert_Meas_Fields_into_Slave; 1.136 float64 createPtInSecs; //time VP created, in seconds 1.137 @@ -172,14 +194,12 @@ 1.138 //Basic PR infrastructure 1.139 SlaveVP **masterVPs; 1.140 AnimSlot ***allAnimSlots; 1.141 + 1.142 + PRProcess **processes; 1.143 1.144 - //plugin related 1.145 - PRSemEnv **langlets; 1.146 - 1.147 - //Slave creation -- global count of slaves existing, across langs and processes 1.148 +//move to processEnv //Slave creation -- global count of slaves existing, across langs and processes 1.149 int32 numSlavesCreated; //used to give unique ID to processor 1.150 -//no reasonable way to do fail-safe when have mult langlets and processes.. have to detect for each langlet separately 1.151 -// int32 numSlavesAlive; //used to detect fail-safe shutdown 1.152 + int32 numTasksCreated; //to give unique ID to a task 1.153 1.154 //Initialization related 1.155 int32 setupComplete; //use while starting up coreCtlr 1.156 @@ -192,14 +212,24 @@ 1.157 uint32_t seed1; 1.158 uint32_t seed2; 1.159 1.160 + These_Prob_belong_in_PRPRocess; 1.161 +// SlaveVP *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS]; 1.162 +// int32 numLiveFreeTaskSlvs; 1.163 +// int32 numLiveThreadSlvs; 1.164 +// bool32 *coreIsDone; 1.165 +// int32 numCoresDone; 1.166 + 1.167 +// SlaveVP* idleSlv[NUM_CORES][NUM_ANIM_SLOTS]; 1.168 +// int shutdownInitiated; 1.169 + 1.170 //=========== MEASUREMENT STUFF ============= 1.171 IntervalProbe **intervalProbes; 1.172 - PtrToPrivDynArray *dynIntervalProbesInfo; 1.173 + PrivDynArrayInfo *dynIntervalProbesInfo; 1.174 HashTable *probeNameHashTbl; 1.175 int32 masterCreateProbeID; 1.176 float64 createPtInSecs; //real-clock time PR initialized 1.177 Histogram **measHists; 1.178 - PtrToPrivDynArray *measHistsInfo; 1.179 + PrivDynArrayInfo *measHistsInfo; 1.180 MEAS__Insert_Susp_Meas_Fields_into_MasterEnv; 1.181 MEAS__Insert_Master_Meas_Fields_into_MasterEnv; 1.182 MEAS__Insert_Master_Lock_Meas_Fields_into_MasterEnv; 1.183 @@ -213,45 +243,112 @@ 1.184 1.185 //===================== 1.186 typedef struct 1.187 - { int32 langletID; //acts as index into array of langlets in master env 1.188 - void *langletSemEnv; 1.189 - int32 langMagicNumber; 1.190 - SlaveAssigner slaveAssigner; 1.191 - RequestHandler requestHandler; 1.192 - EndTaskHandler endTaskHandler; 1.193 + { int32 langMagicNumber; //indexes into hash array of semEnvs in PRProcess 1.194 + PRSemEnv *chainedSemEnv; //chains to semEnvs with same hash 1.195 + void *langSemEnv; 1.196 1.197 - //Tack slaves created, separately for each langlet (in each process) 1.198 - int32 numSlavesCreated; //gives ordering to processor creation 1.199 - int32 numSlavesAlive; //used to detect fail-safe shutdown 1.200 + SlaveAssigner slaveAssigner; 1.201 + RequestHandler requestHdlr; 1.202 + 1.203 + RequestHandler createTaskHdlr; 1.204 + RequestHandler endTaskHdlr; 1.205 + RequestHandler createSlaveHdlr; 1.206 + RequestHandler dissipateSlaveHdlr; 1.207 + RequestHandler semDataCreator; 1.208 + RequestHandler semDataInitializer; 1.209 + 1.210 + 1.211 + //Track slaves created, separately for each langlet? (in each process) 1.212 +// int32 numSlavesCreated; //gives ordering to processor creation 1.213 +// int32 numSlavesAlive; //used to detect fail-safe shutdown 1.214 1.215 //when multi-lang, master polls sem env's to find one with work in it.. 1.216 // in single-lang case, flag ignored, master always asks lang for work 1.217 - int32 hasWork; 1.218 + int32 hasWork; 1.219 } 1.220 PRSemEnv; 1.221 1.222 -//===================== Top Processor level Data Strucs ====================== 1.223 +//The semantic env of every langlet must start with these two fields, so that 1.224 +// PR can cast the void * to this struct, in order to access these two fields 1.225 typedef struct 1.226 + { int32 langMagicNumber; 1.227 + PRSemEnv *protoSemEnv; 1.228 + } 1.229 +PRLangSemEnv; 1.230 + 1.231 +//can cast any langlet's sem env to one of these, so PR can access values 1.232 +typedef struct 1.233 + { int32 langMagicNumber; 1.234 + PRSemEnv *protoSemEnv; 1.235 + } 1.236 +PRServSemEnv; 1.237 + 1.238 +enum PRTaskType 1.239 + { GenericSlave = 1, 1.240 + AtomicTask, 1.241 + SuspendedTask 1.242 + }; 1.243 + 1.244 +struct _PRMetaTask 1.245 { 1.246 - 1.247 + PRTaskType taskType; 1.248 + RequestHandler reqHandler; //Lang-specific hdlr for create, end, etc 1.249 + int32 *taskID; //is standard PR ID 1.250 + SlaveVP *slaveAssignedTo; //no valid until task animated 1.251 + TopLevelFn topLevelFn; //This is the Fn executes as the task 1.252 + void *initData; //The data taken by the function 1.253 + void *langMetaTask; 1.254 + 1.255 + //NOTE: info needed for "wait" functionality is inside lang's metaTask 1.256 + }; 1.257 +//PRMetaTask 1.258 + 1.259 +/*The language's meta task is cast to this struct, inside PR, then the 1.260 + * back pointer to protoMetaTask is set. Keeps existence of PRMetaTask hidden 1.261 + * from plugin -- so can change later. 1.262 + */ 1.263 +typedef struct 1.264 + { int32 langMagicNumber; 1.265 + PRMetaTask *protoMetaTask; 1.266 } 1.267 -PRProcess; 1.268 +PRLangMetaTask; 1.269 + 1.270 +typedef struct 1.271 + { 1.272 + void (*freeFn)(void *); 1.273 + } 1.274 +PRSemDataTemplate; 1.275 + 1.276 +typedef struct 1.277 + { PRSemDataTemplate **semDatas; 1.278 + PRSemDataTemplate **semDatasIter; 1.279 + int32 numSemDatas; 1.280 + } 1.281 +PRSemDataHolder; 1.282 +//===================== Top Process level Data Strucs ====================== 1.283 + 1.284 /*This structure holds all the information PR needs to manage a program. PR 1.285 * stores information about what percent of CPU time the program is getting, 1.286 * 1.287 */ 1.288 typedef struct 1.289 - { //void *semEnv; 1.290 - //RequestHdlrFnPtr requestHandler; 1.291 - //SlaveAssignerFnPtr slaveAssigner; 1.292 - int32 numSlavesLive; 1.293 - void *resultToReturn; 1.294 + { 1.295 + PRSemEnv semEnvs[NUM_SEM_ENVS_IN_PROCESS]; //used as a hash table 1.296 + PRSemEnv semEnvList[NUM_SEM_ENVS_IN_PROCESS]; //lines up the semEnvs, so can iterate through 1.297 + int32 numSemEnvs; //must be less than num sem envs.. used to iterate through 1.298 + 1.299 + int32 numLiveGenericSlaves; 1.300 + int32 numLiveFreeTaskSlaves; 1.301 + int32 numLiveTasks; 1.302 + bool32 coreIsDone[NUM_CORES][CACHE_LINE_SZ]; //Fixes false sharing 1.303 + 1.304 + void *resultToReturn; 1.305 1.306 SlaveVP *seedSlv; 1.307 1.308 - //These are used to coordinate within the main function..? 1.309 + //These are used to coord with OS thread waiting for process to end 1.310 bool32 executionIsComplete; 1.311 - pthread_mutex_t doneLock; //? not sure need these..? 1.312 + pthread_mutex_t doneLock; 1.313 pthread_cond_t doneCond; 1.314 } 1.315 PRProcess; 1.316 @@ -280,7 +377,7 @@ 1.317 1.318 //============================= Global Vars ================================ 1.319 1.320 -volatile MasterEnv *_PRMasterEnv __align_to_cacheline__; 1.321 +volatile MasterEnv *_PRTopEnv __align_to_cacheline__; 1.322 1.323 //these are global, but only used for startup and shutdown 1.324 pthread_t coreCtlrThdHandles[ NUM_CORES ]; //pthread's virt-procr state 1.325 @@ -315,9 +412,6 @@ 1.326 void 1.327 PR__start(); 1.328 1.329 -void 1.330 -PR_SS__start_the_work_then_wait_until_done(); 1.331 - 1.332 SlaveVP* 1.333 PR_SS__create_shutdown_slave(); 1.334 1.335 @@ -328,8 +422,7 @@ 1.336 PR_SS__cleanup_at_end_of_shutdown(); 1.337 1.338 void 1.339 -PR_SS__register_langlets_semEnv( PRSemEnv *semEnv, int32 VSs_MAGIC_NUMBER, 1.340 - SlaveVP *seedVP ); 1.341 +PR_SS__register_langlets_semEnv( PRSemEnv *semEnv, SlaveVP *seedVP, int32 VSs_MAGIC_NUMBER ); 1.342 1.343 1.344 //============== =============== 1.345 @@ -339,35 +432,45 @@ 1.346 #define PR_PI__create_slaveVP PR_int__create_slaveVP 1.347 #define PR_WL__create_slaveVP PR_int__create_slaveVP 1.348 1.349 - //Use this to create processor inside entry point & other places outside 1.350 - // the PR system boundary (IE, don't animate with a SlaveVP or MasterVP) 1.351 +inline 1.352 SlaveVP * 1.353 -PR_ext__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam ); 1.354 +PR_int__create_slot_slave(); 1.355 1.356 -inline SlaveVP * 1.357 +inline 1.358 +SlaveVP * 1.359 PR_int__create_slaveVP_helper( SlaveVP *newSlv, TopLevelFnPtr fnPtr, 1.360 void *dataParam, void *stackLocs ); 1.361 1.362 -inline void 1.363 +inline 1.364 +PRMetaTask * 1.365 +PR_int__create_generic_slave_meta_task( void *initData ); 1.366 + 1.367 +inline 1.368 +void 1.369 PR_int__reset_slaveVP_to_TopLvlFn( SlaveVP *slaveVP, TopLevelFnPtr fnPtr, 1.370 void *dataParam); 1.371 1.372 -inline void 1.373 +inline 1.374 +void 1.375 PR_int__point_slaveVP_to_OneParamFn( SlaveVP *slaveVP, void *fnPtr, 1.376 void *param); 1.377 1.378 -inline void 1.379 +inline 1.380 +void 1.381 PR_int__point_slaveVP_to_TwoParamFn( SlaveVP *slaveVP, void *fnPtr, 1.382 void *param1, void *param2); 1.383 1.384 +inline 1.385 void 1.386 PR_int__dissipate_slaveVP( SlaveVP *slaveToDissipate ); 1.387 #define PR_PI__dissipate_slaveVP PR_int__dissipate_slaveVP 1.388 //WL: dissipate a SlaveVP by sending a request 1.389 1.390 +inline 1.391 void 1.392 -PR_ext__dissipate_slaveVP( SlaveVP *slaveToDissipate ); 1.393 +PR_int__dissipate_slaveVP_multilang( SlaveVP *slaveToDissipate ); 1.394 1.395 +inline 1.396 void 1.397 PR_int__throw_exception( char *msgStr, SlaveVP *reqstSlv, PRExcp *excpData ); 1.398 #define PR_PI__throw_exception PR_int__throw_exception 1.399 @@ -375,17 +478,51 @@ 1.400 PR_WL__throw_exception( char *msgStr, SlaveVP *reqstSlv, PRExcp *excpData ); 1.401 #define PR_App__throw_exception PR_WL__throw_exception 1.402 1.403 +inline 1.404 void * 1.405 -PR_int__give_sem_env_for( SlaveVP *animSlv ); 1.406 -#define PR_PI__give_sem_env_for PR_int__give_sem_env_for 1.407 -#define PR_SS__give_sem_env_for PR_int__give_sem_env_for 1.408 -//No WL version -- not safe! if use in WL, be sure data rd & wr is stable 1.409 +PR_int__give_sem_env_for_slave( SlaveVP *slave, int32 magicNumber ); 1.410 +#define PR_PI__give_sem_env_for PR_int__give_sem_env_for_slave 1.411 +#define PR_SS__give_sem_env_for_slave PR_int__give_sem_env_for_slave 1.412 +//No WL version -- not safe! if use env in WL, be sure data rd & wr is stable 1.413 +inline 1.414 +PRSemEnv * 1.415 +PR_int__give_proto_sem_env_for_slave( SlaveVP *slave, int32 magicNumber ); 1.416 +#define PR_PI__give_proto_sem_env_for PR_int__give_proto_sem_env_for_slave 1.417 +#define PR_SS__give_proto_sem_env_for_slave PR_int__give_proto_sem_env_for_slave 1.418 +//No WL version -- not safe! if use env in WL, be sure data rd & wr is stable 1.419 +inline 1.420 +void * 1.421 +PR_int__give_sem_env_from_process( PRProcess *process, int32 magicNumer ); 1.422 +#define PR_PI__give_sem_env_from_process PR_int__give_sem_env_from_process 1.423 +#define PR_SS__give_sem_env_from_process PR_int__give_sem_env_from_process 1.424 +//#define PR_WL__give_sem_env_from_process PR_int__give_sem_env_from_process 1.425 +//No WL version -- not safe! if use env in WL, be sure data rd & wr is stable 1.426 1.427 +inline 1.428 +void * 1.429 +PR_int__give_sem_data( SlaveVP *slave, int32 magicNumer ); 1.430 +#define PR_PI__give_sem_data PR_int__give_sem_data 1.431 +#define PR_SS__give_sem_data PR_int__give_sem_data 1.432 +#define PR_WL__give_sem_data PR_int__give_sem_data 1.433 + 1.434 + 1.435 +#define PR_int__give_lang_meta_task( slave, magicNumber )\ 1.436 + slave->metaTask->langMetaTask; 1.437 +#define PR_PI__give_lang_meta_task PR_int__give_lang_meta_task 1.438 +#define PR_SS__give_lang_meta_task PR_int__give_lang_meta_task 1.439 +#define PR_WL__give_lang_meta_task PR_int__give_lang_meta_task 1.440 + 1.441 +inline 1.442 +SlaveVP * 1.443 +PR_PI__give_slave_assigned_to( PRLangMetaTask *langMetaTask ); 1.444 + 1.445 +void 1.446 +idle_fn(void* data, SlaveVP *animatingSlv); 1.447 1.448 inline void 1.449 PR_int__get_master_lock(); 1.450 1.451 -#define PR_int__release_master_lock() _PRMasterEnv->masterLock = UNLOCKED 1.452 +#define PR_int__release_master_lock() _PRTopEnv->masterLock = UNLOCKED 1.453 1.454 inline uint32_t 1.455 PR_int__randomNumber(); 1.456 @@ -393,13 +530,13 @@ 1.457 //============== Request Related =============== 1.458 1.459 void 1.460 -PR_int__suspend_slaveVP_and_send_req( SlaveVP *callingSlv ); 1.461 +PR_WL__suspend_slaveVP_and_send_req( SlaveVP *callingSlv ); 1.462 1.463 inline void 1.464 PR_WL__add_sem_request_in_mallocd_PRReqst( void *semReqData, SlaveVP *callingSlv ); 1.465 1.466 inline void 1.467 -PR_WL__send_sem_request( void *semReqData, SlaveVP *callingSlv ); 1.468 +PR_WL__send_sem_request( void *semReq, SlaveVP *callingSlv, int32 magicNum ); 1.469 1.470 void 1.471 PR_WL__send_create_slaveVP_req( void *semReqData, SlaveVP *reqstingSlv ); 1.472 @@ -408,7 +545,7 @@ 1.473 PR_WL__send_dissipate_req( SlaveVP *prToDissipate ); 1.474 1.475 inline void 1.476 -PR_WL__send_PRSem_request( void *semReqData, SlaveVP *callingSlv ); 1.477 +PR_WL__send_service_request( void *semReqData, SlaveVP *callingSlv ); 1.478 1.479 PRReqst * 1.480 PR_PI__take_next_request_out_of( SlaveVP *slaveWithReq ); 1.481 @@ -419,7 +556,7 @@ 1.482 #define PR_PI__take_sem_reqst_from( req ) req->semReqData 1.483 1.484 void inline 1.485 -PR_PI__handle_PRSemReq( PRReqst *req, SlaveVP *requestingSlv, void *semEnv, 1.486 +PR_int__handle_PRServiceReq( PRReqst *req, SlaveVP *requestingSlv, void *semEnv, 1.487 ResumeSlvFnPtr resumeSlvFnPtr ); 1.488 1.489 //======================== MEASUREMENT ====================== 1.490 @@ -434,6 +571,14 @@ 1.491 PR_int__strDup( char *str ); 1.492 1.493 1.494 +//========================= PR request handlers ======================== 1.495 +void inline 1.496 +handleMakeProbe( PRServReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn ); 1.497 + 1.498 +void inline 1.499 +handleThrowException( PRServReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn ); 1.500 +//======================================================================= 1.501 + 1.502 //========================= Probes ======================= 1.503 #include "Services_Offered_by_PR/Measurement_and_Stats/probes.h" 1.504
