view VMS.h @ 157:8cc3d3812c8a

smaller Hists for malloc, free and plugin
author Merten Sach <msach@mailbox.tu-berlin.de>
date Thu, 06 Oct 2011 15:58:34 +0200
parents 99343ffe1918
children c4d8060229ef
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 */
8 #ifndef _VMS_H
9 #define _VMS_H
10 #define _GNU_SOURCE
12 #include <pthread.h>
13 #include <sys/time.h>
15 #include "VMS_primitive_data_types.h"
16 #include "Queue_impl/PrivateQueue.h"
17 #include "Histogram/Histogram.h"
18 #include "DynArray/DynArray.h"
19 #include "Hash_impl/PrivateHash.h"
20 #include "vmalloc.h"
21 #include "inter_VMS_requests.h"
23 //=============================== Debug ===================================
24 //
25 //When SEQUENTIAL is defined, VMS does sequential exe in the main thread
26 // It still does co-routines and all the mechanisms are the same, it just
27 // has only a single thread and animates VPs one at a time
28 //#define SEQUENTIAL
30 //#define USE_WORK_STEALING
32 //turns on the probe-instrumentation in the application -- when not
33 // defined, the calls to the probe functions turn into comments
34 #define STATS__ENABLE_PROBES
35 //#define TURN_ON_DEBUG_PROBES
37 //These defines turn types of bug messages on and off
38 // be sure debug messages are un-commented (next block of defines)
39 #define dbgAppFlow TRUE /* Top level flow of application code -- general*/
40 #define dbgProbes FALSE /* for issues inside probes themselves*/
41 #define dbgB2BMaster FALSE /* in coreloop, back to back master VPs*/
42 #define dbgRqstHdlr FALSE /* in request handler code*/
44 //Comment or un- the substitute half to turn on/off types of debug message
45 #define DEBUG( bool, msg) \
46 // if( bool){ printf(msg); fflush(stdin);}
47 #define DEBUG1( bool, msg, param) \
48 // if(bool){printf(msg, param); fflush(stdin);}
49 #define DEBUG2( bool, msg, p1, p2) \
50 // if(bool) {printf(msg, p1, p2); fflush(stdin);}
52 #define ERROR(msg) printf(msg)
53 #define ERROR1(msg, param) printf(msg, param);
54 #define ERROR2(msg, p1, p2) printf(msg, p1, p2)
56 //=========================== STATS =======================
58 //when MEAS__TIME_STAMP_SUSP is defined, causes code to be inserted and
59 // compiled-in that saves the low part of the time stamp count just before
60 // suspending a processor and just after resuming that processorsrc/VPThread_lib/VMS/VMS.h:322: warning: previous declaration of ‘VMS__create_procr’ was here. It is
61 // saved into a field added to VirtProcr. Have to sanity-check for
62 // rollover of low portion into high portion.
63 //#define MEAS__TIME_STAMP_SUSP
64 //#define MEAS__TIME_MASTER
65 #define MEAS__TIME_PLUGIN
66 #define MEAS__TIME_MALLOC
67 //#define MEAS__TIME_MASTER_LOCK
68 #define MEAS__NUM_TIMES_TO_RUN 100000
70 //For code that calculates normalization-offset between TSC counts of
71 // different cores.
72 #define NUM_TSC_ROUND_TRIPS 10
75 //========================= Hardware related Constants =====================
76 //This value is the number of hardware threads in the shared memory
77 // machine
78 //#define NUM_CORES 8
80 // tradeoff amortizing master fixed overhead vs imbalance potential
81 // when work-stealing, can make bigger, at risk of losing cache affinity
82 #define NUM_SCHED_SLOTS 5
84 #define MIN_WORK_UNIT_CYCLES 20000
86 #define MASTERLOCK_RETRIES 10000
88 // stack size in virtual processors created
89 #define VIRT_PROCR_STACK_SIZE 0x8000 /* 32K */
91 // memory for VMS__malloc
92 #define MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE 0x4000000 /* 64M */
94 #define CACHE_LINE 64
95 #define PAGE_SIZE 4096
98 //==============================
100 #define SUCCESS 0
102 #define writeVMSQ writePrivQ
103 #define readVMSQ readPrivQ
104 #define makeVMSQ makeVMSPrivQ
105 #define numInVMSQ numInPrivQ
106 #define VMSQueueStruc PrivQueueStruc
110 //===========================================================================
111 typedef unsigned long long TSCount;
113 typedef struct _IntervalProbe IntervalProbe;
114 typedef struct _GateStruc GateStruc;
117 typedef VirtProcr * (*SlaveScheduler) ( void *, int ); //semEnv, coreIdx
118 typedef void (*RequestHandler) ( VirtProcr *, void * ); //prWReqst, semEnv
119 typedef void (*ResumePrFnPtr) ( VirtProcr *, void * );
121 //============= Requests ===========
122 //
124 //VMS Request is the carrier for Slave to Master requests
125 // it has an embedded sub-type request that is pulled out
126 // inside the plugin's request handler
127 enum VMSReqstType //For Slave->Master requests
128 {
129 semantic = 1, //avoid starting enums at 0, for debug reasons
130 createReq,
131 dissipate,
132 VMSSemantic //goes with VMSSemReqst below
133 };
135 struct _VMSReqst
136 {
137 enum VMSReqstType reqType;//used for dissipate and in future for IO requests
138 void *semReqData;
140 VMSReqst *nextReqst;
141 };
142 //VMSReqst
144 //This is a sub-type of Slave->Master requests.
145 // It's for Slaves to invoke built-in VMS-core functions that have language-like
146 // behavior.
147 enum VMSSemReqstType //These are equivalent to semantic requests, but for
148 { // VMS's services available directly to app, like OS
149 createProbe = 1, // and probe services -- like a VMS-wide built-in lang
150 openFile,
151 otherIO,
152 interMasterReqst
153 };
155 typedef struct
156 { enum VMSSemReqstType reqType;
157 //VirtProcr *requestingPr;
158 int receiverID; //for inter master requests
159 void *data;
160 }
161 VMSSemReq;
164 //==================== Core data structures ===================
166 /*Master Env is the only global variable -- has entry points for any other
167 * data needed.
168 */
169 typedef struct
170 {
171 SlaveScheduler slaveScheduler;
172 RequestHandler requestHandler;
174 SchedSlot ***allSchedSlots;
175 VMSQueueStruc **readyToAnimateQs;
176 VirtProcr **masterVPs;
178 void *semanticEnv;
179 void *OSEventStruc; //for future, when add I/O to BLIS
181 void *coreLoopReturnPt;//addr to jump to to re-enter coreLoop
183 int32 setupComplete;
184 volatile int32 masterLock;
186 MallocProlog *freeListHead[NUM_CORES];
187 int32 amtOfOutstandingMem; //total currently allocated
189 int32 numMasterInARow[NUM_CORES];//detect back-to-back masterVP
190 GateStruc *workStealingGates[NUM_CORES]; //concurrent work-steal
191 int32 workStealingLock;
193 InterMasterReqst* interMasterRequestsFor[NUM_CORES];
194 InterMasterReqst* interMasterRequestsSentBy[NUM_CORES];
195 RequestHandler interPluginReqHdlr;
197 int32 numProcrsCreated; //gives ordering to processor creation
199 int32 currentMasterProcrID;
201 //=========== MEASUREMENT STUFF =============
202 IntervalProbe **intervalProbes;
203 PrivDynArrayInfo *dynIntervalProbesInfo;
204 HashTable *probeNameHashTbl;
205 int32 masterCreateProbeID;
206 float64 createPtInSecs;
207 Histogram **measHists;
208 PrivDynArrayInfo *measHistsInfo;
209 #ifdef MEAS__TIME_PLUGIN
210 Histogram *reqHdlrLowTimeHist;
211 Histogram *reqHdlrHighTimeHist;
212 #endif
213 #ifdef MEAS__TIME_MALLOC
214 Histogram *mallocTimeHist;
215 Histogram *freeTimeHist;
216 #endif
217 #ifdef MEAS__TIME_MASTER_LOCK
218 Histogram *masterLockLowTimeHist;
219 Histogram *masterLockHighTimeHist;
220 #endif
221 }
222 MasterEnv;
224 //========================= Extra Stuff Data Strucs =======================
225 typedef struct
226 {
228 }
229 VMSExcp;
231 struct _GateStruc
232 {
233 int32 gateClosed;
234 int32 preGateProgress;
235 int32 waitProgress;
236 int32 exitProgress;
237 };
238 //GateStruc
240 //======================= OS Thread related ===============================
242 void * coreLoop( void *paramsIn ); //standard PThreads fn prototype
243 void * coreLoop_Seq( void *paramsIn ); //standard PThreads fn prototype
244 void masterLoop( void *initData, VirtProcr *masterPr );
247 typedef struct
248 {
249 void *endThdPt;
250 unsigned int coreNum;
251 }
252 ThdParams;
254 pthread_t coreLoopThdHandles[ NUM_CORES ]; //pthread's virt-procr state
255 ThdParams *coreLoopThdParams [ NUM_CORES ];
256 pthread_mutex_t suspendLock;
257 pthread_cond_t suspend_cond;
261 //===================== Global Vars ===================
263 volatile MasterEnv *_VMSMasterEnv;
266 //=========================== Function Prototypes =========================
269 //========== Setup and shutdown ==========
270 void
271 VMS__init();
273 void
274 VMS__init_Seq();
276 void
277 VMS__start_the_work_then_wait_until_done();
279 void
280 VMS__start_the_work_then_wait_until_done_Seq();
282 inline VirtProcr *
283 VMS__create_procr( VirtProcrFnPtr fnPtr, void *initialData );
285 void
286 VMS__dissipate_procr( VirtProcr *procrToDissipate );
288 //Use this to create processor inside entry point & other places outside
289 // the VMS system boundary (IE, not run in slave nor Master)
290 VirtProcr *
291 VMS_ext__create_procr( VirtProcrFnPtr fnPtr, void *initialData );
293 void
294 VMS_ext__dissipate_procr( VirtProcr *procrToDissipate );
296 void
297 VMS__throw_exception( char *msgStr, VirtProcr *reqstPr, VMSExcp *excpData );
299 void
300 VMS__shutdown();
302 void
303 VMS__cleanup_at_end_of_shutdown();
305 void *
306 VMS__give_sem_env_for( VirtProcr *animPr );
309 //============== Request Related ===============
311 void
312 VMS__suspend_procr( VirtProcr *callingPr );
314 inline void
315 VMS__add_sem_request_in_mallocd_VMSReqst( void *semReqData, VirtProcr *callingPr );
317 inline void
318 VMS__send_sem_request( void *semReqData, VirtProcr *callingPr );
320 void
321 VMS__send_create_procr_req( void *semReqData, VirtProcr *reqstingPr );
323 void inline
324 VMS__send_dissipate_req( VirtProcr *prToDissipate );
326 inline void
327 VMS__send_VMSSem_request( void *semReqData, VirtProcr *callingPr );
330 void inline
331 VMS__send_inter_plugin_req( void *reqData, int32 targetMaster,
332 VirtProcr *requestingMaster );
333 void inline
334 VMS__send_inter_VMSCore_req( InterVMSCoreReqst *reqData, int32 targetMaster,
335 VirtProcr *requestingMaster );
337 VMSReqst *
338 VMS__take_next_request_out_of( VirtProcr *procrWithReq );
340 inline void *
341 VMS__take_sem_reqst_from( VMSReqst *req );
343 void inline
344 VMS__handle_VMSSemReq( VMSReqst *req, VirtProcr *requestingPr, void *semEnv,
345 ResumePrFnPtr resumePrFnPtr );
347 //======================== STATS ======================
349 //===== RDTSC wrapper ===== //Also runs with x86_64 code
351 #define saveTimeStampCountInto(low, high) \
352 asm volatile("RDTSC; \
353 movl %%eax, %0; \
354 movl %%edx, %1;" \
355 /* outputs */ : "=m" (low), "=m" (high)\
356 /* inputs */ : \
357 /* clobber */ : "%eax", "%edx" \
358 );
360 #define saveLowTimeStampCountInto(low) \
361 asm volatile("RDTSC; \
362 movl %%eax, %0;" \
363 /* outputs */ : "=m" (low) \
364 /* inputs */ : \
365 /* clobber */ : "%eax", "%edx" \
366 );
368 //====================
369 #define makeAMeasHist( idx, name, numBins, startVal, binWidth ) \
370 makeHighestDynArrayIndexBeAtLeast( _VMSMasterEnv->measHistsInfo, idx ); \
371 _VMSMasterEnv->measHists[idx] = \
372 makeFixedBinHist( numBins, startVal, binWidth, name );
375 #define MEAS__SUB_CREATE /*turn on/off subtraction of create from plugin*/
377 #ifdef VPTHREAD
379 //VPThread
380 #define createHistIdx 1
381 #define mutexLockHistIdx 2
382 #define mutexUnlockHistIdx 3
383 #define condWaitHistIdx 4
384 #define condSignalHistIdx 5
386 #define MakeTheMeasHists() \
387 _VMSMasterEnv->measHistsInfo = \
388 makePrivDynArrayOfSize( (void***)&(_VMSMasterEnv->measHists), 200); \
389 makeAMeasHist( createHistIdx, "create", 250, 0, 100 ) \
390 makeAMeasHist( mutexLockHistIdx, "mutex_lock", 50, 0, 100 ) \
391 makeAMeasHist( mutexUnlockHistIdx, "mutex_unlock", 50, 0, 100 ) \
392 makeAMeasHist( condWaitHistIdx, "cond_wait", 50, 0, 100 ) \
393 makeAMeasHist( condSignalHistIdx, "cond_signal", 50, 0, 100 )
395 #endif
398 #ifdef VCILK
400 //VCilk
401 #define spawnHistIdx 1
402 #define syncHistIdx 2
404 #define MakeTheMeasHists() \
405 _VMSMasterEnv->measHistsInfo = \
406 makePrivDynArrayOfSize( (void***)&(_VMSMasterEnv->measHists), 200); \
407 makeAMeasHist( spawnHistIdx, "Spawn", 50, 0, 200 ) \
408 makeAMeasHist( syncHistIdx, "Sync", 50, 0, 200 )
411 #endif
413 #ifdef SSR
415 //SSR
416 #define SendFromToHistIdx 1
417 #define SendOfTypeHistIdx 2
418 #define ReceiveFromToHistIdx 3
419 #define ReceiveOfTypeHistIdx 4
421 #define MakeTheMeasHists() \
422 _VMSMasterEnv->measHistsInfo = \
423 makePrivDynArrayOfSize( (void***)&(_VMSMasterEnv->measHists), 200); \
424 makeAMeasHist( SendFromToHistIdx, "SendFromTo", 50, 0, 100 ) \
425 makeAMeasHist( SendOfTypeHistIdx, "SendOfType", 50, 0, 100 ) \
426 makeAMeasHist( ReceiveFromToHistIdx,"ReceiveFromTo", 50, 0, 100 ) \
427 makeAMeasHist( ReceiveOfTypeHistIdx,"ReceiveOfType", 50, 0, 100 )
429 #endif
431 //===========================================================================
432 //VPThread
435 #define Meas_startCreate \
436 int32 startStamp, endStamp; \
437 saveLowTimeStampCountInto( startStamp ); \
439 #define Meas_endCreate \
440 saveLowTimeStampCountInto( endStamp ); \
441 addIntervalToHist( startStamp, endStamp, \
442 _VMSMasterEnv->measHists[ createHistIdx ] );
444 #define Meas_startMutexLock \
445 int32 startStamp, endStamp; \
446 saveLowTimeStampCountInto( startStamp ); \
448 #define Meas_endMutexLock \
449 saveLowTimeStampCountInto( endStamp ); \
450 addIntervalToHist( startStamp, endStamp, \
451 _VMSMasterEnv->measHists[ mutexLockHistIdx ] );
453 #define Meas_startMutexUnlock \
454 int32 startStamp, endStamp; \
455 saveLowTimeStampCountInto( startStamp ); \
457 #define Meas_endMutexUnlock \
458 saveLowTimeStampCountInto( endStamp ); \
459 addIntervalToHist( startStamp, endStamp, \
460 _VMSMasterEnv->measHists[ mutexUnlockHistIdx ] );
462 #define Meas_startCondWait \
463 int32 startStamp, endStamp; \
464 saveLowTimeStampCountInto( startStamp ); \
466 #define Meas_endCondWait \
467 saveLowTimeStampCountInto( endStamp ); \
468 addIntervalToHist( startStamp, endStamp, \
469 _VMSMasterEnv->measHists[ condWaitHistIdx ] );
471 #define Meas_startCondSignal \
472 int32 startStamp, endStamp; \
473 saveLowTimeStampCountInto( startStamp ); \
475 #define Meas_endCondSignal \
476 saveLowTimeStampCountInto( endStamp ); \
477 addIntervalToHist( startStamp, endStamp, \
478 _VMSMasterEnv->measHists[ condSignalHistIdx ] );
480 //===========================================================================
481 // VCilk
482 #define Meas_startSpawn \
483 int32 startStamp, endStamp; \
484 saveLowTimeStampCountInto( startStamp ); \
486 #define Meas_endSpawn \
487 saveLowTimeStampCountInto( endStamp ); \
488 addIntervalToHist( startStamp, endStamp, \
489 _VMSMasterEnv->measHists[ spawnHistIdx ] );
491 #define Meas_startSync \
492 int32 startStamp, endStamp; \
493 saveLowTimeStampCountInto( startStamp ); \
495 #define Meas_endSync \
496 saveLowTimeStampCountInto( endStamp ); \
497 addIntervalToHist( startStamp, endStamp, \
498 _VMSMasterEnv->measHists[ syncHistIdx ] );
500 //===========================================================================
501 // SSR
502 #define Meas_startSendFromTo \
503 int32 startStamp, endStamp; \
504 saveLowTimeStampCountInto( startStamp ); \
506 #define Meas_endSendFromTo \
507 saveLowTimeStampCountInto( endStamp ); \
508 addIntervalToHist( startStamp, endStamp, \
509 _VMSMasterEnv->measHists[ SendFromToHistIdx ] );
511 #define Meas_startSendOfType \
512 int32 startStamp, endStamp; \
513 saveLowTimeStampCountInto( startStamp ); \
515 #define Meas_endSendOfType \
516 saveLowTimeStampCountInto( endStamp ); \
517 addIntervalToHist( startStamp, endStamp, \
518 _VMSMasterEnv->measHists[ SendOfTypeHistIdx ] );
520 #define Meas_startReceiveFromTo \
521 int32 startStamp, endStamp; \
522 saveLowTimeStampCountInto( startStamp ); \
524 #define Meas_endReceiveFromTo \
525 saveLowTimeStampCountInto( endStamp ); \
526 addIntervalToHist( startStamp, endStamp, \
527 _VMSMasterEnv->measHists[ ReceiveFromToHistIdx ] );
529 #define Meas_startReceiveOfType \
530 int32 startStamp, endStamp; \
531 saveLowTimeStampCountInto( startStamp ); \
533 #define Meas_endReceiveOfType \
534 saveLowTimeStampCountInto( endStamp ); \
535 addIntervalToHist( startStamp, endStamp, \
536 _VMSMasterEnv->measHists[ReceiveOfTypeHistIdx ] );
538 //=====
540 #include "probes.h"
541 #include "vutilities.h"
543 #endif /* _VMS_H */