Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
diff VMS.c @ 29:0e008278fe3c
Works Sequentially -- took out all threads and debugged -- works
| author | Me |
|---|---|
| date | Wed, 28 Jul 2010 13:12:10 -0700 |
| parents | 8b9e4c333fe6 |
| children | c8823e0bb2b4 |
line diff
1.1 --- a/VMS.c Mon Jul 26 16:42:59 2010 -0700 1.2 +++ b/VMS.c Wed Jul 28 13:12:10 2010 -0700 1.3 @@ -389,8 +389,9 @@ 1.4 { VMSReqst *req; 1.5 1.6 req = procrWithReq->requests; 1.7 + if( req == NULL ) return; 1.8 procrWithReq->requests = procrWithReq->requests->nextReqst; 1.9 - free( req ); 1.10 + VMS__free_request( req ); 1.11 } 1.12 1.13 1.14 @@ -455,34 +456,6 @@ 1.15 } 1.16 1.17 1.18 -/*The semantic layer figures out when the work is done ( perhaps by a call 1.19 - * in the application to "work all done", or perhaps all the virtual 1.20 - * processors have dissipated.. a.s.o. ) 1.21 - * 1.22 - *The semantic layer is responsible for making sure all work has fully 1.23 - * completed before using this to shutdown the VMS system. 1.24 - * 1.25 - *After the semantic layer has determined it wants to shut down, the 1.26 - * next time the Master Loop calls the scheduler plug-in, the scheduler 1.27 - * then calls this function and returns the virtual processor it gets back. 1.28 - * 1.29 - *When the shut-down processor runs, it first frees all locations malloc'd to 1.30 - * the VMS system (that wasn't 1.31 - * specified as return-locations). Then it creates one core-loop shut-down 1.32 - * processor for each core loop and puts them all into the workQ. When a 1.33 - * core loop animates a core loop shut-down processor, it causes exit-thread 1.34 - * to run, and when all core loop threads have exited, then the "wait for 1.35 - * work to finish" in the main thread is woken, and the function-call that 1.36 - * started all the work returns. 1.37 - * 1.38 - *The function animated by this processor performs the shut-down work. 1.39 - */ 1.40 -VirtProcr * 1.41 -VMS__create_the_shutdown_procr() 1.42 - { 1.43 - return VMS__create_procr( &shutdownFn, NULL ); 1.44 - } 1.45 - 1.46 1.47 /*This must be called by the request handler plugin -- it cannot be called 1.48 * from the semantic library "dissipate processor" function -- instead, the 1.49 @@ -502,15 +475,14 @@ 1.50 * of dis-owning it. 1.51 */ 1.52 void 1.53 -VMS__free_procr_locs( VirtProcr *animatingPr ) 1.54 +VMS__handle_dissipate_reqst( VirtProcr *animatingPr ) 1.55 { 1.56 //dis-own all locations owned by this processor, causing to be freed 1.57 // any locations that it is (was) sole owner of 1.58 - //TODO: implement VMS__malloc system, including "give up ownership" 1.59 +//TODO: implement VMS__malloc system, including "give up ownership" 1.60 1.61 //The dissipate request might still be attached, so remove and free it 1.62 VMS__remove_and_free_top_request( animatingPr ); 1.63 - free( animatingPr->startOfStack ); 1.64 1.65 //NOTE: initialData was given to the processor, so should either have 1.66 // been alloc'd with VMS__malloc, or freed by the level above animPr. 1.67 @@ -521,54 +493,98 @@ 1.68 } 1.69 1.70 1.71 +//TODO: re-architect so that have clean separation between request handler 1.72 +// and master loop, for dissipate, create, shutdown, and other non-semantic 1.73 +// requests. Issue is chain: one removes requests from AppVP, one dispatches 1.74 +// on type of request, and one handles each type.. but some types require 1.75 +// action from both request handler and master loop -- maybe just give the 1.76 +// request handler calls like: VMS__handle_X_request_type 1.77 1.78 -/*This is the function run by the special "shut-down" processor 1.79 +void 1.80 +endOSThreadFn( void *initData, VirtProcr *animatingPr ); 1.81 + 1.82 +/*This is called by the semantic layer's request handler when it decides its 1.83 + * time to shut down the VMS system. Calling this causes the core loop OS 1.84 + * threads to exit, which unblocks the entry-point function that started up 1.85 + * VMS, and allows it to grab the result and return to the original single- 1.86 + * threaded application. 1.87 * 1.88 - *The _VMSMasterEnv is needed by this shut down function, so the "wait" 1.89 - * function run in the main loop has to free it, and the thread-related 1.90 - * locations (coreLoopThdParams a.s.o.). 1.91 - *However, the semantic environment and all data malloc'd to VMS can be 1.92 - * freed here. 1.93 + *The _VMSMasterEnv is needed by this shut down function, so the create-seed- 1.94 + * and-wait function has to free a bunch of stuff after it detects the 1.95 + * threads have all died: the masterEnv, the thread-related locations, 1.96 + * masterVP any AppVPs that might still be allocated and sitting in the 1.97 + * semantic environment, or have been orphaned in the _VMSWorkQ. 1.98 + * 1.99 + *NOTE: the semantic plug-in is expected to use VMS__malloc_to to get all the 1.100 + * locations it needs, and give ownership to masterVP. Then, they will be 1.101 + * automatically freed when the masterVP is dissipated. (This happens after 1.102 + * the core loop threads have all exited) 1.103 * 1.104 - *NOTE: the semantic plug-in is expected to use VMS__malloc to get all the 1.105 - * locations it needs -- they will be automatically freed by the standard 1.106 - * "free all owned locations" 1.107 - * 1.108 - *Free any locations malloc'd to the VMS system (that weren't 1.109 - * specified as return-locations). 1.110 - *Then create one core-loop shut-down processor for each core loop and puts 1.111 - * them all into the workQ. 1.112 + *In here,create one core-loop shut-down processor for each core loop and put 1.113 + * them all directly into the workQ. 1.114 + *Note, this function can ONLY be called after the semantic environment no 1.115 + * longer cares if AppVPs get animated after the point this is called. In 1.116 + * other words, this can be used as an abort, or else it should only be 1.117 + * called when all AppVPs have finished dissipate requests -- only at that 1.118 + * point is it sure that all results have completed. 1.119 */ 1.120 void 1.121 -shutdownFn( void *dummy, VirtProcr *animatingPr ) 1.122 +VMS__handle_shutdown_reqst( void *dummy, VirtProcr *animatingPr ) 1.123 { int coreIdx; 1.124 VirtProcr *shutDownPr; 1.125 VMSQueueStruc *workQ = _VMSWorkQ; 1.126 1.127 - //free all the locations owned within the VMS system 1.128 - //TODO: write VMS__malloc and free.. -- take the DKU malloc as starting pt 1.129 - 1.130 - //make the core loop shut-down processors and put them into the workQ 1.131 + //create the shutdown processors, one for each core loop -- put them 1.132 + // directly into _VMSWorkQ -- each core will die when gets one, so 1.133 + // the system distributes them evenly itself. 1.134 for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) 1.135 { 1.136 - shutDownPr = VMS__create_procr( NULL, NULL ); 1.137 - shutDownPr->nextInstrPt = _VMSMasterEnv->coreLoopShutDownPt; 1.138 + shutDownPr = VMS__create_procr( &endOSThreadFn, NULL ); 1.139 writeVMSQ( shutDownPr, workQ ); 1.140 } 1.141 1.142 - //This is an issue: the animating processor of this function may not 1.143 - // get its request handled before all the cores have shutdown. 1.144 - //TODO: after all the threads stop, clean out the MasterEnv, the 1.145 - // SemanticEnv, and the workQ before returning. 1.146 - VMS__dissipate_procr( animatingPr ); //will never come back from this 1.147 } 1.148 1.149 1.150 -/*This has to free anything allocated during VMS_init, and any other alloc'd 1.151 +/*Am trying to be cute, avoiding IF statement in coreLoop that checks for 1.152 + * a special shutdown procr. Ended up with extra-complex shutdown sequence. 1.153 + *This function has the sole purpose of setting the stack and framePtr 1.154 + * to the coreLoop's stack and framePtr.. it does that then jumps to the 1.155 + * core loop's shutdown point -- might be able to just call Pthread_exit 1.156 + * from here, but going back to the pthread's stack and setting everything 1.157 + * up just as if it never jumped out, before calling pthread_exit. 1.158 + *The end-point of core loop will free the stack and so forth of the 1.159 + * processor that animates this function, (this fn is transfering the 1.160 + * animator of the AppVP that is in turn animating this function over 1.161 + * to core loop function -- note that this slices out a level of virtual 1.162 + * processors). 1.163 + */ 1.164 +void 1.165 +endOSThreadFn( void *initData, VirtProcr *animatingPr ) 1.166 + { void *jmpPt, *coreLoopStackPtr, *coreLoopFramePtr; 1.167 + 1.168 + jmpPt = _VMSMasterEnv->coreLoopEndPt; 1.169 + coreLoopStackPtr = animatingPr->coreLoopStackPtr; 1.170 + coreLoopFramePtr = animatingPr->coreLoopFramePtr; 1.171 + 1.172 + 1.173 + asm volatile("movl %0, %%eax; \ 1.174 + movl %1, %%esp; \ 1.175 + movl %2, %%ebp; \ 1.176 + jmp %%eax " \ 1.177 + /* outputs */ : \ 1.178 + /* inputs */ : "m" (jmpPt), "m"(coreLoopStackPtr), "m"(coreLoopFramePtr)\ 1.179 + /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi","%esi" \ 1.180 + ); 1.181 + } 1.182 + 1.183 + 1.184 + 1.185 +/*This is called has to free anything allocated during VMS_init, and any other alloc'd 1.186 * locations that might be left over. 1.187 */ 1.188 void 1.189 -VMS__shutdown() 1.190 +VMS__cleanup_after_shutdown() 1.191 { int i; 1.192 1.193 free( _VMSWorkQ ); 1.194 @@ -579,7 +595,7 @@ 1.195 } 1.196 1.197 free( _VMSMasterEnv->schedSlots); 1.198 - VMS__free_procr_locs( _VMSMasterEnv->masterVirtPr ); 1.199 + VMS__handle_dissipate_reqst( _VMSMasterEnv->masterVirtPr ); 1.200 1.201 free( _VMSMasterEnv ); 1.202 }
