Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
view PR.h @ 267:608833ae2c5d
Checkpoint -- about to clean up AnimationMaster, deleting a bunch of stuff
| author | Sean Halle <seanhalle@yahoo.com> |
|---|---|
| date | Sun, 04 Nov 2012 18:39:28 -0800 |
| parents | a5fa1e087c7e |
| children | e5bd470b562b |
line source
1 /*
2 * Copyright 2009 OpenSourceStewardshipFoundation.org
3 * Licensed under GNU General Public License version 2
4 *
5 * Author: seanhalle@yahoo.com
6 *
7 */
9 #ifndef _PR_H
10 #define _PR_H
11 #define _GNU_SOURCE
13 #include "DynArray/DynArray.h"
14 #include "Hash_impl/PrivateHash.h"
15 #include "Histogram/Histogram.h"
16 #include "Queue_impl/PrivateQueue.h"
18 #include "PR_primitive_data_types.h"
19 #include "Services_Offered_by_PR/Memory_Handling/vmalloc.h"
21 #include <pthread.h>
22 #include <sys/time.h>
24 //================= Defines: included from separate files =================
25 //
26 // Note: ALL defines are in other files, none are in here
27 //
28 #include "Defines/PR_defs.h"
31 //================================ Typedefs =================================
32 //
33 typedef unsigned long long TSCount;
35 typedef struct _AnimSlot AnimSlot;
36 typedef struct _PRReqst PRReqst;
37 typedef struct _SlaveVP SlaveVP;
38 typedef struct _MasterVP MasterVP;
39 typedef struct _IntervalProbe IntervalProbe;
40 typedef struct _PRMetaTask PRMetaTask;
43 typedef SlaveVP *(*SlaveAssigner) ( void *, AnimSlot*); //semEnv, slot for HW info
44 typedef void (*RequestHandler) ( SlaveVP *, void * ); //prWReqst, semEnv
45 typedef void (*IndivReqHandler)( SlaveVP *, void * ); //prWReqst, semEnv
46 typedef void (*TopLevelFnPtr) ( void *, SlaveVP * ); //initData, animSlv
47 typedef void TopLevelFn ( void *, SlaveVP * ); //initData, animSlv
48 typedef void (*ResumeSlvFnPtr) ( SlaveVP *, void * );
49 //=========== MEASUREMENT STUFF ==========
50 MEAS__Insert_Counter_Handler
51 //========================================
53 //============================ HW Dependent Fns ================================
55 #include "HW_Dependent_Primitives/PR__HW_measurement.h"
56 #include "HW_Dependent_Primitives/PR__primitives.h"
59 //============= Request Related ===========
60 //
62 enum PRReqstType //avoid starting enums at 0, for debug reasons
63 {
64 TaskCreate = 1,
65 TaskEnd,
66 SlvCreate,
67 SlvDissipate,
68 Language,
69 Service, //To invoke a PR provided equivalent of a language request (ex: probe)
70 Hardware,
71 IO,
72 OSCall
73 };
75 struct _PRReqst
76 {
77 enum PRReqstType reqType;//used for special forms that have PR behavior
78 void *semReq;
79 PRProcess *processReqIsIn;
80 int32 langMagicNumber;
81 TopLevelFn topLevelFn;
82 void *initData;
83 int32 *ID;
85 //The request handling structure is a bit messy.. for special forms,
86 // such as create and dissipate, the language inserts pointer to handler
87 // fn directly into the request.. might change to this for all requests
88 IndivReqHandler handler; //pointer to handler fn for create, dissip, etc
90 PRReqst *nextReqst;
91 };
92 //PRReqst
94 enum PRServReqType //These are equivalent to semantic requests, but for
95 { // PR's services available directly to app, like OS
96 make_probe = 1, // and probe services -- like a PR-wide built-in lang
97 throw_excp,
98 openFile,
99 otherIO
100 };
102 typedef struct
103 { enum PRServReqType reqType;
104 SlaveVP *requestingSlv;
105 char *nameStr; //for create probe
106 char *msgStr; //for exception
107 void *exceptionData;
108 }
109 PRServReq;
112 //==================== Core data structures ===================
114 typedef struct
115 {
116 //for future expansion
117 }
118 SlotPerfInfo;
120 struct _AnimSlot
121 {
122 int workIsDone;
123 int needsWorkAssigned;
124 SlaveVP *slaveAssignedToSlot;
126 int slotIdx; //needed by Holistic Model's data gathering
127 int coreSlotIsOn;
128 SlotPerfInfo *perfInfo; //used by assigner to pick best slave for core
129 };
130 //AnimSlot
132 enum VPtype
133 { SlotTaskSlv = 1,//Slave tied to an anim slot, only animates tasks
134 FreeTaskSlv, //When a suspended task ends, the slave becomes this
135 GenericSlv, //the VP is explicitly seen in the app code, or task suspends
136 Master,
137 Shutdown,
138 Idle
139 };
141 /*This structure embodies the state of a slaveVP. It is reused for masterVP
142 * and shutdownVPs.
143 */
144 struct _SlaveVP
145 { //The offsets of these fields are hard-coded into assembly
146 void *stackPtr; //save the core's stack ptr when suspend
147 void *framePtr; //save core's frame ptr when suspend
148 void *resumeInstrPtr; //save core's program-counter when suspend
149 void *coreCtlrFramePtr; //restore before jmp back to core controller
150 void *coreCtlrStackPtr; //restore before jmp back to core controller
152 //============ below this, no fields are used in asm =============
154 void *startOfStack; //used to free, and to point slave to Fn
155 PRProcess *processSlaveIsIn;
156 PRMetaTask *metaTask;
157 enum VPtype typeOfVP; //Slave vs Master vs Shutdown..
158 int slaveID; //each slave given a globally unique ID
159 int coreAnimatedBy;
160 int numTimesAssignedToASlot; //Each assign is for one work-unit, so is an ID
161 //note, a scheduling decision is uniquely identified by the triple:
162 // <slaveID, coreAnimatedBy, numTimesAssignedToASlot> -- used in record & replay
164 //for comm -- between master and coreCtlr & btwn wrapper lib and plugin
165 AnimSlot *animSlotAssignedTo;
166 PRReqst *request; //wrapper lib puts in requests, plugin takes out
167 void *dataRetFromReq;//Return vals from plugin to Wrapper Lib
169 //For language specific data that needs to be in the slave
170 void *semanticData; //Lang saves lang-specific things in slave here
172 //Task related stuff
173 // bool needsTaskAssigned;
175 //=========== MEASUREMENT STUFF ==========
176 MEAS__Insert_Meas_Fields_into_Slave;
177 float64 createPtInSecs; //time VP created, in seconds
178 //========================================
179 };
180 //SlaveVP
183 /* The one and only global variable, holds many odds and ends
184 */
185 typedef struct
186 { //The offsets of these fields are hard-coded into assembly
187 void *coreCtlrReturnPt; //offset to this field used in asm
188 int8 falseSharePad1[256 - sizeof(void*)];
189 int32 masterLock; //offset to this field used in asm
190 int8 falseSharePad2[256 - sizeof(int32)];
191 //============ below this, no fields are used in asm =============
193 //Basic PR infrastructure
194 SlaveVP **masterVPs;
195 AnimSlot ***allAnimSlots;
197 PRProcess **processes;
199 //move to processEnv //Slave creation -- global count of slaves existing, across langs and processes
200 int32 numSlavesCreated; //used to give unique ID to processor
201 int32 numTasksCreated; //to give unique ID to a task
203 //Initialization related
204 int32 setupComplete; //use while starting up coreCtlr
206 //Memory management related
207 MallocArrays *freeLists;
208 int32 amtOfOutstandingMem;//total currently allocated
210 //Random number seeds -- random nums used in various places
211 uint32_t seed1;
212 uint32_t seed2;
214 These_Prob_belong_in_PRPRocess;
215 // SlaveVP *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS];
216 // int32 numLiveFreeTaskSlvs;
217 // int32 numLiveThreadSlvs;
218 // bool32 *coreIsDone;
219 // int32 numCoresDone;
221 // SlaveVP* idleSlv[NUM_CORES][NUM_ANIM_SLOTS];
222 // int shutdownInitiated;
224 //=========== MEASUREMENT STUFF =============
225 IntervalProbe **intervalProbes;
226 PrivDynArrayInfo *dynIntervalProbesInfo;
227 HashTable *probeNameHashTbl;
228 int32 masterCreateProbeID;
229 float64 createPtInSecs; //real-clock time PR initialized
230 Histogram **measHists;
231 PrivDynArrayInfo *measHistsInfo;
232 MEAS__Insert_Susp_Meas_Fields_into_MasterEnv;
233 MEAS__Insert_Master_Meas_Fields_into_MasterEnv;
234 MEAS__Insert_Master_Lock_Meas_Fields_into_MasterEnv;
235 MEAS__Insert_Malloc_Meas_Fields_into_MasterEnv;
236 MEAS__Insert_Plugin_Meas_Fields_into_MasterEnv;
237 MEAS__Insert_System_Meas_Fields_into_MasterEnv;
238 MEAS__Insert_Counter_Meas_Fields_into_MasterEnv;
239 //==========================================
240 }
241 MasterEnv;
243 //=====================
244 typedef struct
245 { int32 langMagicNumber; //indexes into hash array of semEnvs in PRProcess
246 PRSemEnv *chainedSemEnv; //chains to semEnvs with same hash
247 void *langSemEnv;
249 SlaveAssigner slaveAssigner;
250 RequestHandler requestHdlr;
252 RequestHandler createTaskHdlr;
253 RequestHandler endTaskHdlr;
254 RequestHandler createSlaveHdlr;
255 RequestHandler dissipateSlaveHdlr;
256 RequestHandler semDataCreator;
257 RequestHandler semDataInitializer;
260 //Track slaves created, separately for each langlet? (in each process)
261 // int32 numSlavesCreated; //gives ordering to processor creation
262 // int32 numSlavesAlive; //used to detect fail-safe shutdown
264 //when multi-lang, master polls sem env's to find one with work in it..
265 // in single-lang case, flag ignored, master always asks lang for work
266 int32 hasWork;
267 }
268 PRSemEnv;
270 //The semantic env of every langlet must start with these two fields, so that
271 // PR can cast the void * to this struct, in order to access these two fields
272 typedef struct
273 { int32 langMagicNumber;
274 PRSemEnv *protoSemEnv;
275 }
276 PRLangSemEnv;
278 //can cast any langlet's sem env to one of these, so PR can access values
279 typedef struct
280 { int32 langMagicNumber;
281 PRSemEnv *protoSemEnv;
282 }
283 PRServSemEnv;
285 enum PRTaskType
286 { GenericSlave = 1,
287 SlotTask,
288 FreeTask
289 };
291 struct _PRMetaTask
292 {
293 PRTaskType taskType;
294 // RequestHandler reqHandler; //Lang-specific hdlr for create, end, etc
295 int32 *taskID; //is standard PR ID
296 SlaveVP *slaveAssignedTo; //no valid until task animated
297 TopLevelFn topLevelFn; //This is the Fn executes as the task
298 void *initData; //The data taken by the function
299 void *langMetaTask;
301 //NOTE: info needed for "wait" functionality is inside lang's metaTask
302 };
303 //PRMetaTask
305 /*The language's meta task is cast to this struct, inside PR, then the
306 * back pointer to protoMetaTask is set. Keeps existence of PRMetaTask hidden
307 * from plugin -- so can change later.
308 */
309 typedef struct
310 { int32 langMagicNumber;
311 PRMetaTask *protoMetaTask;
312 }
313 PRLangMetaTask;
315 typedef struct
316 {
317 void (*freeFn)(void *);
318 }
319 PRSemDataTemplate;
321 typedef struct
322 {
323 void (*recycler)(void *);
324 void *langSemData;
325 }
326 PRSemData;
328 typedef struct
329 { PRSemDataTemplate **semDatas;
330 PRSemDataTemplate **semDatasIter;
331 int32 numSemDatas;
332 }
333 PRSemDataHolder;
334 //===================== Top Process level Data Strucs ======================
336 /*This structure holds all the information PR needs to manage a program. PR
337 * stores information about what percent of CPU time the program is getting,
338 *
339 */
340 typedef struct
341 {
342 PRSemEnv semEnvs[NUM_SEM_ENVS_IN_PROCESS]; //used as a hash table
343 PRSemEnv semEnvList[NUM_SEM_ENVS_IN_PROCESS]; //lines up the semEnvs, so can iterate through
344 int32 numSemEnvs; //must be less than num sem envs.. used to iterate through
346 int32 numLiveGenericSlvs;
347 int32 numLiveFreeTaskSlvs;
348 int32 numLiveTasks;
349 // bool32 coreIsDone[NUM_CORES][CACHE_LINE_SZ]; //Fixes false sharing
351 PrivQueueStruc *freeTaskSlvRecycleQ;
352 SlaveVP slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS];
353 void *resultToReturn;
355 SlaveVP *seedSlv;
357 SlaveAssigner overrideAssigner;
359 //These are used to coord with OS thread waiting for process to end
360 bool32 executionIsComplete;
361 pthread_mutex_t doneLock;
362 pthread_cond_t doneCond;
363 }
364 PRProcess;
367 //========================= Extra Stuff Data Strucs =======================
368 typedef struct
369 {
371 }
372 PRExcp; //exception
374 //======================= OS Thread related ===============================
376 void * coreController( void *paramsIn ); //standard PThreads fn prototype
377 void * coreCtlr_Seq( void *paramsIn ); //standard PThreads fn prototype
378 void animationMaster( void *initData, SlaveVP *masterVP );
381 typedef struct
382 {
383 void *endThdPt;
384 unsigned int coreNum;
385 }
386 ThdParams;
388 //============================= Global Vars ================================
390 volatile MasterEnv *_PRTopEnv __align_to_cacheline__;
392 //these are global, but only used for startup and shutdown
393 pthread_t coreCtlrThdHandles[ NUM_CORES ]; //pthread's virt-procr state
394 ThdParams *coreCtlrThdParams [ NUM_CORES ];
396 pthread_mutex_t suspendLock;
397 pthread_cond_t suspendCond;
399 //========================= Function Prototypes ===========================
400 /* MEANING OF WL PI SS int PROS
401 * These indicate which places the function is safe to use. They stand for:
402 *
403 * WL Wrapper Library -- wrapper lib code should only use these
404 * PI Plugin -- plugin code should only use these
405 * SS Startup and Shutdown -- designates these relate to startup & shutdown
406 * int internal to PR -- should not be used in wrapper lib or plugin
407 * PROS means "OS functions for applications to use"
408 *
409 * PR_int__ functions touch internal PR data structs and are only safe
410 * to be used inside the master lock. However, occasionally, they appear
411 * in wrapper-lib or plugin code. In those cases, very careful analysis
412 * has been done to be sure no concurrency issues could arise.
413 *
414 * PR_WL__ functions are all safe for use outside the master lock.
415 *
416 * PROS are only safe for applications to use -- they're like a second
417 * language mixed in -- but they can't be used inside plugin code, and
418 * aren't meant for use in wrapper libraries, because they are themselves
419 * wrapper-library calls!
420 */
421 //========== Startup and shutdown ==========
422 void
423 PR__start();
425 SlaveVP*
426 PR_SS__create_shutdown_slave();
428 void
429 PR_SS__shutdown();
431 void
432 PR_SS__cleanup_at_end_of_shutdown();
434 void
435 PR_SS__register_langlets_semEnv( PRSemEnv *semEnv, SlaveVP *seedVP, int32 VSs_MAGIC_NUMBER );
438 //============== ===============
440 inline SlaveVP *
441 PR_int__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam );
442 #define PR_PI__create_slaveVP PR_int__create_slaveVP
443 #define PR_WL__create_slaveVP PR_int__create_slaveVP
445 inline
446 SlaveVP *
447 PR_int__create_slot_slave();
449 inline
450 SlaveVP *
451 PR_int__create_slaveVP_helper( SlaveVP *newSlv, TopLevelFnPtr fnPtr,
452 void *dataParam, void *stackLocs );
454 inline
455 PRMetaTask *
456 PR_int__create_generic_slave_meta_task( void *initData );
458 inline
459 void
460 PR_int__reset_slaveVP_to_TopLvlFn( SlaveVP *slaveVP, TopLevelFnPtr fnPtr,
461 void *dataParam);
463 inline
464 void
465 PR_int__point_slaveVP_to_OneParamFn( SlaveVP *slaveVP, void *fnPtr,
466 void *param);
468 inline
469 void
470 PR_int__point_slaveVP_to_TwoParamFn( SlaveVP *slaveVP, void *fnPtr,
471 void *param1, void *param2);
473 inline
474 void
475 PR_int__dissipate_slaveVP( SlaveVP *slaveToDissipate );
476 #define PR_PI__dissipate_slaveVP PR_int__dissipate_slaveVP
477 //WL: dissipate a SlaveVP by sending a request
479 inline
480 void
481 PR_int__dissipate_slaveVP_multilang( SlaveVP *slaveToDissipate );
483 inline
484 void
485 PR_int__throw_exception( char *msgStr, SlaveVP *reqstSlv, PRExcp *excpData );
486 #define PR_PI__throw_exception PR_int__throw_exception
487 void
488 PR_WL__throw_exception( char *msgStr, SlaveVP *reqstSlv, PRExcp *excpData );
489 #define PR_App__throw_exception PR_WL__throw_exception
491 inline
492 void *
493 PR_int__give_sem_env_for_slave( SlaveVP *slave, int32 magicNumber );
494 #define PR_PI__give_sem_env_for PR_int__give_sem_env_for_slave
495 #define PR_SS__give_sem_env_for_slave PR_int__give_sem_env_for_slave
496 //No WL version -- not safe! if use env in WL, be sure data rd & wr is stable
497 inline
498 PRSemEnv *
499 PR_int__give_proto_sem_env_for_slave( SlaveVP *slave, int32 magicNumber );
500 #define PR_PI__give_proto_sem_env_for PR_int__give_proto_sem_env_for_slave
501 #define PR_SS__give_proto_sem_env_for_slave PR_int__give_proto_sem_env_for_slave
502 //No WL version -- not safe! if use env in WL, be sure data rd & wr is stable
503 inline
504 void *
505 PR_int__give_sem_env_from_process( PRProcess *process, int32 magicNumer );
506 #define PR_PI__give_sem_env_from_process PR_int__give_sem_env_from_process
507 #define PR_SS__give_sem_env_from_process PR_int__give_sem_env_from_process
508 //#define PR_WL__give_sem_env_from_process PR_int__give_sem_env_from_process
509 //No WL version -- not safe! if use env in WL, be sure data rd & wr is stable
511 inline
512 void *
513 PR_int__give_sem_data( SlaveVP *slave, int32 magicNumer );
514 #define PR_PI__give_sem_data PR_int__give_sem_data
515 #define PR_SS__give_sem_data PR_int__give_sem_data
516 #define PR_WL__give_sem_data PR_int__give_sem_data
519 #define PR_int__give_lang_meta_task( slave, magicNumber )\
520 slave->metaTask->langMetaTask;
521 #define PR_PI__give_lang_meta_task PR_int__give_lang_meta_task
522 #define PR_SS__give_lang_meta_task PR_int__give_lang_meta_task
523 #define PR_WL__give_lang_meta_task PR_int__give_lang_meta_task
525 inline
526 SlaveVP *
527 PR_PI__give_slave_assigned_to( PRLangMetaTask *langMetaTask );
529 void
530 idle_fn(void* data, SlaveVP *animatingSlv);
532 inline void
533 PR_int__get_master_lock();
535 #define PR_int__release_master_lock() _PRTopEnv->masterLock = UNLOCKED
537 inline uint32_t
538 PR_int__randomNumber();
540 //============== Request Related ===============
542 void
543 PR_WL__suspend_slaveVP_and_send_req( SlaveVP *callingSlv );
545 inline void
546 PR_WL__add_sem_request_in_mallocd_PRReqst( void *semReqData, SlaveVP *callingSlv );
548 inline void
549 PR_WL__send_sem_request( void *semReq, SlaveVP *callingSlv, int32 magicNum );
551 void
552 PR_WL__send_create_slaveVP_req( void *semReqData, SlaveVP *reqstingSlv );
554 void inline
555 PR_WL__send_dissipate_req( SlaveVP *prToDissipate );
557 inline void
558 PR_WL__send_service_request( void *semReqData, SlaveVP *callingSlv );
560 PRReqst *
561 PR_PI__take_next_request_out_of( SlaveVP *slaveWithReq );
562 //#define PR_PI__take_next_request_out_of( slave ) slave->requests
564 //inline void *
565 //PR_PI__take_sem_reqst_from( PRReqst *req );
566 #define PR_PI__take_sem_reqst_from( req ) req->semReqData
568 void inline
569 PR_int__handle_PRServiceReq( PRReqst *req, SlaveVP *requestingSlv, void *semEnv,
570 ResumeSlvFnPtr resumeSlvFnPtr );
572 //======================== MEASUREMENT ======================
573 uint64
574 PR_WL__give_num_plugin_cycles();
575 uint32
576 PR_WL__give_num_plugin_animations();
579 //========================= Utilities =======================
580 inline char *
581 PR_int__strDup( char *str );
584 //========================= PR request handlers ========================
585 void inline
586 handleMakeProbe( PRServReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn );
588 void inline
589 handleThrowException( PRServReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn );
590 //=======================================================================
592 //========================= Probes =======================
593 #include "Services_Offered_by_PR/Measurement_and_Stats/probes.h"
595 //================================================
596 #endif /* _PR_H */
