Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
changeset 53:42dd44df1bb0
Init changed to only use VMS__malloc & uses VMS__malloc versions of utilities
| author | Me |
|---|---|
| date | Mon, 01 Nov 2010 21:21:32 -0700 |
| parents | f59cfa31a579 |
| children | f8508572f3de |
| files | CoreLoop.c MasterLoop.c VMS.c VMS.h probes.c probes.h vmalloc.c vmalloc.h |
| diffstat | 8 files changed, 219 insertions(+), 137 deletions(-) [+] |
line diff
1.1 --- a/CoreLoop.c Sat Oct 30 21:53:55 2010 -0700 1.2 +++ b/CoreLoop.c Mon Nov 01 21:21:32 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 @@ -158,7 +161,7 @@ 1.28 CoreLoopEndPt: 1.29 //first free shutdown VP that jumped here -- it first restores the 1.30 // coreloop's stack, so addr of currPr in stack frame is still correct 1.31 - VMS__handle_dissipate_reqst( currPr ); 1.32 + VMS__dissipate_procr( currPr ); 1.33 pthread_exit( NULL ); 1.34 } 1.35 1.36 @@ -206,17 +209,15 @@ 1.37 readyToAnimateQ = _VMSMasterEnv->readyToAnimateQs[thisCoresIdx]; 1.38 currPr = (VirtProcr *) readSRSWQ_NonBlocking( readyToAnimateQ ); 1.39 if( currPr == NULL ) 1.40 - { if( _VMSMasterEnv->numMasterInARow[thisCoresIdx] ) 1.41 - printf("back to back MasterVP\n"); 1.42 - _VMSMasterEnv->numMasterInARow[thisCoresIdx] = TRUE; 1.43 + { if( _VMSMasterEnv->numMasterInARow[thisCoresIdx] > 1000 ) 1.44 + { printf("too many back to back MasterVP\n"); exit(1); } 1.45 + _VMSMasterEnv->numMasterInARow[thisCoresIdx] += 1; 1.46 + 1.47 currPr = _VMSMasterEnv->masterVPs[thisCoresIdx]; 1.48 } 1.49 else 1.50 - _VMSMasterEnv->numMasterInARow[thisCoresIdx] = FALSE; 1.51 + _VMSMasterEnv->numMasterInARow[thisCoresIdx] = 0; 1.52 1.53 - PRINT2_DEBUG("core %d loop procr addr: %d\n",\ 1.54 - coreLoopThdParams->coreNum, \ 1.55 - (int)currPr ) 1.56 1.57 //switch to virt procr's stack and frame ptr then jump to virt procr 1.58 void *stackPtr, *framePtr, *jmpPt, *coreLoopFramePtrAddr, \ 1.59 @@ -259,6 +260,6 @@ 1.60 // all the threads to die will proceed, gather the result, and 1.61 // return to the calling application. 1.62 SeqCoreLoopEndPt: 1.63 - VMS__handle_dissipate_reqst( currPr ); //free shutdown pr, that jmpd here 1.64 + VMS__dissipate_procr( currPr ); //free shutdown pr, that jmpd here 1.65 return; 1.66 }
2.1 --- a/MasterLoop.c Sat Oct 30 21:53:55 2010 -0700 2.2 +++ b/MasterLoop.c Mon Nov 01 21:21:32 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 Sat Oct 30 21:53:55 2010 -0700 3.2 +++ b/VMS.c Mon Nov 01 21:21:32 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 @@ -301,7 +304,6 @@ 3.142 stackLocs = VMS__malloc( VIRT_PROCR_STACK_SIZE ); 3.143 if( stackLocs == 0 ) 3.144 { perror("VMS__malloc stack"); exit(1); } 3.145 - newPr->startOfStack = stackLocs; 3.146 3.147 return create_procr_helper( newPr, fnPtr, initialData, stackLocs ); 3.148 } 3.149 @@ -319,7 +321,6 @@ 3.150 stackLocs = malloc( VIRT_PROCR_STACK_SIZE ); 3.151 if( stackLocs == 0 ) 3.152 { perror("malloc stack"); exit(1); } 3.153 - newPr->startOfStack = stackLocs; 3.154 3.155 return create_procr_helper( newPr, fnPtr, initialData, stackLocs ); 3.156 } 3.157 @@ -445,7 +446,7 @@ 3.158 * pears -- making that suspend the last thing in the virt procr's trace. 3.159 */ 3.160 void 3.161 -VMS__dissipate_procr( VirtProcr *procrToDissipate ) 3.162 +VMS__send_dissipate_req( VirtProcr *procrToDissipate ) 3.163 { VMSReqst req; 3.164 3.165 req.reqType = dissipate; 3.166 @@ -477,18 +478,26 @@ 3.167 3.168 3.169 3.170 -/*This inserts the semantic-layer's request data into standard VMS carrier 3.171 - * request data-struct is allocated on stack of this call & ptr to it sent 3.172 - * to plugin 3.173 +/*This call's name indicates that request is malloc'd -- so req handler 3.174 + * has to free any extra requests tacked on before a send, using this. 3.175 + * 3.176 + * This inserts the semantic-layer's request data into standard VMS carrier 3.177 + * request data-struct that is mallocd. The sem request doesn't need to 3.178 + * be malloc'd if this is called inside the same call chain before the 3.179 + * send of the last request is called. 3.180 + * 3.181 + *The request handler has to call VMS__free_VMSReq for any of these 3.182 */ 3.183 inline void 3.184 -VMS__add_sem_request( void *semReqData, VirtProcr *callingPr ) 3.185 - { VMSReqst req; 3.186 +VMS__add_sem_request_in_mallocd_VMSReqst( void *semReqData, 3.187 + VirtProcr *callingPr ) 3.188 + { VMSReqst *req; 3.189 3.190 - req.reqType = semantic; 3.191 - req.semReqData = semReqData; 3.192 - req.nextReqst = callingPr->requests; 3.193 - callingPr->requests = &req; 3.194 + req = VMS__malloc( sizeof(VMSReqst) ); 3.195 + req->reqType = semantic; 3.196 + req->semReqData = semReqData; 3.197 + req->nextReqst = callingPr->requests; 3.198 + callingPr->requests = req; 3.199 } 3.200 3.201 /*This inserts the semantic-layer's request data into standard VMS carrier 3.202 @@ -573,10 +582,12 @@ 3.203 memcpy( newProbe->nameStr, semReq->nameStr, nameLen ); 3.204 newProbe->hist = NULL; 3.205 newProbe->schedChoiceWasRecorded = FALSE; 3.206 + 3.207 + //This runs in masterVP, so no race-condition worries 3.208 newProbe->probeID = 3.209 addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo ); 3.210 3.211 - requestingPr->dataReturnedFromReq = newProbe; 3.212 + requestingPr->dataRetFromReq = newProbe; 3.213 3.214 (*resumePrFnPtr)( requestingPr, semEnv ); 3.215 } 3.216 @@ -601,7 +612,7 @@ 3.217 * of dis-owning it. 3.218 */ 3.219 void 3.220 -VMS__handle_dissipate_reqst( VirtProcr *animatingPr ) 3.221 +VMS__dissipate_procr( VirtProcr *animatingPr ) 3.222 { 3.223 //dis-own all locations owned by this processor, causing to be freed 3.224 // any locations that it is (was) sole owner of 3.225 @@ -619,15 +630,13 @@ 3.226 } 3.227 3.228 3.229 -//TODO: re-architect so that have clean separation between request handler 3.230 +//TODO: look at architecting cleanest separation between request handler 3.231 // and master loop, for dissipate, create, shutdown, and other non-semantic 3.232 // requests. Issue is chain: one removes requests from AppVP, one dispatches 3.233 // on type of request, and one handles each type.. but some types require 3.234 // action from both request handler and master loop -- maybe just give the 3.235 // request handler calls like: VMS__handle_X_request_type 3.236 3.237 -void 3.238 -endOSThreadFn( void *initData, VirtProcr *animatingPr ); 3.239 3.240 /*This is called by the semantic layer's request handler when it decides its 3.241 * time to shut down the VMS system. Calling this causes the core loop OS 3.242 @@ -641,10 +650,9 @@ 3.243 * masterVP any AppVPs that might still be allocated and sitting in the 3.244 * semantic environment, or have been orphaned in the _VMSWorkQ. 3.245 * 3.246 - *NOTE: the semantic plug-in is expected to use VMS__malloc_to to get all the 3.247 + *NOTE: the semantic plug-in is expected to use VMS__malloc to get all the 3.248 * locations it needs, and give ownership to masterVP. Then, they will be 3.249 - * automatically freed when the masterVP is dissipated. (This happens after 3.250 - * the core loop threads have all exited) 3.251 + * automatically freed. 3.252 * 3.253 *In here,create one core-loop shut-down processor for each core loop and put 3.254 * them all directly into the readyToAnimateQ. 3.255 @@ -655,7 +663,7 @@ 3.256 * point is it sure that all results have completed. 3.257 */ 3.258 void 3.259 -VMS__handle_shutdown_reqst( void *dummy, VirtProcr *animatingPr ) 3.260 +VMS__shutdown() 3.261 { int coreIdx; 3.262 VirtProcr *shutDownPr; 3.263 3.264 @@ -703,19 +711,19 @@ 3.265 } 3.266 3.267 3.268 -/*This is called after the threads have shut down and control has returned 3.269 - * to the semantic layer, in the entry point function in the main thread. 3.270 - * It has to free anything allocated during VMS_init, and any other alloc'd 3.271 - * locations that might be left over. 3.272 +/*This is called from the startup & shutdown 3.273 */ 3.274 void 3.275 -VMS__cleanup_after_shutdown() 3.276 +VMS__cleanup_at_end_of_shutdown() 3.277 { 3.278 SRSWQueueStruc **readyToAnimateQs; 3.279 int coreIdx; 3.280 VirtProcr **masterVPs; 3.281 SchedSlot ***allSchedSlots; //ptr to array of ptrs 3.282 3.283 + //All the environment data has been allocated with VMS__malloc, so just 3.284 + // free its internal big-chunk and all inside it disappear. 3.285 +/* 3.286 readyToAnimateQs = _VMSMasterEnv->readyToAnimateQs; 3.287 masterVPs = _VMSMasterEnv->masterVPs; 3.288 allSchedSlots = _VMSMasterEnv->allSchedSlots; 3.289 @@ -724,23 +732,23 @@ 3.290 { 3.291 freeSRSWQ( readyToAnimateQs[ coreIdx ] ); 3.292 //master VPs were created external to VMS, so use external free 3.293 - VMS_ext__dissipate_procr( masterVPs[ coreIdx ] ); 3.294 + VMS__dissipate_procr( masterVPs[ coreIdx ] ); 3.295 3.296 freeSchedSlots( allSchedSlots[ coreIdx ] ); 3.297 } 3.298 3.299 - free( _VMSMasterEnv->readyToAnimateQs ); 3.300 - free( _VMSMasterEnv->masterVPs ); 3.301 - free( _VMSMasterEnv->allSchedSlots ); 3.302 + VMS__free( _VMSMasterEnv->readyToAnimateQs ); 3.303 + VMS__free( _VMSMasterEnv->masterVPs ); 3.304 + VMS__free( _VMSMasterEnv->allSchedSlots ); 3.305 3.306 - VMS_ext__free_free_list( _VMSMasterEnv->freeListHead ); 3.307 - 3.308 //============================= MEASUREMENT STUFF ======================== 3.309 #ifdef STATS__TURN_ON_PROBES 3.310 - freeDynArrayDeep( _VMSMasterEnv->dynIntervalProbesInfo, &free ); 3.311 + freeDynArrayDeep( _VMSMasterEnv->dynIntervalProbesInfo, &VMS__free_probe); 3.312 #endif 3.313 //======================================================================== 3.314 - 3.315 - free( _VMSMasterEnv ); 3.316 +*/ 3.317 + //These are the only two that use system free 3.318 + VMS_ext__free_free_list( _VMSMasterEnv->freeListHead ); 3.319 + free( (void *)_VMSMasterEnv ); 3.320 } 3.321
4.1 --- a/VMS.h Sat Oct 30 21:53:55 2010 -0700 4.2 +++ b/VMS.h Mon Nov 01 21:21:32 2010 -0700 4.3 @@ -65,7 +65,7 @@ 4.4 4.5 #define MIN_WORK_UNIT_CYCLES 20000 4.6 4.7 -#define READYTOANIMATE_RETRIES 10000 4.8 +#define MASTERLOCK_RETRIES 10000 4.9 4.10 // stack 4.11 #define VIRT_PROCR_STACK_SIZE 0x4000 4.12 @@ -163,7 +163,7 @@ 4.13 VMSReqst *requests; 4.14 4.15 void *semanticData; //this lives here for the life of VP 4.16 - void *dataReturnedFromReq;//values returned from plugin to VP go here 4.17 + void *dataRetFromReq;//values returned from plugin to VP go here 4.18 4.19 //=========== MEASUREMENT STUFF ========== 4.20 #ifdef MEAS__TIME_STAMP_SUSP 4.21 @@ -205,7 +205,7 @@ 4.22 4.23 //=========== MEASUREMENT STUFF ============= 4.24 IntervalProbe **intervalProbes; 4.25 - DynArrayInfo *dynIntervalProbesInfo; 4.26 + PrivDynArrayInfo *dynIntervalProbesInfo; 4.27 HashTable *probeNameHashTbl; 4.28 int32 masterCreateProbeID; 4.29 float64 createPtInSecs; 4.30 @@ -245,7 +245,8 @@ 4.31 4.32 //=========================== Function Prototypes ========================= 4.33 4.34 -//============== Setup and shutdown ============= 4.35 + 4.36 +//========== Setup and shutdown ========== 4.37 void 4.38 VMS__init(); 4.39 4.40 @@ -261,16 +262,22 @@ 4.41 VirtProcr * 4.42 VMS__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); 4.43 4.44 +void 4.45 +VMS__dissipate_procr( VirtProcr *procrToDissipate ); 4.46 + 4.47 //Use this to create processor inside entry point & other places outside 4.48 // the VMS system boundary (IE, not run in slave nor Master) 4.49 VirtProcr * 4.50 VMS_ext__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); 4.51 4.52 -VirtProcr * 4.53 -VMS__create_the_shutdown_procr(); 4.54 +void 4.55 +VMS_ext__dissipate_procr( VirtProcr *procrToDissipate ); 4.56 4.57 void 4.58 -VMS__cleanup_after_shutdown(); 4.59 +VMS__shutdown(); 4.60 + 4.61 +void 4.62 +VMS__cleanup_at_end_of_shutdown(); 4.63 4.64 4.65 //============== Request Related =============== 4.66 @@ -279,49 +286,31 @@ 4.67 VMS__suspend_procr( VirtProcr *callingPr ); 4.68 4.69 inline void 4.70 -VMS__add_sem_request( void *semReqData, VirtProcr *callingPr ); 4.71 +VMS__add_sem_request_in_mallocd_VMSReqst( void *semReqData, VirtProcr *callingPr ); 4.72 + 4.73 +inline void 4.74 +VMS__send_sem_request( void *semReqData, VirtProcr *callingPr ); 4.75 4.76 void 4.77 VMS__send_create_procr_req( void *semReqData, VirtProcr *reqstingPr ); 4.78 4.79 +void inline 4.80 +VMS__send_dissipate_req( VirtProcr *prToDissipate ); 4.81 + 4.82 inline void 4.83 VMS__send_VMSSem_request( void *semReqData, VirtProcr *callingPr ); 4.84 4.85 -void 4.86 -VMS__free_request( VMSReqst *req ); 4.87 - 4.88 -void 4.89 -VMS__remove_and_free_top_request( VirtProcr *reqstingPr ); 4.90 - 4.91 VMSReqst * 4.92 VMS__take_next_request_out_of( VirtProcr *procrWithReq ); 4.93 4.94 inline void * 4.95 VMS__take_sem_reqst_from( VMSReqst *req ); 4.96 -// 4.97 -//VMSReqst * 4.98 -//VMS__take_top_request_from( VirtProcr *reqstingPr ); 4.99 -// 4.100 -//inline int 4.101 -//VMS__isSemanticReqst( VMSReqst *req ); 4.102 -// 4.103 -//inline int 4.104 -//VMS__isDissipateReqst( VMSReqst *req ); 4.105 -// 4.106 -//inline int 4.107 -//VMS__isCreateReqst( VMSReqst *req ); 4.108 4.109 -//========================== 4.110 4.111 -void inline 4.112 -VMS__dissipate_procr( VirtProcr *prToDissipate ); 4.113 4.114 -void 4.115 -VMS__handle_dissipate_reqst( VirtProcr *procrToDissipate ); 4.116 +//======================== STATS ====================== 4.117 4.118 - 4.119 - 4.120 -//===================== RDTSC wrapper ================== 4.121 +//===== RDTSC wrapper ===== 4.122 4.123 #define saveTimeStampCountInto(low, high) \ 4.124 asm volatile("RDTSC; \ 4.125 @@ -339,8 +328,7 @@ 4.126 /* inputs */ : \ 4.127 /* clobber */ : "%eax", "%edx" \ 4.128 ); 4.129 - 4.130 -//======================== STATS ====================== 4.131 +//===== 4.132 4.133 #include "probes.h" 4.134
5.1 --- a/probes.c Sat Oct 30 21:53:55 2010 -0700 5.2 +++ b/probes.c Mon Nov 01 21:21:32 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
6.1 --- a/probes.h Sat Oct 30 21:53:55 2010 -0700 6.2 +++ b/probes.h Mon Nov 01 21:21:32 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 Sat Oct 30 21:53:55 2010 -0700 7.2 +++ b/vmalloc.c Mon Nov 01 21:21:32 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 Sat Oct 30 21:53:55 2010 -0700 8.2 +++ b/vmalloc.h Mon Nov 01 21:21:32 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 );
