comparison PR.h @ 268:e5bd470b562b

Checkpoint 2 -- split up header file, and about to delete single lang version of AnimationMaster
author Sean Halle <seanhalle@yahoo.com>
date Mon, 14 Jan 2013 15:31:23 -0800
parents 608833ae2c5d
children 292393c6bef1
comparison
equal deleted inserted replaced
3:9841b0a45663 4:a28472c9c9d4
1 /* 1 /*
2 * Copyright 2009 OpenSourceStewardshipFoundation.org 2 * Copyright 2009 OpenSourceResearchInstitute.org
3 * Licensed under GNU General Public License version 2 3 * Licensed under GNU General Public License version 2
4 * 4 *
5 * Author: seanhalle@yahoo.com 5 * Author: seanhalle@yahoo.com
6 * 6 *
7 */ 7 */
28 #include "Defines/PR_defs.h" 28 #include "Defines/PR_defs.h"
29 29
30 30
31 //================================ Typedefs ================================= 31 //================================ Typedefs =================================
32 // 32 //
33 typedef unsigned long long TSCount; 33 #include "PR__structs.h"
34
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;
41
42
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 //========================================
52 34
53 //============================ HW Dependent Fns ================================ 35 //============================ HW Dependent Fns ================================
54 36
55 #include "HW_Dependent_Primitives/PR__HW_measurement.h" 37 #include "HW_Dependent_Primitives/PR__HW_measurement.h"
56 #include "HW_Dependent_Primitives/PR__primitives.h" 38 #include "HW_Dependent_Primitives/PR__primitives.h"
57 39
58 40
59 //============= Request Related ===========
60 //
61
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 };
74
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;
84
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
89
90 PRReqst *nextReqst;
91 };
92 //PRReqst
93
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 };
101
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;
110
111
112 //==================== Core data structures ===================
113
114 typedef struct
115 {
116 //for future expansion
117 }
118 SlotPerfInfo;
119
120 struct _AnimSlot
121 {
122 int workIsDone;
123 int needsWorkAssigned;
124 SlaveVP *slaveAssignedToSlot;
125
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
131
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 };
140
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
151
152 //============ below this, no fields are used in asm =============
153
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
163
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
168
169 //For language specific data that needs to be in the slave
170 void *semanticData; //Lang saves lang-specific things in slave here
171
172 //Task related stuff
173 // bool needsTaskAssigned;
174
175 //=========== MEASUREMENT STUFF ==========
176 MEAS__Insert_Meas_Fields_into_Slave;
177 float64 createPtInSecs; //time VP created, in seconds
178 //========================================
179 };
180 //SlaveVP
181
182
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 =============
192
193 //Basic PR infrastructure
194 SlaveVP **masterVPs;
195 AnimSlot ***allAnimSlots;
196
197 PRProcess **processes;
198
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
202
203 //Initialization related
204 int32 setupComplete; //use while starting up coreCtlr
205
206 //Memory management related
207 MallocArrays *freeLists;
208 int32 amtOfOutstandingMem;//total currently allocated
209
210 //Random number seeds -- random nums used in various places
211 uint32_t seed1;
212 uint32_t seed2;
213
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;
220
221 // SlaveVP* idleSlv[NUM_CORES][NUM_ANIM_SLOTS];
222 // int shutdownInitiated;
223
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;
242
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;
248
249 SlaveAssigner slaveAssigner;
250 RequestHandler requestHdlr;
251
252 RequestHandler createTaskHdlr;
253 RequestHandler endTaskHdlr;
254 RequestHandler createSlaveHdlr;
255 RequestHandler dissipateSlaveHdlr;
256 RequestHandler semDataCreator;
257 RequestHandler semDataInitializer;
258
259
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
263
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;
269
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;
277
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;
284
285 enum PRTaskType
286 { GenericSlave = 1,
287 SlotTask,
288 FreeTask
289 };
290
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;
300
301 //NOTE: info needed for "wait" functionality is inside lang's metaTask
302 };
303 //PRMetaTask
304
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;
314
315 typedef struct
316 {
317 void (*freeFn)(void *);
318 }
319 PRSemDataTemplate;
320
321 typedef struct
322 {
323 void (*recycler)(void *);
324 void *langSemData;
325 }
326 PRSemData;
327
328 typedef struct
329 { PRSemDataTemplate **semDatas;
330 PRSemDataTemplate **semDatasIter;
331 int32 numSemDatas;
332 }
333 PRSemDataHolder;
334 //===================== Top Process level Data Strucs ======================
335
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
345
346 int32 numLiveGenericSlvs;
347 int32 numLiveFreeTaskSlvs;
348 int32 numLiveTasks;
349 // bool32 coreIsDone[NUM_CORES][CACHE_LINE_SZ]; //Fixes false sharing
350
351 PrivQueueStruc *freeTaskSlvRecycleQ;
352 SlaveVP slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS];
353 void *resultToReturn;
354
355 SlaveVP *seedSlv;
356
357 SlaveAssigner overrideAssigner;
358
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;
365
366
367 //========================= Extra Stuff Data Strucs =======================
368 typedef struct
369 {
370
371 }
372 PRExcp; //exception
373
374 //======================= OS Thread related ===============================
375
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 );
379
380
381 typedef struct
382 {
383 void *endThdPt;
384 unsigned int coreNum;
385 }
386 ThdParams;
387
388 //============================= Global Vars ================================ 41 //============================= Global Vars ================================
389 42
390 volatile MasterEnv *_PRTopEnv __align_to_cacheline__; 43 volatile TopEnv *_PRTopEnv __align_to_cacheline__;
391 44
392 //these are global, but only used for startup and shutdown 45 //these are global, but only used for startup and shutdown
393 pthread_t coreCtlrThdHandles[ NUM_CORES ]; //pthread's virt-procr state 46 pthread_t coreCtlrThdHandles[ NUM_CORES ]; //pthread's virt-procr state
394 ThdParams *coreCtlrThdParams [ NUM_CORES ]; 47 ThdParams *coreCtlrThdParams [ NUM_CORES ];
395 48
401 * These indicate which places the function is safe to use. They stand for: 54 * These indicate which places the function is safe to use. They stand for:
402 * 55 *
403 * WL Wrapper Library -- wrapper lib code should only use these 56 * WL Wrapper Library -- wrapper lib code should only use these
404 * PI Plugin -- plugin code should only use these 57 * PI Plugin -- plugin code should only use these
405 * SS Startup and Shutdown -- designates these relate to startup & shutdown 58 * SS Startup and Shutdown -- designates these relate to startup & shutdown
406 * int internal to PR -- should not be used in wrapper lib or plugin 59 * int32internal to PR -- should not be used in wrapper lib or plugin
407 * PROS means "OS functions for applications to use" 60 * PROS means "OS functions for applications to use"
408 * 61 *
409 * PR_int__ functions touch internal PR data structs and are only safe 62 * PR_int__ functions touch internal PR data structs and are only safe
410 * to be used inside the master lock. However, occasionally, they appear 63 * to be used inside the master lock. However, occasionally, they appear
411 * in wrapper-lib or plugin code. In those cases, very careful analysis 64 * in wrapper-lib or plugin code. In those cases, very careful analysis
412 * has been done to be sure no concurrency issues could arise. 65 * has been done to be sure no concurrency issues could arise.
413 * 66 *
414 * PR_WL__ functions are all safe for use outside the master lock. 67 * PR_WL__ functions are all safe for use outside the master lock.
415 * 68 *
416 * PROS are only safe for applications to use -- they're like a second 69 * PR_OS 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 70 * 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 71 * aren't meant for use in wrapper libraries, because they are themselves
419 * wrapper-library calls! 72 * wrapper-library calls!
420 */ 73 */
421 //========== Startup and shutdown ==========
422 void
423 PR__start();
424 74
425 SlaveVP* 75 //============== include internally used fn prototypes ================
426 PR_SS__create_shutdown_slave();
427 76
428 void 77 //include fn prototypes used internally in the proto-runtime implementation
429 PR_SS__shutdown(); 78 #include "PR__int.h"
430 79
431 void 80 //include fn prototypes used by plugin
432 PR_SS__cleanup_at_end_of_shutdown(); 81 #include "PR__PI.h"
433 82
434 void 83 //include fn prototype used by wrapper library
435 PR_SS__register_langlets_semEnv( PRSemEnv *semEnv, SlaveVP *seedVP, int32 VSs_MAGIC_NUMBER ); 84 #include "PR__WL.h"
85
86 //=================================
87 #define implement_me printf("Unimpl Fn: \n%s \n%s : %s\n", __FILE__, __FUNCTION__, __LINE__)
88 //#define fix_me printf("Fix me at: \n%s \n%s : %s\n", __FILE__, __FUNCTION__, __LINE__)
436 89
437 90
438 //============== =============== 91 //========================= Services =======================
439 92 //#include "Services_Offered_by_PR/Measurement_and_Stats/probes.h"
440 inline SlaveVP * 93 //#include "Services_Offered_by_PR/Services_Language/PRServ.h"
441 PR_int__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam ); 94 //#include "Services_Offered_by_PR/Services_Language/libPRServ.h"
442 #define PR_PI__create_slaveVP PR_int__create_slaveVP
443 #define PR_WL__create_slaveVP PR_int__create_slaveVP
444
445 inline
446 SlaveVP *
447 PR_int__create_slot_slave();
448
449 inline
450 SlaveVP *
451 PR_int__create_slaveVP_helper( SlaveVP *newSlv, TopLevelFnPtr fnPtr,
452 void *dataParam, void *stackLocs );
453
454 inline
455 PRMetaTask *
456 PR_int__create_generic_slave_meta_task( void *initData );
457
458 inline
459 void
460 PR_int__reset_slaveVP_to_TopLvlFn( SlaveVP *slaveVP, TopLevelFnPtr fnPtr,
461 void *dataParam);
462
463 inline
464 void
465 PR_int__point_slaveVP_to_OneParamFn( SlaveVP *slaveVP, void *fnPtr,
466 void *param);
467
468 inline
469 void
470 PR_int__point_slaveVP_to_TwoParamFn( SlaveVP *slaveVP, void *fnPtr,
471 void *param1, void *param2);
472
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
478
479 inline
480 void
481 PR_int__dissipate_slaveVP_multilang( SlaveVP *slaveToDissipate );
482
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
490
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
510
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
517
518
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
524
525 inline
526 SlaveVP *
527 PR_PI__give_slave_assigned_to( PRLangMetaTask *langMetaTask );
528
529 void
530 idle_fn(void* data, SlaveVP *animatingSlv);
531
532 inline void
533 PR_int__get_master_lock();
534
535 #define PR_int__release_master_lock() _PRTopEnv->masterLock = UNLOCKED
536
537 inline uint32_t
538 PR_int__randomNumber();
539
540 //============== Request Related ===============
541
542 void
543 PR_WL__suspend_slaveVP_and_send_req( SlaveVP *callingSlv );
544
545 inline void
546 PR_WL__add_sem_request_in_mallocd_PRReqst( void *semReqData, SlaveVP *callingSlv );
547
548 inline void
549 PR_WL__send_sem_request( void *semReq, SlaveVP *callingSlv, int32 magicNum );
550
551 void
552 PR_WL__send_create_slaveVP_req( void *semReqData, SlaveVP *reqstingSlv );
553
554 void inline
555 PR_WL__send_dissipate_req( SlaveVP *prToDissipate );
556
557 inline void
558 PR_WL__send_service_request( void *semReqData, SlaveVP *callingSlv );
559
560 PRReqst *
561 PR_PI__take_next_request_out_of( SlaveVP *slaveWithReq );
562 //#define PR_PI__take_next_request_out_of( slave ) slave->requests
563
564 //inline void *
565 //PR_PI__take_sem_reqst_from( PRReqst *req );
566 #define PR_PI__take_sem_reqst_from( req ) req->semReqData
567
568 void inline
569 PR_int__handle_PRServiceReq( PRReqst *req, SlaveVP *requestingSlv, void *semEnv,
570 ResumeSlvFnPtr resumeSlvFnPtr );
571
572 //======================== MEASUREMENT ======================
573 uint64
574 PR_WL__give_num_plugin_cycles();
575 uint32
576 PR_WL__give_num_plugin_animations();
577
578
579 //========================= Utilities =======================
580 inline char *
581 PR_int__strDup( char *str );
582
583
584 //========================= PR request handlers ========================
585 void inline
586 handleMakeProbe( PRServReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn );
587
588 void inline
589 handleThrowException( PRServReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn );
590 //=======================================================================
591
592 //========================= Probes =======================
593 #include "Services_Offered_by_PR/Measurement_and_Stats/probes.h"
594 95
595 //================================================ 96 //================================================
596 #endif /* _PR_H */ 97 #endif /* _PR_H */
597 98