Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
changeset 24:2b161e1a50ee
1st working version -- as far as can tell due to SEH bugs
| author | Me |
|---|---|
| date | Wed, 07 Jul 2010 13:15:54 -0700 |
| parents | aa634ef7cc35 |
| children | c556193f7211 |
| files | CoreLoop.c VMS.c VMS.h |
| diffstat | 3 files changed, 203 insertions(+), 80 deletions(-) [+] |
line diff
1.1 --- a/CoreLoop.c Wed Jun 30 13:11:06 2010 -0700 1.2 +++ b/CoreLoop.c Wed Jul 07 13:15:54 2010 -0700 1.3 @@ -33,21 +33,12 @@ 1.4 //Designate a core by a 1 in bit-position corresponding to the core 1.5 SetThreadAffinityMask(GetCurrentThread(),1 << coreLoopThdParams->coreNum); 1.6 1.7 - //Save the stack pointer and frame pointer of this coreLoop's thread 1.8 -// asm volatile("movl %%ebp, %0; \ 1.9 - movl %%esp, %1; "\ 1.10 - /* outputs */ : "=m" (coreLoopThdParams->framePtr), \ 1.11 - "=m" (coreLoopThdParams->stackPtr) \ 1.12 - /* inputs */ : \ 1.13 - ); 1.14 1.15 //Save addr of "end core loop" label - jump to it to shut down coreloop 1.16 //To get label addr in non-gcc compiler, can trick it by making a call 1.17 // to a fn that does asm that pulls the "return" 1.18 // addr off the stack and stores it in a pointed-to location. 1.19 - coreLoopThdParams->endThdPt = &&EndCoreLoop; 1.20 - _VMSMasterEnv->coreLoopShutDownPt = &&EndCoreLoop; //haven't decided yet 1.21 - //which way will do shutdown of core loops 1.22 + _VMSMasterEnv->coreLoopShutDownPt = &&EndCoreLoop; 1.23 1.24 //Core loop has no values live upon CoreLoopStartPt except workQ 1.25 // every value in the code is defined by a statement in core loop, 1.26 @@ -65,7 +56,9 @@ 1.27 workQ = _VMSWorkQ; 1.28 currPr = (VirtProcr *) readCASQ( workQ ); 1.29 1.30 - currPr->coreLoopStartPt = &&CoreLoopStartPt; //just to be sure.(GCC spec) 1.31 +// printf("core %d loop procr addr: %d\n", coreLoopThdParams->coreNum, \ 1.32 + (int)currPr ); fflush(stdin); 1.33 + currPr->coreLoopStartPt = &&CoreLoopStartPt; //to be sure.(GCC specific) 1.34 1.35 currPr->coreAnimatedBy = coreLoopThdParams->coreNum; 1.36 1.37 @@ -88,7 +81,6 @@ 1.38 //Explicitly loading into eax before changing frame-ptr fixed it 1.39 //Also, it turns "(currPr->coreLoopFramePtr)" into a temporary on the 1.40 // stack, so "movl %%ebp, %0" saves to the temp, NOT the data-struc! 1.41 -//coreLoop 1.42 asm volatile("movl %0, %%eax; \ 1.43 movl %%esp, (%%eax); \ 1.44 movl %1, %%eax; \
2.1 --- a/VMS.c Wed Jun 30 13:11:06 2010 -0700 2.2 +++ b/VMS.c Wed Jul 07 13:15:54 2010 -0700 2.3 @@ -71,12 +71,34 @@ 2.4 masterEnv->schedSlots[0]->workIsDone = FALSE; //says don't touch 2.5 masterEnv->schedSlots[0]->procrAssignedToSlot = masterEnv->masterVirtPr; 2.6 masterEnv->masterVirtPr->schedSlot = masterEnv->schedSlots[0]; 2.7 + masterEnv->stillRunning = FALSE; 2.8 2.9 //First core loop to start up gets this, which will schedule seed Pr 2.10 //TODO: debug: check address of masterVirtPr 2.11 writeCASQ( masterEnv->masterVirtPr, workQ ); 2.12 2.13 numProcrsCreated = 1; 2.14 + 2.15 + //======================================================================== 2.16 + // Create the Threads 2.17 + int coreIdx; 2.18 + 2.19 + //Make params given to the win threads that animate the core loops 2.20 + for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) 2.21 + { coreLoopThdParams[coreIdx] = malloc( sizeof(ThdParams) ); 2.22 + coreLoopThdParams[coreIdx]->coreNum = coreIdx; 2.23 + 2.24 + //make the core loop threads, born in suspended state 2.25 + coreLoopThdHandles[ coreIdx ] = 2.26 + CreateThread ( NULL, // Security attributes 2.27 + 0, // Stack size 2.28 + coreLoop, 2.29 + coreLoopThdParams[coreIdx], 2.30 + CREATE_SUSPENDED, 2.31 + &(coreLoopThdIds[coreIdx]) 2.32 + ); 2.33 + } 2.34 + 2.35 } 2.36 2.37 2.38 @@ -103,30 +125,44 @@ 2.39 2.40 /*Semantic layer calls this when it want the system to start running.. 2.41 * 2.42 - *This creates the core loops, pins them to physical cores, gives them the 2.43 - * pointer to the workQ, and starts them running. 2.44 + *This starts the core loops running then waits for them to exit. 2.45 */ 2.46 void 2.47 -VMS__start() 2.48 +VMS__start_the_work_then_wait_until_done() 2.49 { int coreIdx; 2.50 + //Start the core loops running 2.51 +//=========================================================================== 2.52 + LARGE_INTEGER stPerfCount, endPerfCount, countFreq; 2.53 + unsigned long long count = 0, freq = 0; 2.54 + double runTime; 2.55 2.56 - //TODO: Save "orig" stack pointer and frame ptr -- restore in VMS__end() 2.57 - //Create the win threads that animate the core loops 2.58 + QueryPerformanceCounter( &stPerfCount ); 2.59 + 2.60 + //start them running 2.61 + for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) 2.62 + { //Create the threads 2.63 + ResumeThread( coreLoopThdHandles[coreIdx] ); //starts thread 2.64 + } 2.65 + 2.66 + //wait for all to complete 2.67 for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) 2.68 { 2.69 - coreLoopThdParams[coreIdx] = (ThdParams *)malloc( sizeof(ThdParams) ); 2.70 - coreLoopThdParams[coreIdx]->coreNum = coreIdx; 2.71 + WaitForSingleObject(coreLoopThdHandles[coreIdx], INFINITE); 2.72 + } 2.73 2.74 - coreLoopThdHandles[coreIdx] = 2.75 - CreateThread ( NULL, // Security attributes 2.76 - 0, // Stack size 2.77 - coreLoop, 2.78 - coreLoopThdParams[coreIdx], 2.79 - CREATE_SUSPENDED, 2.80 - &(coreLoopThdIds[coreIdx]) 2.81 - ); 2.82 - ResumeThread( coreLoopThdHandles[coreIdx] ); //starts thread 2.83 - } 2.84 + //NOTE: do not clean up VMS env here -- semantic layer has to have 2.85 + // a chance to clean up its environment first, then do a call to free 2.86 + // the Master env and rest of VMS locations 2.87 + 2.88 + QueryPerformanceCounter( &endPerfCount ); 2.89 + count = endPerfCount.QuadPart - stPerfCount.QuadPart; 2.90 + 2.91 + QueryPerformanceFrequency( &countFreq ); 2.92 + freq = countFreq.QuadPart; 2.93 + runTime = (double)count / (double)freq; 2.94 + 2.95 + printf("\n Time startup to shutdown: %f\n", runTime); 2.96 + fflush( stdin ); 2.97 } 2.98 2.99 2.100 @@ -283,7 +319,7 @@ 2.101 /*This inserts the semantic-layer's request data into standard VMS carrier 2.102 */ 2.103 inline void 2.104 -VMS__send_sem_request( void *semReqData, VirtProcr *callingPr ) 2.105 +VMS__add_sem_request( void *semReqData, VirtProcr *callingPr ) 2.106 { VMSReqst *req; 2.107 2.108 req = malloc( sizeof(VMSReqst) ); 2.109 @@ -295,20 +331,6 @@ 2.110 } 2.111 2.112 2.113 -/*This creates a request of type "dissipate" -- which will cause the virt 2.114 - * processor's state and owned locations to be freed 2.115 - */ 2.116 -inline void 2.117 -VMS__send_dissipate_request( VirtProcr *procrToDissipate ) 2.118 - { VMSReqst *req; 2.119 - 2.120 - req = malloc( sizeof(VMSReqst) ); 2.121 -// req->virtProcrFrom = callingPr; 2.122 - req->reqType = dissipate; 2.123 - req->nextReqst = procrToDissipate->requests; 2.124 - procrToDissipate->requests = req; 2.125 - } 2.126 - 2.127 2.128 //TODO: add a semantic-layer supplied "freer" for the semantic-data portion 2.129 // of a request -- IE call with both a virt procr and a fn-ptr to request 2.130 @@ -322,36 +344,63 @@ 2.131 free( req ); 2.132 } 2.133 2.134 -/*This must be called by the request handler plugin -- it cannot be called 2.135 - * from the semantic library "dissipate processor" function -- instead, the 2.136 - * semantic layer has to generate a request for the plug-in to call this 2.137 - * function. 2.138 - *The reason is that this frees the virtual processor's stack -- which is 2.139 - * still in use inside semantic library calls! 2.140 - * 2.141 - *This frees or recycles all the state owned by and comprising the animating 2.142 - * virtual procr. It frees any state that was malloc'd by the VMS system 2.143 - * itself, and asks the VMS system to dis-own any VMS__malloc'd locations. 2.144 - *If the dissipated processor is the sole (remaining) owner of VMS__malloc'd 2.145 - * state, then that state gets freed (or sent to recycling) as a side-effect 2.146 - * of dis-owning it. 2.147 - */ 2.148 + 2.149 +//TODO: add a semantic-layer supplied "freer" for the semantic-data portion 2.150 +// of a request -- IE call with both a virt procr and a fn-ptr to request 2.151 +// freer (also maybe put sem request freer as a field in virt procr?) 2.152 void 2.153 -VMS__free_procr_locs( VirtProcr *animatingPr ) 2.154 +VMS__free_request( VMSReqst *req ) 2.155 + { 2.156 + free( req ); 2.157 + } 2.158 + 2.159 +VMSReqst * 2.160 +VMS__take_top_request_from( VirtProcr *procrWithReq ) 2.161 + { VMSReqst *req; 2.162 + 2.163 + req = procrWithReq->requests; 2.164 + if( req == NULL ) return req; 2.165 + 2.166 + procrWithReq->requests = procrWithReq->requests->nextReqst; 2.167 + return req; 2.168 + } 2.169 + 2.170 +inline int 2.171 +VMS__isSemanticReqst( VMSReqst *req ) 2.172 { 2.173 - //dis-own all locations owned by this processor, causing to be freed 2.174 - // any locations that it is (was) sole owner of 2.175 - //TODO: implement VMS__malloc system, including "give up ownership" 2.176 + return ( req->reqType == semantic ); 2.177 + } 2.178 2.179 - VMS__remove_and_free_top_request( animatingPr ); 2.180 - free( animatingPr->startOfStack ); 2.181 - 2.182 - //NOTE: animatingPr->semanticData should either have been allocated 2.183 - // with VMS__malloc, or else freed in the request handler plug-in. 2.184 - //NOTE: initialData was given to the processor, so should either have 2.185 - // been alloc'd with VMS__malloc, or freed by the level above animPr. 2.186 - //So, all that's left to free here is the VirtProcr struc itself 2.187 - free( animatingPr ); 2.188 + 2.189 +inline void * 2.190 +VMS__take_sem_reqst_from( VMSReqst *req ) 2.191 + { 2.192 + return req->semReqData; 2.193 + } 2.194 + 2.195 +inline int 2.196 +VMS__isDissipateReqst( VMSReqst *req ) 2.197 + { 2.198 + return ( req->reqType == dissipate ); 2.199 + } 2.200 + 2.201 +inline int 2.202 +VMS__isCreateReqst( VMSReqst *req ) 2.203 + { 2.204 + return ( req->reqType == regCreated ); 2.205 + } 2.206 + 2.207 +void 2.208 +VMS__send_register_new_procr_request(VirtProcr *newPr, VirtProcr *reqstingPr) 2.209 + { VMSReqst *req; 2.210 + 2.211 + req = malloc( sizeof(VMSReqst) ); 2.212 + req->reqType = regCreated; 2.213 + req->semReqData = newPr; 2.214 + req->nextReqst = reqstingPr->requests; 2.215 + reqstingPr->requests = req; 2.216 + 2.217 + VMS__suspend_procr( reqstingPr ); 2.218 } 2.219 2.220 2.221 @@ -384,6 +433,44 @@ 2.222 } 2.223 2.224 2.225 +/*This must be called by the request handler plugin -- it cannot be called 2.226 + * from the semantic library "dissipate processor" function -- instead, the 2.227 + * semantic layer has to generate a request for the plug-in to call this 2.228 + * function. 2.229 + *The reason is that this frees the virtual processor's stack -- which is 2.230 + * still in use inside semantic library calls! 2.231 + * 2.232 + *This frees or recycles all the state owned by and comprising the VMS 2.233 + * portion of the animating virtual procr. The request handler must first 2.234 + * free any semantic data created for the processor that didn't use the 2.235 + * VMS_malloc mechanism. Then it calls this, which first asks the malloc 2.236 + * system to disown any state that did use VMS_malloc, and then frees the 2.237 + * statck and the processor-struct itself. 2.238 + *If the dissipated processor is the sole (remaining) owner of VMS__malloc'd 2.239 + * state, then that state gets freed (or sent to recycling) as a side-effect 2.240 + * of dis-owning it. 2.241 + */ 2.242 +void 2.243 +VMS__free_procr_locs( VirtProcr *animatingPr ) 2.244 + { 2.245 + //dis-own all locations owned by this processor, causing to be freed 2.246 + // any locations that it is (was) sole owner of 2.247 + //TODO: implement VMS__malloc system, including "give up ownership" 2.248 + 2.249 + //The dissipate request might still be attached, so remove and free it 2.250 + VMS__remove_and_free_top_request( animatingPr ); 2.251 + free( animatingPr->startOfStack ); 2.252 + 2.253 + //NOTE: initialData was given to the processor, so should either have 2.254 + // been alloc'd with VMS__malloc, or freed by the level above animPr. 2.255 + //So, all that's left to free here is the stack and the VirtProcr struc 2.256 + // itself 2.257 + free( animatingPr->startOfStack ); 2.258 + free( animatingPr ); 2.259 + } 2.260 + 2.261 + 2.262 + 2.263 /*This is the function run by the special "shut-down" processor 2.264 * 2.265 *The _VMSMasterEnv is needed by this shut down function, so the "wait" 2.266 @@ -422,11 +509,32 @@ 2.267 // get its request handled before all the cores have shutdown. 2.268 //TODO: after all the threads stop, clean out the MasterEnv, the 2.269 // SemanticEnv, and the workQ before returning. 2.270 - VMS__send_dissipate_request( animatingPr ); 2.271 - VMS__suspend_procr( animatingPr ); //will never come back from this 2.272 + VMS__dissipate_procr( animatingPr ); //will never come back from this 2.273 } 2.274 2.275 2.276 +/*This has to free anything allocated during VMS_init, and any other alloc'd 2.277 + * locations that might be left over. 2.278 + */ 2.279 +void 2.280 +VMS__shutdown() 2.281 + { int i; 2.282 + 2.283 + free( _VMSWorkQ ); 2.284 + free( _VMSMasterEnv->filledSlots ); 2.285 + for( i = 0; i < NUM_SCHED_SLOTS; i++ ) 2.286 + { 2.287 + free( _VMSMasterEnv->schedSlots[i] ); 2.288 + } 2.289 + 2.290 + free( _VMSMasterEnv->schedSlots); 2.291 + VMS__free_procr_locs( _VMSMasterEnv->masterVirtPr ); 2.292 + 2.293 + free( _VMSMasterEnv ); 2.294 + } 2.295 + 2.296 + 2.297 +//=========================================================================== 2.298 2.299 inline TSCount getTSCount() 2.300 { unsigned int low, high;
3.1 --- a/VMS.h Wed Jun 30 13:11:06 2010 -0700 3.2 +++ b/VMS.h Wed Jul 07 13:15:54 2010 -0700 3.3 @@ -29,7 +29,7 @@ 3.4 //#define thdAttrs NULL //For PThreads 3.5 3.6 typedef struct _SchedSlot SchedSlot; 3.7 -typedef struct _SlaveReqst VMSReqst; 3.8 +typedef struct _VMSReqst VMSReqst; 3.9 typedef struct _VirtProcr VirtProcr; 3.10 3.11 typedef VirtProcr * (*SlaveScheduler) ( void * ); //semEnv 3.12 @@ -59,18 +59,19 @@ 3.13 { 3.14 semantic = 1, 3.15 dissipate, 3.16 + regCreated, 3.17 IO 3.18 }; 3.19 3.20 -struct _SlaveReqst 3.21 +struct _VMSReqst 3.22 { 3.23 // VirtProcr *virtProcrFrom; 3.24 - enum ReqstType reqType; //used for dissipate and in future for IO requests 3.25 + enum ReqstType reqType;//used for dissipate and in future for IO requests 3.26 void *semReqData; 3.27 3.28 VMSReqst *nextReqst; 3.29 }; 3.30 -//SlaveReqst 3.31 +//VMSReqst 3.32 3.33 struct _VirtProcr 3.34 { int procrID; //for debugging -- count up each time create 3.35 @@ -142,7 +143,7 @@ 3.36 VMS__init(); 3.37 3.38 void 3.39 -VMS__start(); 3.40 +VMS__start_the_work_then_wait_until_done(); 3.41 3.42 VirtProcr * 3.43 VMS__create_procr( VirtProcrFnPtr fnPtr, void *initialData ); 3.44 @@ -150,15 +151,37 @@ 3.45 VirtProcr * 3.46 VMS__create_the_shutdown_procr(); 3.47 3.48 +//========================== 3.49 inline void 3.50 -VMS__send_sem_request( void *semReqData, VirtProcr *callingPr ); 3.51 +VMS__add_sem_request( void *semReqData, VirtProcr *callingPr ); 3.52 3.53 void 3.54 -VMS__send_dissipate_request( VirtProcr *procrToDissipate ); 3.55 +VMS__send_register_new_procr_request( VirtProcr *newPrToRegister, 3.56 + VirtProcr *reqstingPr ); 3.57 + 3.58 +void 3.59 +VMS__free_request( VMSReqst *req ); 3.60 3.61 void 3.62 VMS__remove_and_free_top_request( VirtProcr *reqstingPr ); 3.63 3.64 +VMSReqst * 3.65 +VMS__take_top_request_from( VirtProcr *reqstingPr ); 3.66 + 3.67 +inline void * 3.68 +VMS__take_sem_reqst_from( VMSReqst *req ); 3.69 + 3.70 +inline int 3.71 +VMS__isSemanticReqst( VMSReqst *req ); 3.72 + 3.73 +inline int 3.74 +VMS__isDissipateReqst( VMSReqst *req ); 3.75 + 3.76 +inline int 3.77 +VMS__isCreateReqst( VMSReqst *req ); 3.78 + 3.79 +//========================== 3.80 + 3.81 void 3.82 VMS__suspend_procr( VirtProcr *callingPr ); 3.83
