view 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 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 PRMetaTask *metaTask;
82 TopLevelFn topLevelFn;
83 void *initData;
84 int32 *ID;
86 //The request handling structure is a bit messy.. for special forms,
87 // such as create and dissipate, the language inserts pointer to handler
88 // fn directly into the request.. might change to this for all requests
89 IndivReqHandler handler; //pointer to handler fn for create, dissip, etc
91 PRReqst *nextReqst;
92 };
93 //PRReqst
95 enum PRServReqType //These are equivalent to semantic requests, but for
96 { // PR's services available directly to app, like OS
97 make_probe = 1, // and probe services -- like a PR-wide built-in lang
98 throw_excp,
99 openFile,
100 otherIO
101 };
103 typedef struct
104 { enum PRServReqType reqType;
105 SlaveVP *requestingSlv;
106 char *nameStr; //for create probe
107 char *msgStr; //for exception
108 void *exceptionData;
109 }
110 PRServReq;
113 //==================== Core data structures ===================
115 typedef struct
116 {
117 //for future expansion
118 }
119 SlotPerfInfo;
121 struct _AnimSlot
122 {
123 int workIsDone;
124 int needsSlaveAssigned;
125 SlaveVP *slaveAssignedToSlot;
127 int slotIdx; //needed by Holistic Model's data gathering
128 int coreSlotIsOn;
129 SlotPerfInfo *perfInfo; //used by assigner to pick best slave for core
130 };
131 //AnimSlot
133 enum VPtype
134 { TaskSlotSlv = 1,//Slave tied to an anim slot, only animates tasks
135 TaskFreeSlv, //When a suspended task ends, the slave becomes this
136 GenericSlv, //the VP is explicitly seen in the app code, or task suspends
137 Master,
138 Shutdown,
139 Idle
140 };
142 /*This structure embodies the state of a slaveVP. It is reused for masterVP
143 * and shutdownVPs.
144 */
145 struct _SlaveVP
146 { //The offsets of these fields are hard-coded into assembly
147 void *stackPtr; //save the core's stack ptr when suspend
148 void *framePtr; //save core's frame ptr when suspend
149 void *resumeInstrPtr; //save core's program-counter when suspend
150 void *coreCtlrFramePtr; //restore before jmp back to core controller
151 void *coreCtlrStackPtr; //restore before jmp back to core controller
153 //============ below this, no fields are used in asm =============
155 void *startOfStack; //used to free, and to point slave to Fn
156 PRProcess *processSlaveIsIn;
157 PRMetaTask *metaTask;
158 enum VPtype typeOfVP; //Slave vs Master vs Shutdown..
159 int slaveID; //each slave given a globally unique ID
160 int coreAnimatedBy;
161 int numTimesAssignedToASlot; //Each assign is for one work-unit, so is an ID
162 //note, a scheduling decision is uniquely identified by the triple:
163 // <slaveID, coreAnimatedBy, numTimesAssignedToASlot> -- used in record & replay
165 //for comm -- between master and coreCtlr & btwn wrapper lib and plugin
166 AnimSlot *animSlotAssignedTo;
167 PRReqst *request; //wrapper lib puts in requests, plugin takes out
168 void *dataRetFromReq;//Return vals from plugin to Wrapper Lib
170 //For language specific data that needs to be in the slave
171 void *semanticData; //Lang saves lang-specific things in slave here
173 //Task related stuff
174 bool needsTaskAssigned;
176 //=========== MEASUREMENT STUFF ==========
177 MEAS__Insert_Meas_Fields_into_Slave;
178 float64 createPtInSecs; //time VP created, in seconds
179 //========================================
180 };
181 //SlaveVP
184 /* The one and only global variable, holds many odds and ends
185 */
186 typedef struct
187 { //The offsets of these fields are hard-coded into assembly
188 void *coreCtlrReturnPt; //offset to this field used in asm
189 int8 falseSharePad1[256 - sizeof(void*)];
190 int32 masterLock; //offset to this field used in asm
191 int8 falseSharePad2[256 - sizeof(int32)];
192 //============ below this, no fields are used in asm =============
194 //Basic PR infrastructure
195 SlaveVP **masterVPs;
196 AnimSlot ***allAnimSlots;
198 PRProcess **processes;
200 //move to processEnv //Slave creation -- global count of slaves existing, across langs and processes
201 int32 numSlavesCreated; //used to give unique ID to processor
202 int32 numTasksCreated; //to give unique ID to a task
204 //Initialization related
205 int32 setupComplete; //use while starting up coreCtlr
207 //Memory management related
208 MallocArrays *freeLists;
209 int32 amtOfOutstandingMem;//total currently allocated
211 //Random number seeds -- random nums used in various places
212 uint32_t seed1;
213 uint32_t seed2;
215 These_Prob_belong_in_PRPRocess;
216 // SlaveVP *slotTaskSlvs[NUM_CORES][NUM_ANIM_SLOTS];
217 // int32 numLiveFreeTaskSlvs;
218 // int32 numLiveThreadSlvs;
219 // bool32 *coreIsDone;
220 // int32 numCoresDone;
222 // SlaveVP* idleSlv[NUM_CORES][NUM_ANIM_SLOTS];
223 // int shutdownInitiated;
225 //=========== MEASUREMENT STUFF =============
226 IntervalProbe **intervalProbes;
227 PrivDynArrayInfo *dynIntervalProbesInfo;
228 HashTable *probeNameHashTbl;
229 int32 masterCreateProbeID;
230 float64 createPtInSecs; //real-clock time PR initialized
231 Histogram **measHists;
232 PrivDynArrayInfo *measHistsInfo;
233 MEAS__Insert_Susp_Meas_Fields_into_MasterEnv;
234 MEAS__Insert_Master_Meas_Fields_into_MasterEnv;
235 MEAS__Insert_Master_Lock_Meas_Fields_into_MasterEnv;
236 MEAS__Insert_Malloc_Meas_Fields_into_MasterEnv;
237 MEAS__Insert_Plugin_Meas_Fields_into_MasterEnv;
238 MEAS__Insert_System_Meas_Fields_into_MasterEnv;
239 MEAS__Insert_Counter_Meas_Fields_into_MasterEnv;
240 //==========================================
241 }
242 MasterEnv;
244 //=====================
245 typedef struct
246 { int32 langMagicNumber; //indexes into hash array of semEnvs in PRProcess
247 PRSemEnv *chainedSemEnv; //chains to semEnvs with same hash
248 void *langSemEnv;
250 SlaveAssigner slaveAssigner;
251 RequestHandler requestHdlr;
253 RequestHandler createTaskHdlr;
254 RequestHandler endTaskHdlr;
255 RequestHandler createSlaveHdlr;
256 RequestHandler dissipateSlaveHdlr;
257 RequestHandler semDataCreator;
258 RequestHandler semDataInitializer;
261 //Track slaves created, separately for each langlet? (in each process)
262 // int32 numSlavesCreated; //gives ordering to processor creation
263 // int32 numSlavesAlive; //used to detect fail-safe shutdown
265 //when multi-lang, master polls sem env's to find one with work in it..
266 // in single-lang case, flag ignored, master always asks lang for work
267 int32 hasWork;
268 }
269 PRSemEnv;
271 //The semantic env of every langlet must start with these two fields, so that
272 // PR can cast the void * to this struct, in order to access these two fields
273 typedef struct
274 { int32 langMagicNumber;
275 PRSemEnv *protoSemEnv;
276 }
277 PRLangSemEnv;
279 //can cast any langlet's sem env to one of these, so PR can access values
280 typedef struct
281 { int32 langMagicNumber;
282 PRSemEnv *protoSemEnv;
283 }
284 PRServSemEnv;
286 enum PRTaskType
287 { GenericSlave = 1,
288 AtomicTask,
289 SuspendedTask
290 };
292 struct _PRMetaTask
293 {
294 PRTaskType taskType;
295 RequestHandler reqHandler; //Lang-specific hdlr for create, end, etc
296 int32 *taskID; //is standard PR ID
297 SlaveVP *slaveAssignedTo; //no valid until task animated
298 TopLevelFn topLevelFn; //This is the Fn executes as the task
299 void *initData; //The data taken by the function
300 void *langMetaTask;
302 //NOTE: info needed for "wait" functionality is inside lang's metaTask
303 };
304 //PRMetaTask
306 /*The language's meta task is cast to this struct, inside PR, then the
307 * back pointer to protoMetaTask is set. Keeps existence of PRMetaTask hidden
308 * from plugin -- so can change later.
309 */
310 typedef struct
311 { int32 langMagicNumber;
312 PRMetaTask *protoMetaTask;
313 }
314 PRLangMetaTask;
316 typedef struct
317 {
318 void (*freeFn)(void *);
319 }
320 PRSemDataTemplate;
322 typedef struct
323 { PRSemDataTemplate **semDatas;
324 PRSemDataTemplate **semDatasIter;
325 int32 numSemDatas;
326 }
327 PRSemDataHolder;
328 //===================== Top Process level Data Strucs ======================
330 /*This structure holds all the information PR needs to manage a program. PR
331 * stores information about what percent of CPU time the program is getting,
332 *
333 */
334 typedef struct
335 {
336 PRSemEnv semEnvs[NUM_SEM_ENVS_IN_PROCESS]; //used as a hash table
337 PRSemEnv semEnvList[NUM_SEM_ENVS_IN_PROCESS]; //lines up the semEnvs, so can iterate through
338 int32 numSemEnvs; //must be less than num sem envs.. used to iterate through
340 int32 numLiveGenericSlaves;
341 int32 numLiveFreeTaskSlaves;
342 int32 numLiveTasks;
343 bool32 coreIsDone[NUM_CORES][CACHE_LINE_SZ]; //Fixes false sharing
345 void *resultToReturn;
347 SlaveVP *seedSlv;
349 //These are used to coord with OS thread waiting for process to end
350 bool32 executionIsComplete;
351 pthread_mutex_t doneLock;
352 pthread_cond_t doneCond;
353 }
354 PRProcess;
357 //========================= Extra Stuff Data Strucs =======================
358 typedef struct
359 {
361 }
362 PRExcp; //exception
364 //======================= OS Thread related ===============================
366 void * coreController( void *paramsIn ); //standard PThreads fn prototype
367 void * coreCtlr_Seq( void *paramsIn ); //standard PThreads fn prototype
368 void animationMaster( void *initData, SlaveVP *masterVP );
371 typedef struct
372 {
373 void *endThdPt;
374 unsigned int coreNum;
375 }
376 ThdParams;
378 //============================= Global Vars ================================
380 volatile MasterEnv *_PRTopEnv __align_to_cacheline__;
382 //these are global, but only used for startup and shutdown
383 pthread_t coreCtlrThdHandles[ NUM_CORES ]; //pthread's virt-procr state
384 ThdParams *coreCtlrThdParams [ NUM_CORES ];
386 pthread_mutex_t suspendLock;
387 pthread_cond_t suspendCond;
389 //========================= Function Prototypes ===========================
390 /* MEANING OF WL PI SS int PROS
391 * These indicate which places the function is safe to use. They stand for:
392 *
393 * WL Wrapper Library -- wrapper lib code should only use these
394 * PI Plugin -- plugin code should only use these
395 * SS Startup and Shutdown -- designates these relate to startup & shutdown
396 * int internal to PR -- should not be used in wrapper lib or plugin
397 * PROS means "OS functions for applications to use"
398 *
399 * PR_int__ functions touch internal PR data structs and are only safe
400 * to be used inside the master lock. However, occasionally, they appear
401 * in wrapper-lib or plugin code. In those cases, very careful analysis
402 * has been done to be sure no concurrency issues could arise.
403 *
404 * PR_WL__ functions are all safe for use outside the master lock.
405 *
406 * PROS are only safe for applications to use -- they're like a second
407 * language mixed in -- but they can't be used inside plugin code, and
408 * aren't meant for use in wrapper libraries, because they are themselves
409 * wrapper-library calls!
410 */
411 //========== Startup and shutdown ==========
412 void
413 PR__start();
415 SlaveVP*
416 PR_SS__create_shutdown_slave();
418 void
419 PR_SS__shutdown();
421 void
422 PR_SS__cleanup_at_end_of_shutdown();
424 void
425 PR_SS__register_langlets_semEnv( PRSemEnv *semEnv, SlaveVP *seedVP, int32 VSs_MAGIC_NUMBER );
428 //============== ===============
430 inline SlaveVP *
431 PR_int__create_slaveVP( TopLevelFnPtr fnPtr, void *dataParam );
432 #define PR_PI__create_slaveVP PR_int__create_slaveVP
433 #define PR_WL__create_slaveVP PR_int__create_slaveVP
435 inline
436 SlaveVP *
437 PR_int__create_slot_slave();
439 inline
440 SlaveVP *
441 PR_int__create_slaveVP_helper( SlaveVP *newSlv, TopLevelFnPtr fnPtr,
442 void *dataParam, void *stackLocs );
444 inline
445 PRMetaTask *
446 PR_int__create_generic_slave_meta_task( void *initData );
448 inline
449 void
450 PR_int__reset_slaveVP_to_TopLvlFn( SlaveVP *slaveVP, TopLevelFnPtr fnPtr,
451 void *dataParam);
453 inline
454 void
455 PR_int__point_slaveVP_to_OneParamFn( SlaveVP *slaveVP, void *fnPtr,
456 void *param);
458 inline
459 void
460 PR_int__point_slaveVP_to_TwoParamFn( SlaveVP *slaveVP, void *fnPtr,
461 void *param1, void *param2);
463 inline
464 void
465 PR_int__dissipate_slaveVP( SlaveVP *slaveToDissipate );
466 #define PR_PI__dissipate_slaveVP PR_int__dissipate_slaveVP
467 //WL: dissipate a SlaveVP by sending a request
469 inline
470 void
471 PR_int__dissipate_slaveVP_multilang( SlaveVP *slaveToDissipate );
473 inline
474 void
475 PR_int__throw_exception( char *msgStr, SlaveVP *reqstSlv, PRExcp *excpData );
476 #define PR_PI__throw_exception PR_int__throw_exception
477 void
478 PR_WL__throw_exception( char *msgStr, SlaveVP *reqstSlv, PRExcp *excpData );
479 #define PR_App__throw_exception PR_WL__throw_exception
481 inline
482 void *
483 PR_int__give_sem_env_for_slave( SlaveVP *slave, int32 magicNumber );
484 #define PR_PI__give_sem_env_for PR_int__give_sem_env_for_slave
485 #define PR_SS__give_sem_env_for_slave PR_int__give_sem_env_for_slave
486 //No WL version -- not safe! if use env in WL, be sure data rd & wr is stable
487 inline
488 PRSemEnv *
489 PR_int__give_proto_sem_env_for_slave( SlaveVP *slave, int32 magicNumber );
490 #define PR_PI__give_proto_sem_env_for PR_int__give_proto_sem_env_for_slave
491 #define PR_SS__give_proto_sem_env_for_slave PR_int__give_proto_sem_env_for_slave
492 //No WL version -- not safe! if use env in WL, be sure data rd & wr is stable
493 inline
494 void *
495 PR_int__give_sem_env_from_process( PRProcess *process, int32 magicNumer );
496 #define PR_PI__give_sem_env_from_process PR_int__give_sem_env_from_process
497 #define PR_SS__give_sem_env_from_process PR_int__give_sem_env_from_process
498 //#define PR_WL__give_sem_env_from_process PR_int__give_sem_env_from_process
499 //No WL version -- not safe! if use env in WL, be sure data rd & wr is stable
501 inline
502 void *
503 PR_int__give_sem_data( SlaveVP *slave, int32 magicNumer );
504 #define PR_PI__give_sem_data PR_int__give_sem_data
505 #define PR_SS__give_sem_data PR_int__give_sem_data
506 #define PR_WL__give_sem_data PR_int__give_sem_data
509 #define PR_int__give_lang_meta_task( slave, magicNumber )\
510 slave->metaTask->langMetaTask;
511 #define PR_PI__give_lang_meta_task PR_int__give_lang_meta_task
512 #define PR_SS__give_lang_meta_task PR_int__give_lang_meta_task
513 #define PR_WL__give_lang_meta_task PR_int__give_lang_meta_task
515 inline
516 SlaveVP *
517 PR_PI__give_slave_assigned_to( PRLangMetaTask *langMetaTask );
519 void
520 idle_fn(void* data, SlaveVP *animatingSlv);
522 inline void
523 PR_int__get_master_lock();
525 #define PR_int__release_master_lock() _PRTopEnv->masterLock = UNLOCKED
527 inline uint32_t
528 PR_int__randomNumber();
530 //============== Request Related ===============
532 void
533 PR_WL__suspend_slaveVP_and_send_req( SlaveVP *callingSlv );
535 inline void
536 PR_WL__add_sem_request_in_mallocd_PRReqst( void *semReqData, SlaveVP *callingSlv );
538 inline void
539 PR_WL__send_sem_request( void *semReq, SlaveVP *callingSlv, int32 magicNum );
541 void
542 PR_WL__send_create_slaveVP_req( void *semReqData, SlaveVP *reqstingSlv );
544 void inline
545 PR_WL__send_dissipate_req( SlaveVP *prToDissipate );
547 inline void
548 PR_WL__send_service_request( void *semReqData, SlaveVP *callingSlv );
550 PRReqst *
551 PR_PI__take_next_request_out_of( SlaveVP *slaveWithReq );
552 //#define PR_PI__take_next_request_out_of( slave ) slave->requests
554 //inline void *
555 //PR_PI__take_sem_reqst_from( PRReqst *req );
556 #define PR_PI__take_sem_reqst_from( req ) req->semReqData
558 void inline
559 PR_int__handle_PRServiceReq( PRReqst *req, SlaveVP *requestingSlv, void *semEnv,
560 ResumeSlvFnPtr resumeSlvFnPtr );
562 //======================== MEASUREMENT ======================
563 uint64
564 PR_WL__give_num_plugin_cycles();
565 uint32
566 PR_WL__give_num_plugin_animations();
569 //========================= Utilities =======================
570 inline char *
571 PR_int__strDup( char *str );
574 //========================= PR request handlers ========================
575 void inline
576 handleMakeProbe( PRServReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn );
578 void inline
579 handleThrowException( PRServReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn );
580 //=======================================================================
582 //========================= Probes =======================
583 #include "Services_Offered_by_PR/Measurement_and_Stats/probes.h"
585 //================================================
586 #endif /* _PR_H */