Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
diff VMS.c @ 50:8f7141a9272e
Added VMS__malloc and probes, and major re-factoring to separate mallocs
| author | Me |
|---|---|
| date | Sat, 30 Oct 2010 20:54:36 -0700 |
| parents | cf3e9238aeb0 |
| children | f59cfa31a579 |
line diff
1.1 --- a/VMS.c Thu Oct 14 17:07:23 2010 -0700 1.2 +++ b/VMS.c Sat Oct 30 20:54:36 2010 -0700 1.3 @@ -6,7 +6,9 @@ 1.4 1.5 #include <stdio.h> 1.6 #include <stdlib.h> 1.7 +#include <string.h> 1.8 #include <malloc.h> 1.9 +#include <sys/time.h> 1.10 1.11 #include "VMS.h" 1.12 #include "Queue_impl/BlockingQueue.h" 1.13 @@ -28,6 +30,10 @@ 1.14 void 1.15 create_the_coreLoop_OS_threads(); 1.16 1.17 +MallocProlog * 1.18 +create_free_list(); 1.19 + 1.20 + 1.21 pthread_mutex_t suspendLock = PTHREAD_MUTEX_INITIALIZER; 1.22 pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER; 1.23 1.24 @@ -100,67 +106,47 @@ 1.25 allSchedSlots = malloc( NUM_CORES * sizeof(SchedSlot *) ); 1.26 1.27 for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ ) 1.28 - { 1.29 + { //running in main thread -- normal malloc inside makeSRSWQ 1.30 readyToAnimateQs[ coreIdx ] = makeSRSWQ(); 1.31 1.32 - //Q: should give masterVP core-specific into as its init data? 1.33 - masterVPs[ coreIdx ] = VMS__create_procr( &masterLoop, masterEnv ); 1.34 + //Q: should give masterVP core-specific info as its init data? 1.35 + masterVPs[ coreIdx ] = VMS_ext__create_procr( &masterLoop, masterEnv ); 1.36 masterVPs[ coreIdx ]->coreAnimatedBy = coreIdx; 1.37 allSchedSlots[ coreIdx ] = create_sched_slots(); //makes for one core 1.38 + _VMSMasterEnv->numMasterInARow[ coreIdx ] = FALSE; 1.39 } 1.40 _VMSMasterEnv->readyToAnimateQs = readyToAnimateQs; 1.41 _VMSMasterEnv->masterVPs = masterVPs; 1.42 + _VMSMasterEnv->masterLock = UNLOCKED; 1.43 _VMSMasterEnv->allSchedSlots = allSchedSlots; 1.44 - 1.45 + _VMSMasterEnv->numProcrsCreated = 0; 1.46 1.47 1.48 //Aug 19, 2010: no longer need to place initial masterVP into queue 1.49 // because coreLoop now controls -- animates its masterVP when no work 1.50 1.51 + _VMSMasterEnv->freeListHead = VMS__create_free_list(); 1.52 + _VMSMasterEnv->amtOfOutstandingMem = 0; //none allocated yet 1.53 1.54 - //==================== malloc substitute ======================== 1.55 - // 1.56 - //Testing whether malloc is using thread-local storage and therefore 1.57 - // causing unreliable behavior. 1.58 - //Just allocate a massive chunk of memory and roll own malloc/free and 1.59 - // make app use VMS__malloc_to, which will suspend and perform malloc 1.60 - // in the master, taking from this massive chunk. 1.61 + //============================= MEASUREMENT STUFF ======================== 1.62 + #ifdef STATS__TURN_ON_PROBES 1.63 + //creates intervalProbes array and sets pointer to it in masterEnv too 1.64 + _VMSMasterEnv->dynIntervalProbesInfo = 1.65 + makeDynArrayOfSize( &(_VMSMasterEnv->intervalProbes), 20 ); 1.66 1.67 -// initFreeList(); 1.68 + _VMSMasterEnv->probeNameHashTbl = makeHashTable( 1000, NULL ); 1.69 + _VMSMasterEnv->masterCreateProbeID = 1.70 + VMS_ext__record_time_point_into_new_probe( "masterCreateProbe" ); 1.71 + //Also put creation time directly into master env, for fast retrieval 1.72 + struct timeval timeStamp; 1.73 + gettimeofday( &(timeStamp), NULL); 1.74 + _VMSMasterEnv->createPtInSecs = 1.75 + timeStamp.tv_sec +(timeStamp.tv_usec/1000000.0); 1.76 + #endif 1.77 + //======================================================================== 1.78 1.79 } 1.80 1.81 -/* 1.82 -void 1.83 -initMasterMalloc() 1.84 - { 1.85 - _VMSMasterEnv->mallocChunk = malloc( MASSIVE_MALLOC_SIZE ); 1.86 - 1.87 - //The free-list element is the first several locations of an 1.88 - // allocated chunk -- the address given to the application is pre- 1.89 - // pended with both the ownership structure and the free-list struc. 1.90 - //So, write the values of these into the first locations of 1.91 - // mallocChunk -- which marks it as free & puts in its size. 1.92 - listElem = (FreeListElem *)_VMSMasterEnv->mallocChunk; 1.93 - listElem->size = MASSIVE_MALLOC_SIZE - NUM_PREPEND_BYTES 1.94 - listElem->next = NULL; 1.95 - } 1.96 - 1.97 -void 1.98 -dissipateMasterMalloc() 1.99 - { 1.100 - //Just foo code -- to get going -- doing as if free list were link-list 1.101 - currElem = _VMSMasterEnv->freeList; 1.102 - while( currElem != NULL ) 1.103 - { 1.104 - nextElem = currElem->next; 1.105 - masterFree( currElem ); 1.106 - currElem = nextElem; 1.107 - } 1.108 - free( _VMSMasterEnv->freeList ); 1.109 - } 1.110 - */ 1.111 - 1.112 SchedSlot ** 1.113 create_sched_slots() 1.114 { SchedSlot **schedSlots; 1.115 @@ -213,7 +199,7 @@ 1.116 thdAttrs, 1.117 &coreLoop, 1.118 (void *)(coreLoopThdParams[coreIdx]) ); 1.119 - if(retCode){printf("ERROR creating thread: %d\n", retCode); exit(0);} 1.120 + if(retCode){printf("ERROR creating thread: %d\n", retCode); exit(1);} 1.121 } 1.122 } 1.123 1.124 @@ -225,12 +211,6 @@ 1.125 VMS__start_the_work_then_wait_until_done() 1.126 { int coreIdx; 1.127 //Start the core loops running 1.128 -//=========================================================================== 1.129 - TSCount startCount, endCount; 1.130 - unsigned long long count = 0, freq = 0; 1.131 - double runTime; 1.132 - 1.133 - startCount = getTSCount(); 1.134 1.135 //tell the core loop threads that setup is complete 1.136 //get lock, to lock out any threads still starting up -- they'll see 1.137 @@ -251,14 +231,6 @@ 1.138 //NOTE: do not clean up VMS env here -- semantic layer has to have 1.139 // a chance to clean up its environment first, then do a call to free 1.140 // the Master env and rest of VMS locations 1.141 - 1.142 - 1.143 - endCount = getTSCount(); 1.144 - count = endCount - startCount; 1.145 - 1.146 - runTime = (double)count / (double)TSCOUNT_FREQ; 1.147 - 1.148 - printf("\n Time startup to shutdown: %f\n", runTime); fflush( stdin ); 1.149 } 1.150 1.151 /*Only difference between version with an OS thread pinned to each core and 1.152 @@ -285,37 +257,73 @@ 1.153 * animator state to return to -- 1.154 * 1.155 */ 1.156 -VirtProcr * 1.157 -VMS__create_procr( VirtProcrFnPtr fnPtr, void *initialData ) 1.158 - { VirtProcr *newPr; 1.159 - char *stackLocs, *stackPtr; 1.160 +inline VirtProcr * 1.161 +create_procr_helper( VirtProcr *newPr, VirtProcrFnPtr fnPtr, 1.162 + void *initialData, char *stackLocs ) 1.163 + { 1.164 + char *stackPtr; 1.165 1.166 - newPr = malloc( sizeof(VirtProcr) ); 1.167 - newPr->procrID = numProcrsCreated++; 1.168 + newPr->procrID = _VMSMasterEnv->numProcrsCreated++; 1.169 newPr->nextInstrPt = fnPtr; 1.170 newPr->initialData = initialData; 1.171 newPr->requests = NULL; 1.172 newPr->schedSlot = NULL; 1.173 -// newPr->coreLoopStartPt = _VMSMasterEnv->coreLoopStartPt; 1.174 1.175 //fnPtr takes two params -- void *initData & void *animProcr 1.176 //alloc stack locations, make stackPtr be the highest addr minus room 1.177 // for 2 params + return addr. Return addr (NULL) is in loc pointed to 1.178 // by stackPtr, initData at stackPtr + 4 bytes, animatingPr just above 1.179 - stackLocs = malloc( VIRT_PROCR_STACK_SIZE ); 1.180 - if(stackLocs == 0) 1.181 - {perror("malloc stack"); exit(1);} 1.182 - newPr->startOfStack = stackLocs; 1.183 stackPtr = ( (char *)stackLocs + VIRT_PROCR_STACK_SIZE - 0x10 ); 1.184 + 1.185 //setup __cdecl on stack -- coreloop will switch to stackPtr before jmp 1.186 *( (int *)stackPtr + 2 ) = (int) newPr; //rightmost param -- 32bit pointer 1.187 *( (int *)stackPtr + 1 ) = (int) initialData; //next param to left 1.188 newPr->stackPtr = stackPtr; //core loop will switch to this, then 1.189 newPr->framePtr = stackPtr; //suspend loop will save new stack & frame ptr 1.190 1.191 + //============================= MEASUREMENT STUFF ======================== 1.192 + #ifdef STATS__TURN_ON_PROBES 1.193 + struct timeval timeStamp; 1.194 + gettimeofday( &(timeStamp), NULL); 1.195 + newPr->createPtInSecs = timeStamp.tv_sec +(timeStamp.tv_usec/1000000.0); 1.196 + #endif 1.197 + //======================================================================== 1.198 + 1.199 return newPr; 1.200 } 1.201 1.202 +inline VirtProcr * 1.203 +VMS__create_procr( VirtProcrFnPtr fnPtr, void *initialData ) 1.204 + { VirtProcr *newPr; 1.205 + char *stackLocs; 1.206 + 1.207 + newPr = VMS__malloc( sizeof(VirtProcr) ); 1.208 + stackLocs = VMS__malloc( VIRT_PROCR_STACK_SIZE ); 1.209 + if( stackLocs == 0 ) 1.210 + { perror("VMS__malloc stack"); exit(1); } 1.211 + newPr->startOfStack = stackLocs; 1.212 + 1.213 + return create_procr_helper( newPr, fnPtr, initialData, stackLocs ); 1.214 + } 1.215 + 1.216 +/* "ext" designates that it's for use outside the VMS system -- should only 1.217 + * be called from main thread or other thread -- never from code animated by 1.218 + * a VMS virtual processor. 1.219 + */ 1.220 +inline VirtProcr * 1.221 +VMS_ext__create_procr( VirtProcrFnPtr fnPtr, void *initialData ) 1.222 + { VirtProcr *newPr; 1.223 + char *stackLocs; 1.224 + 1.225 + newPr = malloc( sizeof(VirtProcr) ); 1.226 + stackLocs = malloc( VIRT_PROCR_STACK_SIZE ); 1.227 + if( stackLocs == 0 ) 1.228 + { perror("malloc stack"); exit(1); } 1.229 + newPr->startOfStack = stackLocs; 1.230 + 1.231 + return create_procr_helper( newPr, fnPtr, initialData, stackLocs ); 1.232 + } 1.233 + 1.234 1.235 /*there is a label inside this function -- save the addr of this label in 1.236 * the callingPr struc, as the pick-up point from which to start the next 1.237 @@ -339,7 +347,6 @@ 1.238 1.239 //return ownership of the virt procr and sched slot to Master virt pr 1.240 animatingPr->schedSlot->workIsDone = TRUE; 1.241 -// coreIdx = callingPr->coreAnimatedBy; 1.242 1.243 stackPtrAddr = &(animatingPr->stackPtr); 1.244 framePtrAddr = &(animatingPr->framePtr); 1.245 @@ -390,6 +397,31 @@ 1.246 1.247 1.248 1.249 +/*For this implementation of VMS, it may not make much sense to have the 1.250 + * system of requests for creating a new processor done this way.. but over 1.251 + * the scope of single-master, multi-master, mult-tasking, OS-implementing, 1.252 + * distributed-memory, and so on, this gives VMS implementation a chance to 1.253 + * do stuff before suspend, in the AppVP, and in the Master before the plugin 1.254 + * is called, as well as in the lang-lib before this is called, and in the 1.255 + * plugin. So, this gives both VMS and language implementations a chance to 1.256 + * intercept at various points and do order-dependent stuff. 1.257 + *Having a standard VMSNewPrReqData struc allows the language to create and 1.258 + * free the struc, while VMS knows how to get the newPr if it wants it, and 1.259 + * it lets the lang have lang-specific data related to creation transported 1.260 + * to the plugin. 1.261 + */ 1.262 +void 1.263 +VMS__send_create_procr_req( void *semReqData, VirtProcr *reqstingPr ) 1.264 + { VMSReqst req; 1.265 + 1.266 + req.reqType = createReq; 1.267 + req.semReqData = semReqData; 1.268 + req.nextReqst = reqstingPr->requests; 1.269 + reqstingPr->requests = &req; 1.270 + 1.271 + VMS__suspend_procr( reqstingPr ); 1.272 + } 1.273 + 1.274 1.275 /* 1.276 *This adds a request to dissipate, then suspends the processor so that the 1.277 @@ -414,80 +446,93 @@ 1.278 */ 1.279 void 1.280 VMS__dissipate_procr( VirtProcr *procrToDissipate ) 1.281 - { VMSReqst *req; 1.282 + { VMSReqst req; 1.283 1.284 - req = malloc( sizeof(VMSReqst) ); 1.285 -// req->virtProcrFrom = callingPr; 1.286 - req->reqType = dissipate; 1.287 - req->nextReqst = procrToDissipate->requests; 1.288 - procrToDissipate->requests = req; 1.289 - 1.290 + req.reqType = dissipate; 1.291 + req.nextReqst = procrToDissipate->requests; 1.292 + procrToDissipate->requests = &req; 1.293 + 1.294 VMS__suspend_procr( procrToDissipate ); 1.295 -} 1.296 + } 1.297 + 1.298 + 1.299 +/* "ext" designates that it's for use outside the VMS system -- should only 1.300 + * be called from main thread or other thread -- never from code animated by 1.301 + * a VMS virtual processor. 1.302 + * 1.303 + *Use this version to dissipate VPs created outside the VMS system. 1.304 + */ 1.305 +void 1.306 +VMS_ext__dissipate_procr( VirtProcr *procrToDissipate ) 1.307 + { 1.308 + //NOTE: initialData was given to the processor, so should either have 1.309 + // been alloc'd with VMS__malloc, or freed by the level above animPr. 1.310 + //So, all that's left to free here is the stack and the VirtProcr struc 1.311 + // itself 1.312 + //Note, should not stack-allocate initial data -- no guarantee, in 1.313 + // general that creating processor will outlive ones it creates. 1.314 + free( procrToDissipate->startOfStack ); 1.315 + free( procrToDissipate ); 1.316 + } 1.317 + 1.318 1.319 1.320 /*This inserts the semantic-layer's request data into standard VMS carrier 1.321 + * request data-struct is allocated on stack of this call & ptr to it sent 1.322 + * to plugin 1.323 */ 1.324 inline void 1.325 VMS__add_sem_request( void *semReqData, VirtProcr *callingPr ) 1.326 - { VMSReqst *req; 1.327 + { VMSReqst req; 1.328 1.329 - req = malloc( sizeof(VMSReqst) ); 1.330 -// req->virtProcrFrom = callingPr; 1.331 - req->reqType = semantic; 1.332 - req->semReqData = semReqData; 1.333 - req->nextReqst = callingPr->requests; 1.334 - callingPr->requests = req; 1.335 + req.reqType = semantic; 1.336 + req.semReqData = semReqData; 1.337 + req.nextReqst = callingPr->requests; 1.338 + callingPr->requests = &req; 1.339 } 1.340 1.341 +/*This inserts the semantic-layer's request data into standard VMS carrier 1.342 + * request data-struct is allocated on stack of this call & ptr to it sent 1.343 + * to plugin 1.344 + *Then it does suspend, to cause request to be sent. 1.345 + */ 1.346 +inline void 1.347 +VMS__send_sem_request( void *semReqData, VirtProcr *callingPr ) 1.348 + { VMSReqst req; 1.349 1.350 -/*Use this to get first request before starting request handler's loop 1.351 + req.reqType = semantic; 1.352 + req.semReqData = semReqData; 1.353 + req.nextReqst = callingPr->requests; 1.354 + callingPr->requests = &req; 1.355 + 1.356 + VMS__suspend_procr( callingPr ); 1.357 + } 1.358 + 1.359 + 1.360 +inline void 1.361 +VMS__send_VMSSem_request( void *semReqData, VirtProcr *callingPr ) 1.362 + { VMSReqst req; 1.363 + 1.364 + req.reqType = VMSSemantic; 1.365 + req.semReqData = semReqData; 1.366 + req.nextReqst = callingPr->requests; //gab any other preceeding 1.367 + callingPr->requests = &req; 1.368 + 1.369 + VMS__suspend_procr( callingPr ); 1.370 + } 1.371 + 1.372 + 1.373 +/* 1.374 */ 1.375 VMSReqst * 1.376 -VMS__take_top_request_from( VirtProcr *procrWithReq ) 1.377 - { VMSReqst *req; 1.378 - 1.379 - req = procrWithReq->requests; 1.380 - if( req == NULL ) return req; 1.381 - 1.382 - procrWithReq->requests = procrWithReq->requests->nextReqst; 1.383 - return req; 1.384 - } 1.385 - 1.386 -/*A subtle bug due to freeing then accessing "next" after freed caused this 1.387 - * form of call to be put in -- so call this at end of request handler loop 1.388 - * that iterates through the requests. 1.389 - */ 1.390 -VMSReqst * 1.391 -VMS__free_top_and_give_next_request_from( VirtProcr *procrWithReq ) 1.392 +VMS__take_next_request_out_of( VirtProcr *procrWithReq ) 1.393 { VMSReqst *req; 1.394 1.395 req = procrWithReq->requests; 1.396 if( req == NULL ) return NULL; 1.397 1.398 procrWithReq->requests = procrWithReq->requests->nextReqst; 1.399 - VMS__free_request( req ); 1.400 - return procrWithReq->requests; 1.401 - } 1.402 - 1.403 - 1.404 -//TODO: add a semantic-layer supplied "freer" for the semantic-data portion 1.405 -// of a request -- IE call with both a virt procr and a fn-ptr to request 1.406 -// freer (also maybe put sem request freer as a field in virt procr?) 1.407 -//MeasVMS relies right now on this only freeing VMS layer of request -- the 1.408 -// semantic portion of request is alloc'd and freed by request handler 1.409 -void 1.410 -VMS__free_request( VMSReqst *req ) 1.411 - { 1.412 - free( req ); 1.413 - } 1.414 - 1.415 - 1.416 - 1.417 -inline int 1.418 -VMS__isSemanticReqst( VMSReqst *req ) 1.419 - { 1.420 - return ( req->reqType == semantic ); 1.421 + return req; 1.422 } 1.423 1.424 1.425 @@ -497,36 +542,44 @@ 1.426 return req->semReqData; 1.427 } 1.428 1.429 -inline int 1.430 -VMS__isDissipateReqst( VMSReqst *req ) 1.431 - { 1.432 - return ( req->reqType == dissipate ); 1.433 - } 1.434 1.435 -inline int 1.436 -VMS__isCreateReqst( VMSReqst *req ) 1.437 - { 1.438 - return ( req->reqType == regCreated ); 1.439 - } 1.440 1.441 -void 1.442 -VMS__send_req_to_register_new_procr(VirtProcr *newPr, VirtProcr *reqstingPr) 1.443 - { VMSReqst *req; 1.444 +/* This is for OS requests and VMS infrastructure requests, such as to create 1.445 + * a probe -- a probe is inside the heart of VMS-core, it's not part of any 1.446 + * language -- but it's also a semantic thing that's triggered from and used 1.447 + * in the application.. so it crosses abstractions.. so, need some special 1.448 + * pattern here for handling such requests. 1.449 + * This is called from the language's request handler when it sees a request 1.450 + * of type VMSSemReq 1.451 + */ 1.452 +void inline 1.453 +VMS__handle_VMSSemReq( VMSReqst *req, VirtProcr *requestingPr, void *semEnv, 1.454 + ResumePrFnPtr resumePrFnPtr ) 1.455 + { VMSSemReq *semReq; 1.456 + IntervalProbe *newProbe; 1.457 + int32 nameLen; 1.458 1.459 - req = malloc( sizeof(VMSReqst) ); 1.460 - req->reqType = regCreated; 1.461 - req->semReqData = newPr; 1.462 - req->nextReqst = reqstingPr->requests; 1.463 - reqstingPr->requests = req; 1.464 + semReq = req->semReqData; 1.465 1.466 - VMS__suspend_procr( reqstingPr ); 1.467 + newProbe = VMS__malloc( sizeof(IntervalProbe) ); 1.468 + nameLen = strlen( semReq->nameStr ); 1.469 + newProbe->nameStr = VMS__malloc( nameLen ); 1.470 + memcpy( newProbe->nameStr, semReq->nameStr, nameLen ); 1.471 + newProbe->hist = NULL; 1.472 + newProbe->schedChoiceWasRecorded = FALSE; 1.473 + newProbe->probeID = 1.474 + addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo ); 1.475 + 1.476 + requestingPr->dataReturnedFromReq = newProbe; 1.477 + 1.478 + (*resumePrFnPtr)( requestingPr, semEnv ); 1.479 } 1.480 1.481 1.482 1.483 /*This must be called by the request handler plugin -- it cannot be called 1.484 * from the semantic library "dissipate processor" function -- instead, the 1.485 - * semantic layer has to generate a request for the plug-in to call this 1.486 + * semantic layer has to generate a request, and the plug-in calls this 1.487 * function. 1.488 *The reason is that this frees the virtual processor's stack -- which is 1.489 * still in use inside semantic library calls! 1.490 @@ -548,15 +601,15 @@ 1.491 // any locations that it is (was) sole owner of 1.492 //TODO: implement VMS__malloc system, including "give up ownership" 1.493 1.494 - //The dissipate request might still be attached, so remove and free it 1.495 - VMS__free_top_and_give_next_request_from( animatingPr ); 1.496 1.497 //NOTE: initialData was given to the processor, so should either have 1.498 // been alloc'd with VMS__malloc, or freed by the level above animPr. 1.499 //So, all that's left to free here is the stack and the VirtProcr struc 1.500 // itself 1.501 - free( animatingPr->startOfStack ); 1.502 - free( animatingPr ); 1.503 + //Note, should not stack-allocate initial data -- no guarantee, in 1.504 + // general that creating processor will outlive ones it creates. 1.505 + VMS__free( animatingPr->startOfStack ); 1.506 + VMS__free( animatingPr ); 1.507 } 1.508 1.509 1.510 @@ -603,7 +656,7 @@ 1.511 //create the shutdown processors, one for each core loop -- put them 1.512 // directly into the Q -- each core will die when gets one 1.513 for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) 1.514 - { 1.515 + { //Note, this is running in the master 1.516 shutDownPr = VMS__create_procr( &endOSThreadFn, NULL ); 1.517 writeSRSWQ( shutDownPr, _VMSMasterEnv->readyToAnimateQs[coreIdx] ); 1.518 } 1.519 @@ -664,8 +717,8 @@ 1.520 for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ ) 1.521 { 1.522 freeSRSWQ( readyToAnimateQs[ coreIdx ] ); 1.523 - 1.524 - VMS__handle_dissipate_reqst( masterVPs[ coreIdx ] ); 1.525 + //master VPs were created external to VMS, so use external free 1.526 + VMS_ext__dissipate_procr( masterVPs[ coreIdx ] ); 1.527 1.528 freeSchedSlots( allSchedSlots[ coreIdx ] ); 1.529 } 1.530 @@ -673,20 +726,15 @@ 1.531 free( _VMSMasterEnv->readyToAnimateQs ); 1.532 free( _VMSMasterEnv->masterVPs ); 1.533 free( _VMSMasterEnv->allSchedSlots ); 1.534 + 1.535 + VMS_ext__free_free_list( _VMSMasterEnv->freeListHead ); 1.536 + 1.537 + //============================= MEASUREMENT STUFF ======================== 1.538 + #ifdef STATS__TURN_ON_PROBES 1.539 + freeDynArrayDeep( _VMSMasterEnv->dynIntervalProbesInfo, &free ); 1.540 + #endif 1.541 + //======================================================================== 1.542 1.543 free( _VMSMasterEnv ); 1.544 } 1.545 1.546 - 1.547 -//=========================================================================== 1.548 - 1.549 -inline TSCount getTSCount() 1.550 - { unsigned int low, high; 1.551 - TSCount out; 1.552 - 1.553 - saveTimeStampCountInto( low, high ); 1.554 - out = high; 1.555 - out = (out << 32) + low; 1.556 - return out; 1.557 - } 1.558 -
