Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
changeset 57:85b731b290f8
Merge between VCilk and SSR intermediate Nov 4
| author | Me |
|---|---|
| date | Thu, 04 Nov 2010 18:27:27 -0700 |
| parents | 420a09d3f32a f8508572f3de |
| children | 26d53313a8f2 |
| files | CoreLoop.c VMS.c VMS.h |
| diffstat | 8 files changed, 255 insertions(+), 143 deletions(-) [+] |
line diff
1.1 --- a/CoreLoop.c Thu Nov 04 17:57:39 2010 -0700 1.2 +++ b/CoreLoop.c Thu Nov 04 18:27:27 2010 -0700 1.3 @@ -108,16 +108,19 @@ 1.4 { //run own MasterVP -- when its done, unlocks MasterLock and 1.5 // jumps back to coreLoops's startPt 1.6 currPr = _VMSMasterEnv->masterVPs[thisCoresIdx]; 1.7 - if( _VMSMasterEnv->numMasterInARow[thisCoresIdx] > 10000 ) 1.8 - { //printf("10000 back to back MasterVP\n"); 1.9 + if( _VMSMasterEnv->numMasterInARow[thisCoresIdx] > 100 ) 1.10 + { //printf("1000 back to back MasterVP\n"); 1.11 + //TODO: turn this into work-stealing from another core 1.12 + //only yield if no work to steal -- and count consecutive yields 1.13 + // if too many of those, then sleep for 10ms or whatever 1.14 pthread_yield(); 1.15 } 1.16 _VMSMasterEnv->numMasterInARow[thisCoresIdx] += 1; 1.17 break; //end while -- have a VP to animate now 1.18 } 1.19 1.20 - tries++; 1.21 - if( tries > READYTOANIMATE_RETRIES ) { tries = 0; pthread_yield(); } 1.22 + tries++; //if too many, means master on other core taking too long 1.23 + if( tries > MASTERLOCK_RETRIES ) { tries = 0; pthread_yield(); } 1.24 } 1.25 1.26 1.27 @@ -206,17 +209,15 @@ 1.28 readyToAnimateQ = _VMSMasterEnv->readyToAnimateQs[thisCoresIdx]; 1.29 currPr = (VirtProcr *) readSRSWQ_NonBlocking( readyToAnimateQ ); 1.30 if( currPr == NULL ) 1.31 - { if( _VMSMasterEnv->numMasterInARow[thisCoresIdx] ) 1.32 - printf("back to back MasterVP\n"); 1.33 - _VMSMasterEnv->numMasterInARow[thisCoresIdx] = TRUE; 1.34 + { if( _VMSMasterEnv->numMasterInARow[thisCoresIdx] > 1000 ) 1.35 + { printf("too many back to back MasterVP\n"); exit(1); } 1.36 + _VMSMasterEnv->numMasterInARow[thisCoresIdx] += 1; 1.37 + 1.38 currPr = _VMSMasterEnv->masterVPs[thisCoresIdx]; 1.39 } 1.40 else 1.41 - _VMSMasterEnv->numMasterInARow[thisCoresIdx] = FALSE; 1.42 + _VMSMasterEnv->numMasterInARow[thisCoresIdx] = 0; 1.43 1.44 - PRINT2_DEBUG("core %d loop procr addr: %d\n",\ 1.45 - coreLoopThdParams->coreNum, \ 1.46 - (int)currPr ) 1.47 1.48 //switch to virt procr's stack and frame ptr then jump to virt procr 1.49 void *stackPtr, *framePtr, *jmpPt, *coreLoopFramePtrAddr, \
2.1 --- a/MasterLoop.c Thu Nov 04 17:57:39 2010 -0700 2.2 +++ b/MasterLoop.c Thu Nov 04 18:27:27 2010 -0700 2.3 @@ -7,7 +7,6 @@ 2.4 2.5 2.6 #include <stdio.h> 2.7 -#include <malloc.h> 2.8 #include <stddef.h> 2.9 2.10 #include "VMS.h"
3.1 --- a/VMS.c Thu Nov 04 17:57:39 2010 -0700 3.2 +++ b/VMS.c Thu Nov 04 18:27:27 2010 -0700 3.3 @@ -33,6 +33,8 @@ 3.4 MallocProlog * 3.5 create_free_list(); 3.6 3.7 +void 3.8 +endOSThreadFn( void *initData, VirtProcr *animatingPr ); 3.9 3.10 pthread_mutex_t suspendLock = PTHREAD_MUTEX_INITIALIZER; 3.11 pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER; 3.12 @@ -89,55 +91,55 @@ 3.13 int coreIdx; 3.14 VirtProcr **masterVPs; 3.15 SchedSlot ***allSchedSlots; //ptr to array of ptrs 3.16 - 3.17 + 3.18 + 3.19 //Make the master env, which holds everything else 3.20 _VMSMasterEnv = malloc( sizeof(MasterEnv) ); 3.21 + 3.22 + //Very first thing put into the master env is the free-list, seeded 3.23 + // with a massive initial chunk of memory. 3.24 + //After this, all other mallocs are VMS__malloc. 3.25 + _VMSMasterEnv->freeListHead = VMS_ext__create_free_list(); 3.26 + 3.27 + //===================== Only VMS__malloc after this ==================== 3.28 masterEnv = _VMSMasterEnv; 3.29 - //Need to set start pt here 'cause used by seed procr, which is created 3.30 - // before the first core loop starts up. -- not sure how yet.. 3.31 -// masterEnv->coreLoopStartPt = ; 3.32 -// masterEnv->coreLoopEndPt = ; 3.33 3.34 //Make a readyToAnimateQ for each core loop 3.35 - readyToAnimateQs = malloc( NUM_CORES * sizeof(SRSWQueueStruc *) ); 3.36 - masterVPs = malloc( NUM_CORES * sizeof(VirtProcr *) ); 3.37 + readyToAnimateQs = VMS__malloc( NUM_CORES * sizeof(SRSWQueueStruc *) ); 3.38 + masterVPs = VMS__malloc( NUM_CORES * sizeof(VirtProcr *) ); 3.39 3.40 //One array for each core, 3 in array, core's masterVP scheds all 3.41 - allSchedSlots = malloc( NUM_CORES * sizeof(SchedSlot *) ); 3.42 + allSchedSlots = VMS__malloc( NUM_CORES * sizeof(SchedSlot *) ); 3.43 3.44 + _VMSMasterEnv->numProcrsCreated = 0; //used by create procr 3.45 for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ ) 3.46 - { //running in main thread -- normal malloc inside makeSRSWQ 3.47 + { 3.48 readyToAnimateQs[ coreIdx ] = makeSRSWQ(); 3.49 3.50 //Q: should give masterVP core-specific info as its init data? 3.51 - masterVPs[ coreIdx ] = VMS_ext__create_procr( &masterLoop, masterEnv ); 3.52 + masterVPs[ coreIdx ] = VMS__create_procr( &masterLoop, masterEnv ); 3.53 masterVPs[ coreIdx ]->coreAnimatedBy = coreIdx; 3.54 allSchedSlots[ coreIdx ] = create_sched_slots(); //makes for one core 3.55 - _VMSMasterEnv->numMasterInARow[ coreIdx ] = FALSE; 3.56 + _VMSMasterEnv->numMasterInARow[ coreIdx ] = 0; 3.57 } 3.58 _VMSMasterEnv->readyToAnimateQs = readyToAnimateQs; 3.59 _VMSMasterEnv->masterVPs = masterVPs; 3.60 _VMSMasterEnv->masterLock = UNLOCKED; 3.61 _VMSMasterEnv->allSchedSlots = allSchedSlots; 3.62 - _VMSMasterEnv->numProcrsCreated = 0; 3.63 3.64 3.65 //Aug 19, 2010: no longer need to place initial masterVP into queue 3.66 // because coreLoop now controls -- animates its masterVP when no work 3.67 3.68 - _VMSMasterEnv->freeListHead = VMS__create_free_list(); 3.69 - _VMSMasterEnv->amtOfOutstandingMem = 0; //none allocated yet 3.70 3.71 //============================= MEASUREMENT STUFF ======================== 3.72 #ifdef STATS__TURN_ON_PROBES 3.73 - //creates intervalProbes array and sets pointer to it in masterEnv too 3.74 _VMSMasterEnv->dynIntervalProbesInfo = 3.75 - makeDynArrayOfSize( &(_VMSMasterEnv->intervalProbes), 20 ); 3.76 + makePrivDynArrayOfSize( &(_VMSMasterEnv->intervalProbes), 200); 3.77 3.78 - _VMSMasterEnv->probeNameHashTbl = makeHashTable( 1000, NULL ); 3.79 - _VMSMasterEnv->masterCreateProbeID = 3.80 - VMS_ext__record_time_point_into_new_probe( "masterCreateProbe" ); 3.81 - //Also put creation time directly into master env, for fast retrieval 3.82 + _VMSMasterEnv->probeNameHashTbl = makeHashTable( 1000, &VMS__free ); 3.83 + 3.84 + //put creation time directly into master env, for fast retrieval 3.85 struct timeval timeStamp; 3.86 gettimeofday( &(timeStamp), NULL); 3.87 _VMSMasterEnv->createPtInSecs = 3.88 @@ -152,11 +154,11 @@ 3.89 { SchedSlot **schedSlots; 3.90 int i; 3.91 3.92 - schedSlots = malloc( NUM_SCHED_SLOTS * sizeof(SchedSlot *) ); 3.93 + schedSlots = VMS__malloc( NUM_SCHED_SLOTS * sizeof(SchedSlot *) ); 3.94 3.95 for( i = 0; i < NUM_SCHED_SLOTS; i++ ) 3.96 { 3.97 - schedSlots[i] = malloc( sizeof(SchedSlot) ); 3.98 + schedSlots[i] = VMS__malloc( sizeof(SchedSlot) ); 3.99 3.100 //Set state to mean "handling requests done, slot needs filling" 3.101 schedSlots[i]->workIsDone = FALSE; 3.102 @@ -171,9 +173,9 @@ 3.103 { int i; 3.104 for( i = 0; i < NUM_SCHED_SLOTS; i++ ) 3.105 { 3.106 - free( schedSlots[i] ); 3.107 + VMS__free( schedSlots[i] ); 3.108 } 3.109 - free( schedSlots ); 3.110 + VMS__free( schedSlots ); 3.111 } 3.112 3.113 3.114 @@ -191,7 +193,7 @@ 3.115 3.116 //Make the threads that animate the core loops 3.117 for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) 3.118 - { coreLoopThdParams[coreIdx] = malloc( sizeof(ThdParams) ); 3.119 + { coreLoopThdParams[coreIdx] = VMS__malloc( sizeof(ThdParams) ); 3.120 coreLoopThdParams[coreIdx]->coreNum = coreIdx; 3.121 3.122 retCode = 3.123 @@ -263,11 +265,12 @@ 3.124 { 3.125 char *stackPtr; 3.126 3.127 - newPr->procrID = _VMSMasterEnv->numProcrsCreated++; 3.128 - newPr->nextInstrPt = fnPtr; 3.129 - newPr->initialData = initialData; 3.130 - newPr->requests = NULL; 3.131 - newPr->schedSlot = NULL; 3.132 + newPr->startOfStack = stackLocs; 3.133 + newPr->procrID = _VMSMasterEnv->numProcrsCreated++; 3.134 + newPr->nextInstrPt = fnPtr; 3.135 + newPr->initialData = initialData; 3.136 + newPr->requests = NULL; 3.137 + newPr->schedSlot = NULL; 3.138 3.139 //fnPtr takes two params -- void *initData & void *animProcr 3.140 //alloc stack locations, make stackPtr be the highest addr minus room 3.141 @@ -285,7 +288,8 @@ 3.142 #ifdef STATS__TURN_ON_PROBES 3.143 struct timeval timeStamp; 3.144 gettimeofday( &(timeStamp), NULL); 3.145 - newPr->createPtInSecs = timeStamp.tv_sec +(timeStamp.tv_usec/1000000.0); 3.146 + newPr->createPtInSecs = timeStamp.tv_sec +(timeStamp.tv_usec/1000000.0) - 3.147 + _VMSMasterEnv->createPtInSecs; 3.148 #endif 3.149 //======================================================================== 3.150 3.151 @@ -301,7 +305,6 @@ 3.152 stackLocs = VMS__malloc( VIRT_PROCR_STACK_SIZE ); 3.153 if( stackLocs == 0 ) 3.154 { perror("VMS__malloc stack"); exit(1); } 3.155 - newPr->startOfStack = stackLocs; 3.156 3.157 return create_procr_helper( newPr, fnPtr, initialData, stackLocs ); 3.158 } 3.159 @@ -319,7 +322,6 @@ 3.160 stackLocs = malloc( VIRT_PROCR_STACK_SIZE ); 3.161 if( stackLocs == 0 ) 3.162 { perror("malloc stack"); exit(1); } 3.163 - newPr->startOfStack = stackLocs; 3.164 3.165 return create_procr_helper( newPr, fnPtr, initialData, stackLocs ); 3.166 } 3.167 @@ -477,18 +479,26 @@ 3.168 3.169 3.170 3.171 -/*This inserts the semantic-layer's request data into standard VMS carrier 3.172 - * request data-struct is allocated on stack of this call & ptr to it sent 3.173 - * to plugin 3.174 +/*This call's name indicates that request is malloc'd -- so req handler 3.175 + * has to free any extra requests tacked on before a send, using this. 3.176 + * 3.177 + * This inserts the semantic-layer's request data into standard VMS carrier 3.178 + * request data-struct that is mallocd. The sem request doesn't need to 3.179 + * be malloc'd if this is called inside the same call chain before the 3.180 + * send of the last request is called. 3.181 + * 3.182 + *The request handler has to call VMS__free_VMSReq for any of these 3.183 */ 3.184 inline void 3.185 -VMS__add_sem_request( void *semReqData, VirtProcr *callingPr ) 3.186 - { VMSReqst req; 3.187 +VMS__add_sem_request_in_mallocd_VMSReqst( void *semReqData, 3.188 + VirtProcr *callingPr ) 3.189 + { VMSReqst *req; 3.190 3.191 - req.reqType = semantic; 3.192 - req.semReqData = semReqData; 3.193 - req.nextReqst = callingPr->requests; 3.194 - callingPr->requests = &req; 3.195 + req = VMS__malloc( sizeof(VMSReqst) ); 3.196 + req->reqType = semantic; 3.197 + req->semReqData = semReqData; 3.198 + req->nextReqst = callingPr->requests; 3.199 + callingPr->requests = req; 3.200 } 3.201 3.202 /*This inserts the semantic-layer's request data into standard VMS carrier 3.203 @@ -573,10 +583,12 @@ 3.204 memcpy( newProbe->nameStr, semReq->nameStr, nameLen ); 3.205 newProbe->hist = NULL; 3.206 newProbe->schedChoiceWasRecorded = FALSE; 3.207 + 3.208 + //This runs in masterVP, so no race-condition worries 3.209 newProbe->probeID = 3.210 addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo ); 3.211 3.212 - requestingPr->dataReturnedFromReq = newProbe; 3.213 + requestingPr->dataRetFromReq = newProbe; 3.214 3.215 (*resumePrFnPtr)( requestingPr, semEnv ); 3.216 } 3.217 @@ -619,15 +631,13 @@ 3.218 } 3.219 3.220 3.221 -//TODO: re-architect so that have clean separation between request handler 3.222 +//TODO: look at architecting cleanest separation between request handler 3.223 // and master loop, for dissipate, create, shutdown, and other non-semantic 3.224 // requests. Issue is chain: one removes requests from AppVP, one dispatches 3.225 // on type of request, and one handles each type.. but some types require 3.226 // action from both request handler and master loop -- maybe just give the 3.227 // request handler calls like: VMS__handle_X_request_type 3.228 3.229 -void 3.230 -endOSThreadFn( void *initData, VirtProcr *animatingPr ); 3.231 3.232 /*This is called by the semantic layer's request handler when it decides its 3.233 * time to shut down the VMS system. Calling this causes the core loop OS 3.234 @@ -641,10 +651,9 @@ 3.235 * masterVP any AppVPs that might still be allocated and sitting in the 3.236 * semantic environment, or have been orphaned in the _VMSWorkQ. 3.237 * 3.238 - *NOTE: the semantic plug-in is expected to use VMS__malloc_to to get all the 3.239 + *NOTE: the semantic plug-in is expected to use VMS__malloc to get all the 3.240 * locations it needs, and give ownership to masterVP. Then, they will be 3.241 - * automatically freed when the masterVP is dissipated. (This happens after 3.242 - * the core loop threads have all exited) 3.243 + * automatically freed. 3.244 * 3.245 *In here,create one core-loop shut-down processor for each core loop and put 3.246 * them all directly into the readyToAnimateQ. 3.247 @@ -655,7 +664,7 @@ 3.248 * point is it sure that all results have completed. 3.249 */ 3.250 void 3.251 -VMS__handle_shutdown_reqst( void *dummy, VirtProcr *animatingPr ) 3.252 +VMS__shutdown() 3.253 { int coreIdx; 3.254 VirtProcr *shutDownPr; 3.255 3.256 @@ -703,19 +712,19 @@ 3.257 } 3.258 3.259 3.260 -/*This is called after the threads have shut down and control has returned 3.261 - * to the semantic layer, in the entry point function in the main thread. 3.262 - * It has to free anything allocated during VMS_init, and any other alloc'd 3.263 - * locations that might be left over. 3.264 +/*This is called from the startup & shutdown 3.265 */ 3.266 void 3.267 -VMS__cleanup_after_shutdown() 3.268 +VMS__cleanup_at_end_of_shutdown() 3.269 { 3.270 SRSWQueueStruc **readyToAnimateQs; 3.271 int coreIdx; 3.272 VirtProcr **masterVPs; 3.273 SchedSlot ***allSchedSlots; //ptr to array of ptrs 3.274 3.275 + //All the environment data has been allocated with VMS__malloc, so just 3.276 + // free its internal big-chunk and all inside it disappear. 3.277 +/* 3.278 readyToAnimateQs = _VMSMasterEnv->readyToAnimateQs; 3.279 masterVPs = _VMSMasterEnv->masterVPs; 3.280 allSchedSlots = _VMSMasterEnv->allSchedSlots; 3.281 @@ -724,23 +733,40 @@ 3.282 { 3.283 freeSRSWQ( readyToAnimateQs[ coreIdx ] ); 3.284 //master VPs were created external to VMS, so use external free 3.285 - VMS_ext__dissipate_procr( masterVPs[ coreIdx ] ); 3.286 + VMS__dissipate_procr( masterVPs[ coreIdx ] ); 3.287 3.288 freeSchedSlots( allSchedSlots[ coreIdx ] ); 3.289 } 3.290 3.291 - free( _VMSMasterEnv->readyToAnimateQs ); 3.292 - free( _VMSMasterEnv->masterVPs ); 3.293 - free( _VMSMasterEnv->allSchedSlots ); 3.294 + VMS__free( _VMSMasterEnv->readyToAnimateQs ); 3.295 + VMS__free( _VMSMasterEnv->masterVPs ); 3.296 + VMS__free( _VMSMasterEnv->allSchedSlots ); 3.297 3.298 - VMS_ext__free_free_list( _VMSMasterEnv->freeListHead ); 3.299 - 3.300 //============================= MEASUREMENT STUFF ======================== 3.301 #ifdef STATS__TURN_ON_PROBES 3.302 - freeDynArrayDeep( _VMSMasterEnv->dynIntervalProbesInfo, &free ); 3.303 + freeDynArrayDeep( _VMSMasterEnv->dynIntervalProbesInfo, &VMS__free_probe); 3.304 #endif 3.305 //======================================================================== 3.306 - 3.307 - free( _VMSMasterEnv ); 3.308 +*/ 3.309 + //These are the only two that use system free 3.310 + VMS_ext__free_free_list( _VMSMasterEnv->freeListHead ); 3.311 + free( (void *)_VMSMasterEnv ); 3.312 } 3.313 3.314 + 3.315 +//================================ 3.316 + 3.317 + 3.318 +/*Later, improve this -- for now, just exits the application after printing 3.319 + * the error message. 3.320 + */ 3.321 +void 3.322 +VMS__throw_exception( char *msgStr, VirtProcr *reqstPr, VMSExcp *excpData ) 3.323 + { 3.324 + printf(msgStr); 3.325 + fflush(stdin); 3.326 + exit(1); 3.327 + } 3.328 + 3.329 + 3.330 +
4.1 --- a/VMS.h Thu Nov 04 17:57:39 2010 -0700 4.2 +++ b/VMS.h Thu Nov 04 18:27:27 2010 -0700 4.3 @@ -22,6 +22,10 @@ 4.4 4.5 4.6 //=============================== Debug =================================== 4.7 + //These defines turn types of bug messages on and off 4.8 +#define dbgProbes FALSE 4.9 +#define dbgAppFlow FALSE 4.10 + 4.11 //When SEQUENTIAL is defined, VMS does sequential exe in the main thread 4.12 // It still does co-routines and all the mechanisms are the same, it just 4.13 // has only a single thread and animates VPs one at a time 4.14 @@ -32,7 +36,8 @@ 4.15 #define STATS__ENABLE_PROBES 4.16 4.17 4.18 -#define PRINT_DEBUG(msg)// printf(msg); fflush(stdin); 4.19 +#define DEBUG(msg)// printf(msg); fflush(stdin); 4.20 +#define DEBUG_MSG( bool, msg) //if( bool){ printf(msg); fflush(stdin);} 4.21 #define PRINT1_DEBUG(msg, param) //printf(msg, param); fflush(stdin); 4.22 #define PRINT2_DEBUG(msg, p1, p2) //printf(msg, p1, p2); fflush(stdin); 4.23 4.24 @@ -40,7 +45,6 @@ 4.25 #define PRINT1_ERROR(msg, param) printf(msg, param); fflush(stdin); 4.26 #define PRINT2_ERROR(msg, p1, p2) printf(msg, p1, p2); fflush(stdin); 4.27 4.28 - 4.29 //=========================== STATS ======================= 4.30 4.31 //when MEAS__TIME_STAMP_SUSP is defined, causes code to be inserted and 4.32 @@ -65,13 +69,13 @@ 4.33 4.34 #define MIN_WORK_UNIT_CYCLES 20000 4.35 4.36 -#define READYTOANIMATE_RETRIES 10000 4.37 +#define MASTERLOCK_RETRIES 10000 4.38 4.39 - // stack 4.40 -#define VIRT_PROCR_STACK_SIZE 0x4000 4.41 + // stack size in virtual processors created 4.42 +#define VIRT_PROCR_STACK_SIZE 0x4000 /* 16K */ 4.43 4.44 - // memory for VMS__malloc -- 256M 4.45 -#define MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE 0x10000000 4.46 + // memory for VMS__malloc 4.47 +#define MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE 0x10000000 /* 256M */ 4.48 4.49 4.50 //============================== 4.51 @@ -163,7 +167,7 @@ 4.52 VMSReqst *requests; 4.53 4.54 void *semanticData; //this lives here for the life of VP 4.55 - void *dataReturnedFromReq;//values returned from plugin to VP go here 4.56 + void *dataRetFromReq;//values returned from plugin to VP go here 4.57 4.58 //=========== MEASUREMENT STUFF ========== 4.59 #ifdef MEAS__TIME_STAMP_SUSP 4.60 @@ -205,14 +209,19 @@ 4.61 4.62 //=========== MEASUREMENT STUFF ============= 4.63 IntervalProbe **intervalProbes; 4.64 - DynArrayInfo *dynIntervalProbesInfo; 4.65 + PrivDynArrayInfo *dynIntervalProbesInfo; 4.66 HashTable *probeNameHashTbl; 4.67 int32 masterCreateProbeID; 4.68 float64 createPtInSecs; 4.69 } 4.70 MasterEnv; 4.71 4.72 +//============================= 4.73 +typedef struct 4.74 + { 4.75 4.76 + } 4.77 +VMSExcp; 4.78 4.79 4.80 //======================= OS Thread related =============================== 4.81 @@ -245,7 +254,8 @@ 4.82 4.83 //=========================== Function Prototypes ========================= 4.84 4.85 -//============== Setup and shutdown ============= 4.86 + 4.87 +//========== Setup and shutdown ========== 4.88 void 4.89 VMS__init(); 4.90 4.91 @@ -261,16 +271,25 @@ 4.92 VirtProcr * 4.93 VMS__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); 4.94 4.95 +void 4.96 +VMS__dissipate_procr( VirtProcr *procrToDissipate ); 4.97 + 4.98 //Use this to create processor inside entry point & other places outside 4.99 // the VMS system boundary (IE, not run in slave nor Master) 4.100 VirtProcr * 4.101 VMS_ext__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); 4.102 4.103 -VirtProcr * 4.104 -VMS__create_the_shutdown_procr(); 4.105 +void 4.106 +VMS_ext__dissipate_procr( VirtProcr *procrToDissipate ); 4.107 4.108 void 4.109 -VMS__cleanup_after_shutdown(); 4.110 +VMS__throw_exception( char *msgStr, VirtProcr *reqstPr, VMSExcp *excpData ); 4.111 + 4.112 +void 4.113 +VMS__shutdown(); 4.114 + 4.115 +void 4.116 +VMS__cleanup_at_end_of_shutdown(); 4.117 4.118 4.119 //============== Request Related =============== 4.120 @@ -279,49 +298,29 @@ 4.121 VMS__suspend_procr( VirtProcr *callingPr ); 4.122 4.123 inline void 4.124 -VMS__add_sem_request( void *semReqData, VirtProcr *callingPr ); 4.125 +VMS__add_sem_request_in_mallocd_VMSReqst( void *semReqData, VirtProcr *callingPr ); 4.126 + 4.127 +inline void 4.128 +VMS__send_sem_request( void *semReqData, VirtProcr *callingPr ); 4.129 4.130 void 4.131 VMS__send_create_procr_req( void *semReqData, VirtProcr *reqstingPr ); 4.132 4.133 +void inline 4.134 +VMS__send_dissipate_req( VirtProcr *prToDissipate ); 4.135 + 4.136 inline void 4.137 VMS__send_VMSSem_request( void *semReqData, VirtProcr *callingPr ); 4.138 4.139 -void 4.140 -VMS__free_request( VMSReqst *req ); 4.141 - 4.142 -void 4.143 -VMS__remove_and_free_top_request( VirtProcr *reqstingPr ); 4.144 - 4.145 VMSReqst * 4.146 VMS__take_next_request_out_of( VirtProcr *procrWithReq ); 4.147 4.148 inline void * 4.149 VMS__take_sem_reqst_from( VMSReqst *req ); 4.150 -// 4.151 -//VMSReqst * 4.152 -//VMS__take_top_request_from( VirtProcr *reqstingPr ); 4.153 -// 4.154 -//inline int 4.155 -//VMS__isSemanticReqst( VMSReqst *req ); 4.156 -// 4.157 -//inline int 4.158 -//VMS__isDissipateReqst( VMSReqst *req ); 4.159 -// 4.160 -//inline int 4.161 -//VMS__isCreateReqst( VMSReqst *req ); 4.162 4.163 -//========================== 4.164 +//======================== STATS ====================== 4.165 4.166 -void inline 4.167 -VMS__send_dissipate_req( VirtProcr *prToDissipate ); 4.168 - 4.169 -void 4.170 -VMS__dissipate_procr( VirtProcr *procrToDissipate ); 4.171 - 4.172 - 4.173 - 4.174 -//===================== RDTSC wrapper ================== 4.175 +//===== RDTSC wrapper ===== 4.176 4.177 #define saveTimeStampCountInto(low, high) \ 4.178 asm volatile("RDTSC; \ 4.179 @@ -339,8 +338,7 @@ 4.180 /* inputs */ : \ 4.181 /* clobber */ : "%eax", "%edx" \ 4.182 ); 4.183 - 4.184 -//======================== STATS ====================== 4.185 +//===== 4.186 4.187 #include "probes.h" 4.188
5.1 --- a/probes.c Thu Nov 04 17:57:39 2010 -0700 5.2 +++ b/probes.c Thu Nov 04 18:27:27 2010 -0700 5.3 @@ -31,17 +31,6 @@ 5.4 5.5 //==================== Probes ================= 5.6 #ifdef STATS__USE_TSC_PROBES 5.7 -int32 5.8 -VMS__create_single_interval_probe( char *nameStr ) 5.9 - { IntervalProbe *newProbe; 5.10 - int32 idx; 5.11 - 5.12 - newProbe = malloc( sizeof(IntervalProbe) ); 5.13 - newProbe->nameStr = nameStr; //caller frees if not constant on stack 5.14 - newProbe->hist = NULL; 5.15 - idx = addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo ); 5.16 - return idx; 5.17 - } 5.18 5.19 int32 5.20 VMS__create_histogram_probe( int32 numBins, float32 startValue, 5.21 @@ -131,7 +120,7 @@ 5.22 5.23 VMS__send_VMSSem_request( &reqData, animPr ); 5.24 5.25 - return animPr->dataReturnedFromReq; 5.26 + return animPr->dataRetFromReq; 5.27 } 5.28 5.29 /*Use this version from outside VMS -- it uses external malloc, and modifies 5.30 @@ -154,8 +143,19 @@ 5.31 return newProbe; 5.32 } 5.33 5.34 + 5.35 +/*Only call from inside master or main startup/shutdown thread 5.36 + */ 5.37 +void 5.38 +VMS_impl__free_probe( IntervalProbe *probe ) 5.39 + { if( probe->hist != NULL ) freeDblHist( probe->hist ); 5.40 + if( probe->nameStr != NULL) VMS__free( probe->nameStr ); 5.41 + VMS__free( probe ); 5.42 + } 5.43 + 5.44 + 5.45 int32 5.46 -VMS_impl__record_time_point_into_new_probe( char *nameStr, VirtProcr *animPr ) 5.47 +VMS_impl__record_time_point_into_new_probe( char *nameStr, VirtProcr *animPr) 5.48 { IntervalProbe *newProbe; 5.49 struct timeval *startStamp; 5.50 float64 startSecs; 5.51 @@ -243,7 +243,7 @@ 5.52 probe->schedChoiceWasRecorded = TRUE; 5.53 probe->coreNum = animatingPr->coreAnimatedBy; 5.54 probe->procrID = animatingPr->procrID; 5.55 - probe->procrCreateSecs = 0; 5.56 + probe->procrCreateSecs = animatingPr->createPtInSecs; 5.57 } 5.58 5.59 /*Everything is local to the animating procr, so no need for request, do 5.60 @@ -253,6 +253,7 @@ 5.61 VMS_impl__record_interval_start_in_probe( int32 probeID ) 5.62 { IntervalProbe *probe; 5.63 5.64 + DEBUG_MSG( dbgProbes, "record start of interval\n" ) 5.65 probe = _VMSMasterEnv->intervalProbes[ probeID ]; 5.66 gettimeofday( &(probe->startStamp), NULL ); 5.67 } 5.68 @@ -265,8 +266,9 @@ 5.69 VMS_impl__record_interval_end_in_probe( int32 probeID ) 5.70 { IntervalProbe *probe; 5.71 struct timeval *endStamp, *startStamp; 5.72 - double startSecs, endSecs; 5.73 + float64 startSecs, endSecs; 5.74 5.75 + DEBUG_MSG( dbgProbes, "record end of interval\n" ) 5.76 //possible seg-fault if array resized by diff core right after this 5.77 // one gets probe..? Something like that? Might be safe.. don't care 5.78 probe = _VMSMasterEnv->intervalProbes[ probeID ];
6.1 --- a/probes.h Thu Nov 04 17:57:39 2010 -0700 6.2 +++ b/probes.h Thu Nov 04 18:27:27 2010 -0700 6.3 @@ -87,6 +87,10 @@ 6.4 binWidth, nameStr, animPr ) \ 6.5 VMS_impl__create_histogram_probe( numBins, startValue, \ 6.6 binWidth, nameStr, animPr ) 6.7 +void 6.8 +VMS_impl__free_probe( IntervalProbe *probe ); 6.9 +#define VMS__free_probe( probe ) \ 6.10 + VMS_impl__free_probe( probe ) 6.11 6.12 void 6.13 VMS_impl__index_probe_by_its_name( int32 probeID, VirtProcr *animPr );
7.1 --- a/vmalloc.c Thu Nov 04 17:57:39 2010 -0700 7.2 +++ b/vmalloc.c Thu Nov 04 18:27:27 2010 -0700 7.3 @@ -8,6 +8,7 @@ 7.4 */ 7.5 7.6 #include <malloc.h> 7.7 +#include <stdlib.h> 7.8 7.9 #include "VMS.h" 7.10 7.11 @@ -123,14 +124,19 @@ 7.12 { MallocProlog *elemToFree, *nextLowerElem, *nextHigherElem; 7.13 int32 lowerExistsAndIsFree, higherExistsAndIsFree, sizeOfElem; 7.14 7.15 - if( ptrToFree < _VMSMasterEnv->freeListHead->nextLowerInMem || 7.16 - ptrToFree > _VMSMasterEnv->freeListHead->nextHigherInMem ) 7.17 + if( ptrToFree < (void*)_VMSMasterEnv->freeListHead->nextLowerInMem || 7.18 + ptrToFree > (void*)_VMSMasterEnv->freeListHead->nextHigherInMem ) 7.19 { //outside the range of data owned by VMS's malloc, so do nothing 7.20 return; 7.21 } 7.22 //subtract size of prolog to get pointer to prolog, then cast 7.23 elemToFree = (MallocProlog *)((char *)ptrToFree - sizeof(MallocProlog)); 7.24 sizeOfElem =(int32)((char*)elemToFree->nextHigherInMem-(char*)elemToFree); 7.25 + 7.26 + if( elemToFree->prevChunkInFreeList != NULL ) 7.27 + { printf( "error: freeing same element twice!" ); exit(1); 7.28 + } 7.29 + 7.30 _VMSMasterEnv->amtOfOutstandingMem -= sizeOfElem; 7.31 7.32 nextLowerElem = elemToFree->nextLowerInMem; 7.33 @@ -209,10 +215,73 @@ 7.34 } 7.35 7.36 7.37 +/*Allocates memory from the external system -- higher overhead 7.38 + * 7.39 + *Because of Linux's malloc throwing bizarre random faults when malloc is 7.40 + * used inside a VMS virtual processor, have to pass this as a request and 7.41 + * have the core loop do it when it gets around to it -- will look for these 7.42 + * chores leftover from the previous animation of masterVP the next time it 7.43 + * goes to animate the masterVP -- so it takes two separate masterVP 7.44 + * animations, separated by work, to complete an external malloc or 7.45 + * external free request. 7.46 + * 7.47 + *Thinking core loop accepts signals -- just looks if signal-location is 7.48 + * empty or not -- 7.49 + */ 7.50 +void * 7.51 +VMS__malloc_in_ext( int32 sizeRequested ) 7.52 + { 7.53 + /* 7.54 + //This is running in the master, so no chance for multiple cores to be 7.55 + // competing for the core's flag. 7.56 + if( *(_VMSMasterEnv->coreLoopSignalAddr[ 0 ]) != 0 ) 7.57 + { //something has already signalled to core loop, so save the signal 7.58 + // and look, next time master animated, to see if can send it. 7.59 + //Note, the addr to put a signal is in the coreloop's frame, so just 7.60 + // checks it each time through -- make it volatile to avoid GCC 7.61 + // optimizations -- it's a coreloop local var that only changes 7.62 + // after jumping away. The signal includes the addr to send the 7.63 + //return to -- even if just empty return completion-signal 7.64 + // 7.65 + //save the signal in some queue that the master looks at each time 7.66 + // it starts up -- one loc says if empty for fast common case -- 7.67 + //something like that -- want to hide this inside this call -- but 7.68 + // think this has to come as a request -- req handler gives procr 7.69 + // back to master loop, which gives it back to req handler at point 7.70 + // it sees that core loop has sent return signal. Something like 7.71 + // that. 7.72 + saveTheSignal 7.73 + 7.74 + } 7.75 + coreSigData->type = malloc; 7.76 + coreSigData->sizeToMalloc = sizeRequested; 7.77 + coreSigData->locToSignalCompletion = &figureOut; 7.78 + _VMSMasterEnv->coreLoopSignals[ 0 ] = coreSigData; 7.79 + */ 7.80 + //just risk system-stack faults until get this figured out 7.81 + return malloc( sizeRequested ); 7.82 + } 7.83 + 7.84 + 7.85 +/*Frees memory that was allocated in the external system -- higher overhead 7.86 + * 7.87 + *As noted in external malloc comment, this is clunky 'cause the free has 7.88 + * to be called in the core loop. 7.89 + */ 7.90 +void 7.91 +VMS__free_in_ext( void *ptrToFree ) 7.92 + { 7.93 + //just risk system-stack faults until get this figured out 7.94 + free( ptrToFree ); 7.95 + 7.96 + //TODO: fix this -- so 7.97 + } 7.98 + 7.99 + 7.100 /*Designed to be called from the main thread outside of VMS, during init 7.101 */ 7.102 MallocProlog * 7.103 -VMS__create_free_list() 7.104 +VMS_ext__create_free_list() 7.105 { MallocProlog *freeListHead, *firstChunk; 7.106 7.107 //Note, this is running in the main thread -- all increases in malloc 7.108 @@ -226,16 +295,18 @@ 7.109 //Use this addr to free the heap when cleanup 7.110 freeListHead->nextLowerInMem = firstChunk; 7.111 //to identify top-of-heap elem, compare this addr to elem's next higher 7.112 - freeListHead->nextHigherInMem = (char *)firstChunk + 7.113 - MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE; 7.114 + freeListHead->nextHigherInMem = (void*)( (char*)firstChunk + 7.115 + MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE); 7.116 freeListHead->nextChunkInFreeList = firstChunk; 7.117 7.118 firstChunk->nextChunkInFreeList = NULL; 7.119 firstChunk->prevChunkInFreeList = freeListHead; 7.120 //next Higher has to be set to top of chunk, so can calc size in malloc 7.121 - firstChunk->nextHigherInMem = (char *)firstChunk + 7.122 - MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE; 7.123 + firstChunk->nextHigherInMem = (void*)( (char*)firstChunk + 7.124 + MALLOC_ADDITIONAL_MEM_FROM_OS_SIZE); 7.125 firstChunk->nextLowerInMem = NULL; //identifies as bott of heap 7.126 + 7.127 + _VMSMasterEnv->amtOfOutstandingMem = 0; //none allocated yet 7.128 7.129 return freeListHead; 7.130 }
8.1 --- a/vmalloc.h Thu Nov 04 17:57:39 2010 -0700 8.2 +++ b/vmalloc.h Thu Nov 04 18:27:27 2010 -0700 8.3 @@ -34,8 +34,19 @@ 8.4 void 8.5 VMS__free( void *ptrToFree ); 8.6 8.7 +/*Allocates memory from the external system -- higher overhead 8.8 + */ 8.9 +void * 8.10 +VMS__malloc_in_ext( int32 sizeRequested ); 8.11 + 8.12 +/*Frees memory that was allocated in the external system -- higher overhead 8.13 + */ 8.14 +void 8.15 +VMS__free_in_ext( void *ptrToFree ); 8.16 + 8.17 + 8.18 MallocProlog * 8.19 -VMS__create_free_list(); 8.20 +VMS_ext__create_free_list(); 8.21 8.22 void 8.23 VMS_ext__free_free_list( MallocProlog *freeListHead );
