Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VSs_impls > VSs__MC_shared_impl
changeset 30:a40859b8dc33 ML_dev
ML_dev -- compiles and runs, may still have shutdown issues
author | Sean Halle <seanhalle@yahoo.com> |
---|---|
date | Sat, 02 Mar 2013 10:07:58 -0800 |
parents | dd1efbf29ff9 |
children | 0162554f6ef5 |
files | VSs.c VSs.h VSs_PluginFns.c VSs_Request_Handlers.c VSs_Request_Handlers.h VSs_SS.c |
diffstat | 6 files changed, 216 insertions(+), 662 deletions(-) [+] |
line diff
1.1 --- a/VSs.c Thu Feb 07 16:30:16 2013 -0800 1.2 +++ b/VSs.c Sat Mar 02 10:07:58 2013 -0800 1.3 @@ -125,26 +125,6 @@ 1.4 ANY_CORE, creatingThd ); 1.5 } 1.6 1.7 -/* old version -- looks safe to delete 1.8 -SlaveVP * 1.9 -VSs__create_slave_with_affinity( TopLevelFnPtr fnPtr, void *initData, 1.10 - SlaveVP *creatingSlv, int32 coreToAssignOnto ) 1.11 - { VSsLangReq reqData; 1.12 - 1.13 - //the lang request data is on the stack and disappears when this 1.14 - // call returns -- it's guaranteed to remain in the VP's stack for as 1.15 - // long as the VP is suspended. 1.16 - reqData.reqType = create_slave_w_aff; //not used, May 2012 1.17 - reqData.coreToAssignOnto = coreToAssignOnto; 1.18 - reqData.fnPtr = fnPtr; 1.19 - reqData.initData = initData; 1.20 - reqData.callingSlv = creatingSlv; 1.21 - 1.22 - PR_WL__send_create_slaveVP_req( &reqData, creatingSlv, VSs_MAGIC_NUMBER ); 1.23 - 1.24 - return creatingSlv->dataRetFromReq; 1.25 - } 1.26 -*/ 1.27 1.28 1.29 SlaveVP * 1.30 @@ -160,7 +140,7 @@ 1.31 reqData.fnPtr = fnPtr; 1.32 reqData.initData = initData; 1.33 1.34 - PR_WL__send_create_slaveVP_req( &reqData, thdID, (CreateHandler)&handleCreateThd, 1.35 + PR_WL__send_create_slaveVP_req( &reqData, thdID, (CreateHandler)&VSs__handleCreateThd, 1.36 creatingThd, VSs_MAGIC_NUMBER ); 1.37 return (SlaveVP *)creatingThd->dataRetFromReq; 1.38 } 1.39 @@ -176,7 +156,7 @@ 1.40 VSs__end_thread( SlaveVP *thdToEnd ) 1.41 { 1.42 //the lang request is null for VSs version of end slave 1.43 - PR_WL__send_end_slave_req( NULL, (RequestHandler)&handleDissipate, thdToEnd, 1.44 + PR_WL__send_end_slave_req( NULL, (RequestHandler)&VSs__handleDissipate, thdToEnd, 1.45 VSs_MAGIC_NUMBER ); 1.46 } 1.47 1.48 @@ -202,7 +182,7 @@ 1.49 // top-level-fn of task and the data for that fn, plus lang's req, 1.50 // animating slave, and lang's magic number 1.51 PR_WL__send_create_task_req( taskType->fn, args, &reqData, NO_ID, 1.52 - &handleSubmitTask, animSlv, VSs_MAGIC_NUMBER ); 1.53 + &VSs__handleSubmitTask, animSlv, VSs_MAGIC_NUMBER ); 1.54 } 1.55 1.56 void 1.57 @@ -212,12 +192,12 @@ 1.58 1.59 reqData.reqType = submit_task; 1.60 1.61 - reqData.taskType = taskType; 1.62 + reqData.taskType = taskType; //VSs info about args, dependencies, etc 1.63 reqData.args = args; 1.64 reqData.callingSlv = animSlv; 1.65 1.66 PR_WL__send_create_task_req( taskType->fn, args, &reqData, taskID, 1.67 - &handleSubmitTask, animSlv, VSs_MAGIC_NUMBER ); 1.68 + &VSs__handleSubmitTask, animSlv, VSs_MAGIC_NUMBER ); 1.69 } 1.70 1.71 1.72 @@ -243,7 +223,7 @@ 1.73 { VSsLangReq reqData; 1.74 1.75 //VSs has nothing extra to communicate to end task handler, so lang req is NULL 1.76 - PR_WL__send_end_task_request( NULL, &handleEndTask, animSlv, VSs_MAGIC_NUMBER ); 1.77 + PR_WL__send_end_task_request( NULL, &VSs__handleEndTask, animSlv, VSs_MAGIC_NUMBER ); 1.78 } 1.79 1.80 1.81 @@ -258,11 +238,34 @@ 1.82 reqData.reqType = taskwait; 1.83 reqData.callingSlv = animSlv; 1.84 1.85 - PR_WL__send_lang_request( &reqData, (RequestHandler)&handleTaskwait, animSlv, 1.86 + PR_WL__send_lang_request( &reqData, (RequestHandler)&VSs__handleTaskwait, animSlv, 1.87 VSs_MAGIC_NUMBER ); 1.88 } 1.89 1.90 +void 1.91 +VSs__wait_for_all_VSs_created_work_to_end( SlaveVP *seedSlv ) 1.92 + { 1.93 + VSsLangReq reqData; 1.94 1.95 + reqData.reqType = activity_cease_wait; 1.96 + reqData.callingSlv = seedSlv; 1.97 + 1.98 + PR_WL__send_lang_request( &reqData, (RequestHandler)&VSs__handleWaitForVSsWorkToEnd, seedSlv, 1.99 + VSs_MAGIC_NUMBER ); 1.100 + } 1.101 + 1.102 + 1.103 + 1.104 +/*This is called by the application -- normally the seed slave. It causes a 1.105 + * request to be sent that frees the VSs lang env and all its contents. 1.106 + *The seed slave resumes from the built-in PRServ langlet's environment. It 1.107 + * will be PRServ that causes return from this call. 1.108 + */ 1.109 +void 1.110 +VSs__shutdown( SlaveVP *seedSlv ) 1.111 + { 1.112 + PR_WL__send_lang_shutdown_request( seedSlv, VSs_MAGIC_NUMBER ); 1.113 + } 1.114 1.115 //========================== send and receive ============================ 1.116 // 1.117 @@ -270,8 +273,9 @@ 1.118 inline 1.119 int32 * 1.120 VSs__give_self_taskID( SlaveVP *animSlv ) 1.121 - { 1.122 - return PR__give_ID_from_slave( animSlv, VSs_MAGIC_NUMBER ); 1.123 + { void *metaTask; 1.124 + metaTask = PR_WL__give_lang_meta_task_from_slave( animSlv, VSs_MAGIC_NUMBER ); 1.125 + return PR__give_ID_from_lang_meta_task( metaTask ); 1.126 } 1.127 1.128 //================================ send =================================== 1.129 @@ -290,7 +294,7 @@ 1.130 1.131 reqData.nextReqInHashEntry = NULL; 1.132 1.133 - PR_WL__send_lang_request( &reqData, (RequestHandler)&handleSendTypeTo, 1.134 + PR_WL__send_lang_request( &reqData, (RequestHandler)&VSs__handleSendTypeTo, 1.135 senderSlv, VSs_MAGIC_NUMBER ); 1.136 1.137 //When come back from suspend, no longer own data reachable from msg 1.138 @@ -309,7 +313,7 @@ 1.139 1.140 reqData.nextReqInHashEntry = NULL; 1.141 1.142 - PR_WL__send_lang_request( &reqData, (RequestHandler)&handleSendFromTo, 1.143 + PR_WL__send_lang_request( &reqData, (RequestHandler)&VSs__handleSendFromTo, 1.144 senderSlv, VSs_MAGIC_NUMBER ); 1.145 } 1.146 1.147 @@ -335,7 +339,7 @@ 1.148 1.149 reqData.nextReqInHashEntry = NULL; 1.150 1.151 - PR_WL__send_lang_request( &reqData, (RequestHandler)&handleReceiveTypeTo, 1.152 + PR_WL__send_lang_request( &reqData, (RequestHandler)&VSs__handleReceiveTypeTo, 1.153 receiverSlv, VSs_MAGIC_NUMBER ); 1.154 1.155 return receiverSlv->dataRetFromReq; 1.156 @@ -361,7 +365,7 @@ 1.157 reqData.nextReqInHashEntry = NULL; 1.158 DEBUG__printf2(dbgRqstHdlr,"WL: receive from %d to: %d", reqData.senderID[1], reqData.receiverID[1]); 1.159 1.160 - PR_WL__send_lang_request( &reqData, (RequestHandler)&handleReceiveFromTo, 1.161 + PR_WL__send_lang_request( &reqData, (RequestHandler)&VSs__handleReceiveFromTo, 1.162 receiverSlv, VSs_MAGIC_NUMBER ); 1.163 1.164 return receiverSlv->dataRetFromReq; 1.165 @@ -370,195 +374,4 @@ 1.166 1.167 1.168 1.169 -//========================================================================== 1.170 -// 1.171 -/*A function singleton is a function whose body executes exactly once, on a 1.172 - * single core, no matter how many times the fuction is called and no 1.173 - * matter how many cores or the timing of cores calling it. 1.174 - * 1.175 - *A data singleton is a ticket attached to data. That ticket can be used 1.176 - * to get the data through the function exactly once, no matter how many 1.177 - * times the data is given to the function, and no matter the timing of 1.178 - * trying to get the data through from different cores. 1.179 - */ 1.180 1.181 -/*asm function declarations*/ 1.182 -void asm_save_ret_to_singleton(VSsSingleton *singletonPtrAddr); 1.183 -void asm_write_ret_from_singleton(VSsSingleton *singletonPtrAddr); 1.184 - 1.185 -/*Fn singleton uses ID as index into array of singleton structs held in the 1.186 - * language environment. 1.187 - */ 1.188 -void 1.189 -VSs__start_fn_singleton( int32 singletonID, SlaveVP *animSlv ) 1.190 - { 1.191 - VSsLangReq reqData; 1.192 - 1.193 - // 1.194 - reqData.reqType = singleton_fn_start; 1.195 - reqData.singletonID = singletonID; 1.196 - 1.197 - PR_WL__send_lang_request( &reqData, (RequestHandler)&handleStartFnSingleton, 1.198 - animSlv, VSs_MAGIC_NUMBER ); 1.199 - if( animSlv->dataRetFromReq ) //will be 0 or addr of label in end singleton 1.200 - { 1.201 - VSsLangEnv *langEnv = 1.202 - PR_int__give_lang_env_for_slave( animSlv, VSs_MAGIC_NUMBER ); 1.203 - asm_write_ret_from_singleton(&(langEnv->fnSingletons[ singletonID])); 1.204 - } 1.205 - } 1.206 - 1.207 -/*Data singleton hands addr of loc holding a pointer to a singleton struct. 1.208 - * The start_data_singleton makes the structure and puts its addr into the 1.209 - * location. 1.210 - */ 1.211 -void 1.212 -VSs__start_data_singleton( VSsSingleton **singletonAddr, SlaveVP *animSlv ) 1.213 - { 1.214 - VSsLangReq reqData; 1.215 - 1.216 - if( *singletonAddr && (*singletonAddr)->hasFinished ) 1.217 - goto JmpToEndSingleton; 1.218 - 1.219 - reqData.reqType = singleton_data_start; 1.220 - reqData.singletonPtrAddr = singletonAddr; 1.221 - 1.222 - PR_WL__send_lang_request( &reqData, (RequestHandler)&handleStartDataSingleton, 1.223 - animSlv, VSs_MAGIC_NUMBER ); 1.224 - if( animSlv->dataRetFromReq ) //either 0 or end singleton's return addr 1.225 - { //Assembly code changes the return addr on the stack to the one 1.226 - // saved into the singleton by the end-singleton-fn 1.227 - //The return addr is at 0x4(%%ebp) 1.228 - JmpToEndSingleton: 1.229 - asm_write_ret_from_singleton(*singletonAddr); 1.230 - } 1.231 - //now, simply return 1.232 - //will exit either from the start singleton call or the end-singleton call 1.233 - } 1.234 - 1.235 -/*Uses ID as index into array of flags. If flag already set, resumes from 1.236 - * end-label. Else, sets flag and resumes normally. 1.237 - * 1.238 - *Note, this call cannot be inlined because the instr addr at the label 1.239 - * inside is shared by all invocations of a given singleton ID. 1.240 - */ 1.241 -void 1.242 -VSs__end_fn_singleton( int32 singletonID, SlaveVP *animSlv ) 1.243 - { 1.244 - VSsLangReq reqData; 1.245 - 1.246 - //don't need this addr until after at least one singleton has reached 1.247 - // this function 1.248 - VSsLangEnv * 1.249 - langEnv = PR_int__give_lang_env_for_slave( animSlv, VSs_MAGIC_NUMBER ); 1.250 - 1.251 - asm_write_ret_from_singleton(&(langEnv->fnSingletons[ singletonID])); 1.252 - 1.253 - reqData.reqType = singleton_fn_end; 1.254 - reqData.singletonID = singletonID; 1.255 - 1.256 - PR_WL__send_lang_request( &reqData, (RequestHandler)&handleEndFnSingleton, 1.257 - animSlv, VSs_MAGIC_NUMBER ); 1.258 - 1.259 -EndSingletonInstrAddr: 1.260 - return; 1.261 - } 1.262 - 1.263 -void 1.264 -VSs__end_data_singleton( VSsSingleton **singletonPtrAddr, SlaveVP *animSlv ) 1.265 - { 1.266 - VSsLangReq reqData; 1.267 - 1.268 - //don't need this addr until after singleton struct has reached 1.269 - // this function for first time 1.270 - //do assembly that saves the return addr of this fn call into the 1.271 - // data singleton -- that data-singleton can only be given to exactly 1.272 - // one instance in the code of this function. However, can use this 1.273 - // function in different places for different data-singletons. 1.274 - asm_save_ret_to_singleton(*singletonPtrAddr); 1.275 - 1.276 - reqData.reqType = singleton_data_end; 1.277 - reqData.singletonPtrAddr = singletonPtrAddr; 1.278 - 1.279 - PR_WL__send_lang_request( &reqData, (RequestHandler)&handleEndDataSingleton, 1.280 - animSlv, VSs_MAGIC_NUMBER ); 1.281 - } 1.282 - 1.283 -/*This executes the function in the masterVP, so it executes in isolation 1.284 - * from any other copies -- only one copy of the function can ever execute 1.285 - * at a time. 1.286 - * 1.287 - *It suspends to the master, and the request handler takes the function 1.288 - * pointer out of the request and calls it, then resumes the VP. 1.289 - *Only very short functions should be called this way -- for longer-running 1.290 - * isolation, use transaction-start and transaction-end, which run the code 1.291 - * between as work-code. 1.292 - */ 1.293 -void 1.294 -VSs__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster, 1.295 - void *data, SlaveVP *animSlv ) 1.296 - { 1.297 - VSsLangReq reqData; 1.298 - 1.299 - // 1.300 - reqData.reqType = atomic; 1.301 - reqData.fnToExecInMaster = ptrToFnToExecInMaster; 1.302 - reqData.dataForFn = data; 1.303 - 1.304 - PR_WL__send_lang_request( &reqData, (RequestHandler)&handleAtomic, 1.305 - animSlv, VSs_MAGIC_NUMBER ); 1.306 - } 1.307 - 1.308 - 1.309 -/*This suspends to the master. 1.310 - *First, it looks at the VP's data, to see the highest transactionID that VP 1.311 - * already has entered. If the current ID is not larger, it throws an 1.312 - * exception stating a bug in the code. Otherwise it puts the current ID 1.313 - * there, and adds the ID to a linked list of IDs entered -- the list is 1.314 - * used to check that exits are properly ordered. 1.315 - *Next it is uses transactionID as index into an array of transaction 1.316 - * structures. 1.317 - *If the "VP_currently_executing" field is non-null, then put requesting VP 1.318 - * into queue in the struct. (At some point a holder will request 1.319 - * end-transaction, which will take this VP from the queue and resume it.) 1.320 - *If NULL, then write requesting into the field and resume. 1.321 - */ 1.322 -void 1.323 -VSs__start_transaction( int32 transactionID, SlaveVP *animSlv ) 1.324 - { 1.325 - VSsLangReq reqData; 1.326 - 1.327 - // 1.328 - reqData.callingSlv = animSlv; 1.329 - reqData.reqType = trans_start; 1.330 - reqData.transID = transactionID; 1.331 - 1.332 - PR_WL__send_lang_request( &reqData, (RequestHandler)&handleTransStart, 1.333 - animSlv, VSs_MAGIC_NUMBER ); 1.334 - } 1.335 - 1.336 -/*This suspends to the master, then uses transactionID as index into an 1.337 - * array of transaction structures. 1.338 - *It looks at VP_currently_executing to be sure it's same as requesting VP. 1.339 - * If different, throws an exception, stating there's a bug in the code. 1.340 - *Next it looks at the queue in the structure. 1.341 - *If it's empty, it sets VP_currently_executing field to NULL and resumes. 1.342 - *If something in, gets it, sets VP_currently_executing to that VP, then 1.343 - * resumes both. 1.344 - */ 1.345 -void 1.346 -VSs__end_transaction( int32 transactionID, SlaveVP *animSlv ) 1.347 - { 1.348 - VSsLangReq reqData; 1.349 - 1.350 - // 1.351 - reqData.callingSlv = animSlv; 1.352 - reqData.reqType = trans_end; 1.353 - reqData.transID = transactionID; 1.354 - 1.355 - PR_WL__send_lang_request( &reqData, (RequestHandler)&handleTransEnd, 1.356 - animSlv, VSs_MAGIC_NUMBER ); 1.357 - } 1.358 - 1.359 -//======================== Internal ================================== 1.360 -
2.1 --- a/VSs.h Thu Feb 07 16:30:16 2013 -0800 2.2 +++ b/VSs.h Sat Mar 02 10:07:58 2013 -0800 2.3 @@ -73,13 +73,12 @@ 2.4 } 2.5 VSsPointerEntry; 2.6 2.7 -/*This is placed into langData, used for dependencies and wait construct*/ 2.8 +/*This is VSs's "lang meta task" 2.9 + *See the proto-runtime wiki entry to learn about "lang meta task" 2.10 + *In essence, this holds all the meta information that VSs needs about a task 2.11 + */ 2.12 struct _VSsTaskStub 2.13 { 2.14 - //====== The first fields must match PRLangMetaTask fields ====== 2.15 - int32 langMagicNumber; //magic num must be 1st field of langMetaTask 2.16 - PRMetaTask *protoMetaTask; //back-link must always be 2nd field 2.17 - //====== end PRLangMetaTask fields ========= 2.18 void **args; //ctld args must be the first ones (as ptrs) 2.19 VSsPointerEntry **ptrEntries; 2.20 int32 numBlockingProp; 2.21 @@ -140,15 +139,9 @@ 2.22 receive_from_to, 2.23 //=============================== 2.24 taskwait, 2.25 - malloc_req, 2.26 - free_req, 2.27 - singleton_fn_start, 2.28 - singleton_fn_end, 2.29 - singleton_data_start, 2.30 - singleton_data_end, 2.31 - atomic, 2.32 - trans_start, 2.33 - trans_end 2.34 + activity_cease_wait, 2.35 + wait_then_shutdown, 2.36 + shutdown 2.37 }; 2.38 2.39 struct _VSsLangReq 2.40 @@ -269,7 +262,13 @@ 2.41 VSs__start( SlaveVP *seedSlv ); 2.42 2.43 void 2.44 -VSs__cleanup_after_shutdown(); 2.45 +VSs__shutdown( SlaveVP *seedSlv ); 2.46 + 2.47 +void 2.48 +VSs__wait_for_all_VSs_created_work_to_end( SlaveVP *seedSlv ); 2.49 + 2.50 +void 2.51 +VSs__wait_until_activity_done_then_shutdown( SlaveVP *seedSlv ); 2.52 2.53 //======================= 2.54 2.55 @@ -291,8 +290,8 @@ 2.56 void 2.57 VSs__submit_task( VSsTaskType *taskType, void *args, SlaveVP *animSlv); 2.58 2.59 -inline int32 * 2.60 -VSs__create_taskID_of_size( int32 numInts, SlaveVP *animSlv ); 2.61 +//inline int32 * 2.62 +//VSs__create_taskID_of_size( int32 numInts, SlaveVP *animSlv ); 2.63 2.64 void 2.65 VSs__submit_task_with_ID( VSsTaskType *taskType, void *args, int32 *taskID, 2.66 @@ -322,35 +321,10 @@ 2.67 void * 2.68 VSs__receive_from_to( int32 *senderID, int32 *receiverID, SlaveVP *receiverSlv ); 2.69 2.70 -//======================= Concurrency Stuff ====================== 2.71 -void 2.72 -VSs__start_fn_singleton( int32 singletonID, SlaveVP *animSlv ); 2.73 - 2.74 -void 2.75 -VSs__end_fn_singleton( int32 singletonID, SlaveVP *animSlv ); 2.76 - 2.77 -void 2.78 -VSs__start_data_singleton( VSsSingleton **singeltonAddr, SlaveVP *animSlv ); 2.79 - 2.80 -void 2.81 -VSs__end_data_singleton( VSsSingleton **singletonAddr, SlaveVP *animSlv ); 2.82 - 2.83 -void 2.84 -VSs__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster, 2.85 - void *data, SlaveVP *animSlv ); 2.86 - 2.87 -void 2.88 -VSs__start_transaction( int32 transactionID, SlaveVP *animSlv ); 2.89 - 2.90 -void 2.91 -VSs__end_transaction( int32 transactionID, SlaveVP *animSlv ); 2.92 - 2.93 2.94 //========================= Internal use only ============================= 2.95 -void 2.96 -VSs__Request_Handler( SlaveVP *requestingSlv, void *_langEnv ); 2.97 2.98 -SlaveVP * 2.99 +bool32 2.100 VSs__assign_work_to_slot( void *_langEnv, AnimSlot *slot ); 2.101 2.102 SlaveVP* 2.103 @@ -365,6 +339,9 @@ 2.104 VSs__create_slave_with_affinity( TopLevelFnPtr fnPtr, void *initData, 2.105 SlaveVP *creatingSlv, int32 coreToAssignOnto); 2.106 2.107 +void 2.108 +VSs__cleanup_after_shutdown(); 2.109 + 2.110 //===================== ===================== 2.111 2.112 #include "VSs_Request_Handlers.h"
3.1 --- a/VSs_PluginFns.c Thu Feb 07 16:30:16 2013 -0800 3.2 +++ b/VSs_PluginFns.c Sat Mar 02 10:07:58 2013 -0800 3.3 @@ -12,17 +12,6 @@ 3.4 #include "VSs_Request_Handlers.h" 3.5 3.6 //=========================== Local Fn Prototypes =========================== 3.7 -void 3.8 -VSs__resume_slave( SlaveVP *slave, VSsLangEnv *langEnv ); 3.9 - 3.10 -inline void 3.11 -handleLangReq( PRReqst *req, SlaveVP *requestingSlv, VSsLangEnv *langEnv ); 3.12 - 3.13 -inline void 3.14 -handleDissipate( SlaveVP *requestingSlv, VSsLangEnv *langEnv ); 3.15 - 3.16 -inline void 3.17 -handleCreate( PRReqst *req, SlaveVP *requestingSlv, VSsLangEnv *langEnv ); 3.18 3.19 //============================== Assigner ================================== 3.20 // 3.21 @@ -68,8 +57,9 @@ 3.22 if( returnSlv != NULL ) //Yes, have a slave, so return it. 3.23 { returnSlv->coreAnimatedBy = coreNum; 3.24 3.25 - fixme; //check that putting into slot and call chain are correct 3.26 - PR_int__put_slave_into_slot( returnSlv, slot ); 3.27 + PR_PI__put_slave_into_slot( returnSlv, slot ); 3.28 + //Note: PR uses the return boolean to track how much ready work the 3.29 + // lang env has in it.. 3.30 goto Success; 3.31 } 3.32 3.33 @@ -77,8 +67,7 @@ 3.34 newTaskStub = readPrivQ( langEnv->taskReadyQ ); 3.35 if( newTaskStub != NULL ) 3.36 { 3.37 - fixme; //check that putting into slot and call chain are correct 3.38 - PR_int__put_task_into_slot( newTaskStub, slot ); 3.39 + PR_int__put_task_into_slot( newTaskStub, slot ); 3.40 goto Success; 3.41 } 3.42 3.43 @@ -144,8 +133,9 @@ 3.44 3.45 //=========================== Helper ============================== 3.46 void 3.47 -VSs__resume_slave( SlaveVP *slave, VSsLangEnv *langEnv ) 3.48 - { 3.49 +VSs__resume_slave( SlaveVP *slave, void *_langEnv ) 3.50 + { VSsLangEnv *langEnv = (VSsLangEnv *)_langEnv; 3.51 + 3.52 //both suspended tasks and suspended explicit slaves resumed with this 3.53 writePrivQ( slave, langEnv->slavesReadyToResumeQ ); 3.54 //PR handles this.. PR_int__set_work_in_lang_env(langEnv);
4.1 --- a/VSs_Request_Handlers.c Thu Feb 07 16:30:16 2013 -0800 4.2 +++ b/VSs_Request_Handlers.c Sat Mar 02 10:07:58 2013 -0800 4.3 @@ -17,14 +17,6 @@ 4.4 4.5 4.6 //=========================== Local Fn Prototypes =========================== 4.7 -void 4.8 -VSs__resume_slave( SlaveVP *slave, VSsLangEnv *langEnv ); 4.9 - 4.10 -void 4.11 -VSs__lang_meta_task_freer( void *_langMetaTask ); 4.12 - 4.13 -void 4.14 -VSs__langDataFreer( void *_langData ); 4.15 4.16 //========================================================================== 4.17 // Helpers 4.18 @@ -198,7 +190,7 @@ 4.19 */ 4.20 //inline 4.21 SlaveVP * 4.22 -handleCreateThd( void *_langReq, SlaveVP *requestingSlv, void *_langEnv ) 4.23 +VSs__handleCreateThd( void *_langReq, SlaveVP *requestingSlv, void *_langEnv ) 4.24 { VSsLangReq *langReq; 4.25 VSsTaskStub *taskStub, *parentTaskStub; 4.26 SlaveVP *newSlv; 4.27 @@ -272,7 +264,7 @@ 4.28 */ 4.29 //inline 4.30 void 4.31 -handleDissipate( void *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ) 4.32 +VSs__handleDissipate( void *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ) 4.33 { 4.34 VSsTaskStub *parentTaskStub, *ownTaskStub; 4.35 4.36 @@ -283,14 +275,32 @@ 4.37 parentTaskStub = ownTaskStub->parentTaskStub; 4.38 parentTaskStub->numLiveChildThreads -= 1; //parent wasn't freed, even if ended 4.39 4.40 - //if all children ended, then free this task's stub 4.41 - // else, keep stub around, and last child will free it (below) 4.42 - if( ownTaskStub->numLiveChildTasks == 0 && 4.43 - ownTaskStub->numLiveChildThreads == 0 ) 4.44 - free_task_stub( ownTaskStub ); 4.45 - else 4.46 - ownTaskStub->isEnded = TRUE; //for children to see when they end 4.47 - 4.48 + //Thinking add a "don't free this!" flag to meta task and lang data, plus 4.49 + // an "is ended" flag.. to their prologs.. VSs sets the flag at create 4.50 + // clears it in here.. then PR does all the freeing, calling the freer 4.51 + // pointed to inside the meta-task/lang-data 4.52 + //Abort-end of lang or process can lose meta-tasks and lang-datas have the 4.53 + // flag set.. memory leak.. so add linked list of meta-tasks/lang-datas 4.54 + // owned by a lang/process.. plus a list of slaves.. free those first, 4.55 + // then free the meta-tasks and lang-datas left over.. maybe leave as 4.56 + // a bug for now, fix mem leak later.. 4.57 + 4.58 + //if children still live, keep stub around, and last child will free it (below) 4.59 + if( ownTaskStub->numLiveChildTasks != 0 || 4.60 + ownTaskStub->numLiveChildThreads != 0 ) 4.61 + { 4.62 + PR_PI__set_no_del_flag_in_lang_meta_task( ownTaskStub ); 4.63 + ownTaskStub->isEnded = TRUE; //for children to see, when they end 4.64 + } 4.65 + 4.66 + //check if this is last child of ended parent (note, not possible to 4.67 + // have more than one level of ancestor waiting to be freed) 4.68 + if( parentTaskStub->isEnded && 4.69 + parentTaskStub->numLiveChildTasks == 0 && 4.70 + parentTaskStub->numLiveChildThreads == 0 ) 4.71 + { PR_PI__free_lang_meta_task( parentTaskStub ); //free whole meta-task 4.72 + } 4.73 + 4.74 //Now, check on parents waiting on child threads to end 4.75 if( parentTaskStub->isWaitingForChildThreadsToEnd && 4.76 parentTaskStub->numLiveChildThreads == 0 ) 4.77 @@ -301,66 +311,14 @@ 4.78 PR_PI__make_slave_ready( PR_PI__give_slave_lang_meta_task_is_assigned_to(parentTaskStub), langEnv ); 4.79 } 4.80 4.81 - //check if this is last child of ended parent (note, not possible to 4.82 - // have more than one level of ancestor waiting to be freed) 4.83 - if( parentTaskStub->isEnded && 4.84 - parentTaskStub->numLiveChildTasks == 0 && 4.85 - parentTaskStub->numLiveChildThreads == 0 ) 4.86 - { free_task_stub( parentTaskStub ); //just stub, langData already freed 4.87 - } 4.88 4.89 FreeSlaveStateAndReturn: 4.90 - //PR frees the langData, task stub and requesting slave's base state 4.91 + //PR frees slave's base state, and also the meta-tasks and lang data, 4.92 + // except ones have "don't delete" flag set 4.93 return; 4.94 } 4.95 4.96 -inline 4.97 -void 4.98 -handleShutdownDissipate( SlaveVP *requestingSlv, VSsLangEnv *langEnv ) 4.99 - { 4.100 - VSsTaskStub *ownTaskStub; 4.101 - 4.102 - ownTaskStub = PR_PI__give_lang_meta_task_from_slave( requestingSlv, VSs_MAGIC_NUMBER ); 4.103 - free_task_stub( ownTaskStub ); 4.104 4.105 - //PR frees the langData, task stub and requesting slave's base state 4.106 - return; 4.107 - } 4.108 - 4.109 -/*Register this with PR, during VSs start 4.110 - * 4.111 - *At some point, may change PR so that it recycles langData, in which case this 4.112 - * only gets called when a process shuts down.. at that point, PR will call 4.113 - * dissipate on all the slaves it has in the recycle Q. 4.114 - */ 4.115 -void 4.116 -freeVSsLangData( void *_langData ) 4.117 - { VSsLangData *langData; 4.118 - TransListElem *transElem, *nextTransElem; 4.119 - 4.120 - langData = (VSsLangData *)_langData; 4.121 - transElem = langData->lastTransEntered; 4.122 - 4.123 - //Each trans the slave has entered was saved in a linked list elem inside 4.124 - // lang data -- delete those linked list elements 4.125 - while( transElem != NULL) 4.126 - { nextTransElem = transElem->nextTrans; 4.127 - PR_int__free( transElem ); 4.128 - transElem = nextTransElem; 4.129 - } 4.130 - PR_PI__free( _langData ); 4.131 - } 4.132 - 4.133 -/*Will be used by a landData recycler, when (and if) such a thing added 4.134 - to PR 4.135 - */ 4.136 -void 4.137 -resetVSsLangData( void *_langData ) 4.138 - { VSsLangData *langData = (VSsLangData *)_langData; 4.139 - 4.140 - langData->highestTransEntered = -1; 4.141 - langData->lastTransEntered = NULL; 4.142 - } 4.143 4.144 //========================================================================== 4.145 // 4.146 @@ -445,9 +403,10 @@ 4.147 * decide garbage collection of no-longer-used pointers later) 4.148 * 4.149 */ 4.150 -//inline 4.151 +//Here's the typedef this Fn's signature has to match: 4.152 +//typedef void * (*CreateHandler)( void *, SlaveVP *, void * ); //req, slv, langEnv 4.153 void * 4.154 -handleSubmitTask( VSsLangReq *langReq, VSsLangEnv *langEnv ) 4.155 +VSs__handleSubmitTask( VSsLangReq *langReq, SlaveVP *slave, VSsLangEnv *langEnv ) 4.156 { uint32 key[3]; 4.157 HashEntry *rawHashEntry; //has char *, but use with uint32 * 4.158 VSsPointerEntry *ptrEntry; //contents of hash table entry for an arg pointer 4.159 @@ -472,6 +431,7 @@ 4.160 taskStub = create_task_stub( taskType, args );//copies arg ptrs 4.161 4.162 taskStub->numBlockingProp = taskType->numCtldArgs; 4.163 + 4.164 //PR does this (metaTask contains taskID): taskStub->taskID = langReq->taskID; 4.165 4.166 parentTaskStub = (VSsTaskStub *)PR_PI__give_lang_meta_task_from_slave(langReq->callingSlv, VSs_MAGIC_NUMBER); 4.167 @@ -502,12 +462,15 @@ 4.168 rawHashEntry = addValueIntoTable32( key, ptrEntry, argPtrHashTbl ); 4.169 } 4.170 else 4.171 - { ptrEntry = (VSsPointerEntry *)rawHashEntry->content; 4.172 + { //The hash table returns a "hashEntry" struct, which then holds 4.173 + // a "pointer entry" struct -- get that struct for this hash value 4.174 + ptrEntry = (VSsPointerEntry *)rawHashEntry->content; 4.175 if( ptrEntry == NULL ) 4.176 { ptrEntry = create_pointer_entry(); 4.177 rawHashEntry = addValueIntoTable32(key, ptrEntry, argPtrHashTbl); 4.178 } 4.179 } 4.180 + //save into task stub, the struct that holds meta-info about a pointer 4.181 taskStub->ptrEntries[argNum] = ptrEntry; 4.182 4.183 /*Have the hash entry. 4.184 @@ -603,7 +566,7 @@ 4.185 */ 4.186 //inline 4.187 void 4.188 -handleEndTask( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ) 4.189 +VSs__handleEndTask( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ) 4.190 { VSsPointerEntry *ptrEntry; //contents of hash table entry for an arg pointer 4.191 void **args; 4.192 VSsTaskStub *endingTaskStub, *waitingTaskStub, *parentStub; 4.193 @@ -631,8 +594,10 @@ 4.194 } 4.195 4.196 //Check if parent ended, and this was last descendent, then free it 4.197 - if( parentStub->isEnded && parentStub->numLiveChildTasks == 0 ) 4.198 - { free_task_stub( parentStub ); 4.199 + if( parentStub->isEnded && 4.200 + parentStub->numLiveChildTasks == 0 && 4.201 + parentStub->numLiveChildThreads == 0 ) 4.202 + { PR_PI__free_lang_meta_task( parentStub ); 4.203 } 4.204 4.205 4.206 @@ -730,17 +695,24 @@ 4.207 4.208 //done ending the task, if still has live children, then keep stub around 4.209 // else, free the stub and args copy 4.210 - if( endingTaskStub->numLiveChildTasks == 0 && 4.211 - endingTaskStub->numLiveChildThreads == 0 ) 4.212 - { free_task_stub( endingTaskStub ); 4.213 + if( endingTaskStub->numLiveChildTasks != 0 || 4.214 + endingTaskStub->numLiveChildThreads != 0 ) 4.215 + { PR_PI__set_no_del_flag_in_lang_meta_task( endingTaskStub ); 4.216 } 4.217 4.218 return; 4.219 } 4.220 4.221 + 4.222 +/*This is called during shutdown, to delete a task that still has dependencies 4.223 + * unfulfilled. 4.224 + *VSs has a complex meta task, so this freer has to do a fair amount. 4.225 + * The arguments were copied over into the meta task, and there are queues of 4.226 + * other tasks waiting on completion of this one 4.227 + */ 4.228 //inline 4.229 void 4.230 -handleFreeTask( void *langMetaTask ) 4.231 +VSs__free_waiting_task( void *langMetaTask ) 4.232 { VSsPointerEntry *ptrEntry; //contents of hash table entry for an arg pointer 4.233 void **args; 4.234 VSsTaskStub *endingTaskStub, *waitingTaskStub; 4.235 @@ -761,7 +733,7 @@ 4.236 */ 4.237 int32 argNum; 4.238 for( argNum = 0; argNum < endingTaskType->numCtldArgs; argNum++ ) 4.239 - { 4.240 + { 4.241 ptrEntry = ptrEntries[argNum]; 4.242 while( TRUE ) 4.243 { 4.244 @@ -781,7 +753,7 @@ 4.245 waitingTaskStub->numBlockingProp -= 1; 4.246 if( waitingTaskStub->numBlockingProp == 0 ) 4.247 { //last ptrEntry holding the task, so free it 4.248 - free_task_stub( endingTaskStub ); 4.249 + VSs__free_langlet_part_of_lang_meta_task( endingTaskStub ); 4.250 } 4.251 } 4.252 }// 4.253 @@ -789,13 +761,42 @@ 4.254 } 4.255 4.256 4.257 +/*Two use-cases for freeing a meta-task.. one is the langlet has control 4.258 + * over the meta tasks's life-line it may differ from the task-work-unit's 4.259 + * lifeline.. the other is PR controls, for example when a langlet or 4.260 + * process gets pre-maturely shutdown due to outside influences, or exception, 4.261 + * and so on.. 4.262 + *In the first case, the langlet has two choices.. it can free all the langlet 4.263 + * malloc'd data owned by the meta-task, then as PR to free the remaining 4.264 + * proto meta-task.. or, it can just call PR's full-service "free meta-task" 4.265 + * which in turn calls the langlet's "free just langlet-malloc'd data" Fn, which 4.266 + * was given to the meta-task creator.. 4.267 + * 4.268 + *In the second case, PR calls the langlet's "free just langlet malloc'd data" 4.269 + * Fn, which was given to the meta-task creator. The langlet has no other 4.270 + * involvement. 4.271 + * 4.272 + *This is the VSs call that the langlet uses when it separately frees its own 4.273 + * portion of the meta-task. 4.274 + */ 4.275 +void 4.276 +VSs__free_full_lang_meta_task( VSsTaskStub *taskStub ) 4.277 + { 4.278 + 4.279 + } 4.280 + 4.281 + 4.282 +/*Frees only the langlet's portion of the meta task. 4.283 + *This is given to PR when a meta task is created. It is also used by the 4.284 + * end task handler, which may choose to keep the meta task info far past the 4.285 + * end of the task's existence.. 4.286 + */ 4.287 //inline 4.288 void 4.289 -free_task_stub( VSsTaskStub *stubToFree ) 4.290 +VSs__free_langlet_part_of_lang_meta_task( VSsTaskStub *stubToFree ) 4.291 { if(stubToFree->ptrEntries != NULL ) //a thread stub has NULL entry 4.292 { PR_PI__free( stubToFree->ptrEntries ); 4.293 } 4.294 - PR_PI__free( stubToFree ); 4.295 } 4.296 4.297 //========================== Task Comm handlers =========================== 4.298 @@ -815,7 +816,7 @@ 4.299 */ 4.300 //inline 4.301 void 4.302 -handleSendTypeTo( VSsLangReq *langReq, SlaveVP *reqSlave, VSsLangEnv *langEnv ) 4.303 +VSs__handleSendTypeTo( VSsLangReq *langReq, SlaveVP *reqSlave, VSsLangEnv *langEnv ) 4.304 { SlaveVP *senderSlv, *receiverSlv; 4.305 int32 *senderID, *receiverID; 4.306 int32 *key, keySz, receiverIDNumInt; 4.307 @@ -923,7 +924,7 @@ 4.308 //TODO: combine both send handlers into single handler 4.309 //inline 4.310 void 4.311 -handleSendFromTo( VSsLangReq *langReq, SlaveVP *dummySlave, VSsLangEnv *langEnv) 4.312 +VSs__handleSendFromTo( VSsLangReq *langReq, SlaveVP *dummySlave, VSsLangEnv *langEnv) 4.313 { SlaveVP *senderSlv, *receiverSlv; 4.314 int32 *senderID, *receiverID; 4.315 int32 *key, keySz, receiverIDNumInt, senderIDNumInt; 4.316 @@ -1004,7 +1005,7 @@ 4.317 4.318 //inline 4.319 void 4.320 -handleReceiveTypeTo( VSsLangReq *langReq, SlaveVP *dummySlv, VSsLangEnv *langEnv) 4.321 +VSs__handleReceiveTypeTo( VSsLangReq *langReq, SlaveVP *dummySlv, VSsLangEnv *langEnv) 4.322 { SlaveVP *senderSlv, *receiverSlv; 4.323 int32 *receiverID; 4.324 int32 *key, keySz, receiverIDNumInt; 4.325 @@ -1090,7 +1091,7 @@ 4.326 */ 4.327 //inline 4.328 void 4.329 -handleReceiveFromTo( VSsLangReq *langReq, SlaveVP *dummySlv, VSsLangEnv *langEnv) 4.330 +VSs__handleReceiveFromTo( VSsLangReq *langReq, SlaveVP *dummySlv, VSsLangEnv *langEnv) 4.331 { SlaveVP *senderSlv, *receiverSlv; 4.332 int32 *senderID, *receiverID; 4.333 int32 *key, keySz, receiverIDNumInt, senderIDNumInt; 4.334 @@ -1161,7 +1162,7 @@ 4.335 */ 4.336 //inline 4.337 void 4.338 -handleTaskwait( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv) 4.339 +VSs__handleTaskwait( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv) 4.340 { VSsTaskStub* taskStub; 4.341 4.342 DEBUG__printf1(dbgRqstHdlr,"Taskwait request from processor %d", 4.343 @@ -1179,256 +1180,16 @@ 4.344 } 4.345 } 4.346 4.347 - 4.348 -//========================================================================== 4.349 -/* 4.350 - */ 4.351 void 4.352 -handleMalloc( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ) 4.353 - { void *ptr; 4.354 - 4.355 - DEBUG__printf1(dbgRqstHdlr,"Malloc request from processor %d",requestingSlv->slaveNum) 4.356 - 4.357 - ptr = PR_PI__malloc( langReq->sizeToMalloc ); 4.358 - requestingSlv->dataRetFromReq = ptr; 4.359 - PR_PI__make_slave_ready( requestingSlv, langEnv ); 4.360 +VSs__handleWaitForVSsWorkToEnd( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv) 4.361 + { 4.362 + PR_PI__handle_wait_for_langlets_work_to_end( requestingSlv, langEnv ); 4.363 } 4.364 4.365 -/* 4.366 - */ 4.367 void 4.368 -handleFree( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ) 4.369 +VSs__handleWaitThenShutdown( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv) 4.370 { 4.371 - DEBUG__printf1(dbgRqstHdlr,"Free request from processor %d",requestingSlv->slaveNum) 4.372 - PR_PI__free( langReq->ptrToFree ); 4.373 - PR_PI__make_slave_ready( requestingSlv, langEnv ); 4.374 - } 4.375 - 4.376 - 4.377 -//=========================================================================== 4.378 -// 4.379 -/*Uses ID as index into array of flags. If flag already set, resumes from 4.380 - * end-label. Else, sets flag and resumes normally. 4.381 - */ 4.382 -void 4.383 -//inline 4.384 -handleStartSingleton_helper( VSsSingleton *singleton, SlaveVP *reqstingSlv, 4.385 - VSsLangEnv *langEnv ) 4.386 - { 4.387 - if( singleton->hasFinished ) 4.388 - { //the code that sets the flag to true first sets the end instr addr 4.389 - reqstingSlv->dataRetFromReq = singleton->endInstrAddr; 4.390 - PR_PI__make_slave_ready( reqstingSlv, langEnv ); 4.391 - return; 4.392 - } 4.393 - else if( singleton->hasBeenStarted ) 4.394 - { //singleton is in-progress in a diff slave, so wait for it to finish 4.395 - writePrivQ(reqstingSlv, singleton->waitQ ); 4.396 - return; 4.397 - } 4.398 - else 4.399 - { //hasn't been started, so this is the first attempt at the singleton 4.400 - singleton->hasBeenStarted = TRUE; 4.401 - reqstingSlv->dataRetFromReq = 0x0; 4.402 - PR_PI__make_slave_ready( reqstingSlv, langEnv ); 4.403 - return; 4.404 - } 4.405 - } 4.406 -void 4.407 -//inline 4.408 -handleStartFnSingleton( VSsLangReq *langReq, SlaveVP *requestingSlv, 4.409 - VSsLangEnv *langEnv ) 4.410 - { VSsSingleton *singleton; 4.411 - DEBUG__printf1(dbgRqstHdlr,"StartFnSingleton request from processor %d",requestingSlv->slaveNum) 4.412 - 4.413 - singleton = &(langEnv->fnSingletons[ langReq->singletonID ]); 4.414 - handleStartSingleton_helper( singleton, requestingSlv, langEnv ); 4.415 - } 4.416 -void 4.417 -//inline 4.418 -handleStartDataSingleton( VSsLangReq *langReq, SlaveVP *requestingSlv, 4.419 - VSsLangEnv *langEnv ) 4.420 - { VSsSingleton *singleton; 4.421 - 4.422 - DEBUG__printf1(dbgRqstHdlr,"StartDataSingleton request from processor %d",requestingSlv->slaveNum) 4.423 - if( *(langReq->singletonPtrAddr) == NULL ) 4.424 - { singleton = PR_PI__malloc( sizeof(VSsSingleton) ); 4.425 - singleton->waitQ = makePRQ(); 4.426 - singleton->endInstrAddr = 0x0; 4.427 - singleton->hasBeenStarted = FALSE; 4.428 - singleton->hasFinished = FALSE; 4.429 - *(langReq->singletonPtrAddr) = singleton; 4.430 - } 4.431 - else 4.432 - singleton = *(langReq->singletonPtrAddr); 4.433 - handleStartSingleton_helper( singleton, requestingSlv, langEnv ); 4.434 - } 4.435 - 4.436 - 4.437 -void 4.438 -//inline 4.439 -handleEndSingleton_helper( VSsSingleton *singleton, SlaveVP *requestingSlv, 4.440 - VSsLangEnv *langEnv ) 4.441 - { PrivQueueStruc *waitQ; 4.442 - int32 numWaiting, i; 4.443 - SlaveVP *resumingSlv; 4.444 - 4.445 - if( singleton->hasFinished ) 4.446 - { //by definition, only one slave should ever be able to run end singleton 4.447 - // so if this is true, is an error 4.448 - ERROR1( "singleton code ran twice", requestingSlv ); 4.449 - } 4.450 - 4.451 - singleton->hasFinished = TRUE; 4.452 - waitQ = singleton->waitQ; 4.453 - numWaiting = numInPrivQ( waitQ ); 4.454 - for( i = 0; i < numWaiting; i++ ) 4.455 - { //they will resume inside start singleton, then jmp to end singleton 4.456 - resumingSlv = readPrivQ( waitQ ); 4.457 - resumingSlv->dataRetFromReq = singleton->endInstrAddr; 4.458 - PR_PI__make_slave_ready( resumingSlv, langEnv ); 4.459 - } 4.460 - 4.461 - PR_PI__make_slave_ready( requestingSlv, langEnv ); 4.462 - 4.463 -} 4.464 -void 4.465 -handleEndFnSingleton( VSsLangReq *langReq, SlaveVP *requestingSlv, 4.466 - VSsLangEnv *langEnv ) 4.467 - { 4.468 - VSsSingleton *singleton; 4.469 - 4.470 - DEBUG__printf1(dbgRqstHdlr,"EndFnSingleton request from processor %d",requestingSlv->slaveNum) 4.471 - 4.472 - singleton = &(langEnv->fnSingletons[ langReq->singletonID ]); 4.473 - handleEndSingleton_helper( singleton, requestingSlv, langEnv ); 4.474 - } 4.475 -void 4.476 -handleEndDataSingleton( VSsLangReq *langReq, SlaveVP *requestingSlv, 4.477 - VSsLangEnv *langEnv ) 4.478 - { 4.479 - VSsSingleton *singleton; 4.480 - 4.481 - DEBUG__printf1(dbgRqstHdlr,"EndDataSingleton request from processor %d",requestingSlv->slaveNum) 4.482 - 4.483 - singleton = *(langReq->singletonPtrAddr); 4.484 - handleEndSingleton_helper( singleton, requestingSlv, langEnv ); 4.485 - } 4.486 - 4.487 - 4.488 -/*This executes the function in the masterVP, take the function 4.489 - * pointer out of the request and call it, then resume the VP. 4.490 - */ 4.491 -void 4.492 -handleAtomic( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ) 4.493 - { 4.494 - DEBUG__printf1(dbgRqstHdlr,"Atomic request from processor %d",requestingSlv->slaveNum) 4.495 - langReq->fnToExecInMaster( langReq->dataForFn ); 4.496 - PR_PI__make_slave_ready( requestingSlv, langEnv ); 4.497 - } 4.498 - 4.499 -/*First, it looks at the VP's semantic data, to see the highest transactionID 4.500 - * that VP 4.501 - * already has entered. If the current ID is not larger, it throws an 4.502 - * exception stating a bug in the code. 4.503 - *Otherwise it puts the current ID 4.504 - * there, and adds the ID to a linked list of IDs entered -- the list is 4.505 - * used to check that exits are properly ordered. 4.506 - *Next it is uses transactionID as index into an array of transaction 4.507 - * structures. 4.508 - *If the "VP_currently_executing" field is non-null, then put requesting VP 4.509 - * into queue in the struct. (At some point a holder will request 4.510 - * end-transaction, which will take this VP from the queue and resume it.) 4.511 - *If NULL, then write requesting into the field and resume. 4.512 - */ 4.513 -void 4.514 -handleTransStart( VSsLangReq *langReq, SlaveVP *requestingSlv, 4.515 - VSsLangEnv *langEnv ) 4.516 - { VSsLangData *langData; 4.517 - TransListElem *nextTransElem; 4.518 - 4.519 - DEBUG__printf1(dbgRqstHdlr,"TransStart request from processor %d",requestingSlv->slaveNum) 4.520 - 4.521 - //check ordering of entering transactions is correct 4.522 - langData = PR_PI__give_lang_data(requestingSlv, VSs_MAGIC_NUMBER); 4.523 - if( langData->highestTransEntered > langReq->transID ) 4.524 - { //throw PR exception, which shuts down PR. 4.525 - PR_PI__throw_exception( "transID smaller than prev", requestingSlv, NULL); 4.526 - } 4.527 - //add this trans ID to the list of transactions entered -- check when 4.528 - // end a transaction 4.529 - langData->highestTransEntered = langReq->transID; 4.530 - nextTransElem = PR_PI__malloc( sizeof(TransListElem) ); 4.531 - nextTransElem->transID = langReq->transID; 4.532 - nextTransElem->nextTrans = langData->lastTransEntered; 4.533 - langData->lastTransEntered = nextTransElem; 4.534 - 4.535 - //get the structure for this transaction ID 4.536 - VSsTrans * 4.537 - transStruc = &(langEnv->transactionStrucs[ langReq->transID ]); 4.538 - 4.539 - if( transStruc->VPCurrentlyExecuting == NULL ) 4.540 - { 4.541 - transStruc->VPCurrentlyExecuting = requestingSlv; 4.542 - PR_PI__make_slave_ready( requestingSlv, langEnv ); 4.543 - } 4.544 - else 4.545 - { //note, might make future things cleaner if save request with VP and 4.546 - // add this trans ID to the linked list when gets out of queue. 4.547 - // but don't need for now, and lazy.. 4.548 - writePrivQ( requestingSlv, transStruc->waitingVPQ ); 4.549 - } 4.550 - } 4.551 - 4.552 - 4.553 -/*Use the trans ID to get the transaction structure from the array. 4.554 - *Look at VP_currently_executing to be sure it's same as requesting VP. 4.555 - * If different, throw an exception, stating there's a bug in the code. 4.556 - *Next, take the first element off the list of entered transactions. 4.557 - * Check to be sure the ending transaction is the same ID as the next on 4.558 - * the list. If not, incorrectly nested so throw an exception. 4.559 - * 4.560 - *Next, get from the queue in the structure. 4.561 - *If it's empty, set VP_currently_executing field to NULL and resume 4.562 - * requesting VP. 4.563 - *If get somethine, set VP_currently_executing to the VP from the queue, then 4.564 - * resume both. 4.565 - */ 4.566 -void 4.567 -handleTransEnd(VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv) 4.568 - { VSsLangData *langData; 4.569 - SlaveVP *waitingSlv; 4.570 - VSsTrans *transStruc; 4.571 - TransListElem *lastTrans; 4.572 - 4.573 - DEBUG__printf1(dbgRqstHdlr,"TransEnd request from processor %d",requestingSlv->slaveNum) 4.574 - 4.575 - transStruc = &(langEnv->transactionStrucs[ langReq->transID ]); 4.576 - 4.577 - //make sure transaction ended in same VP as started it. 4.578 - if( transStruc->VPCurrentlyExecuting != requestingSlv ) 4.579 - { 4.580 - PR_PI__throw_exception( "trans ended in diff VP", requestingSlv, NULL ); 4.581 - } 4.582 - 4.583 - //make sure nesting is correct -- last ID entered should == this ID 4.584 - langData = PR_PI__give_lang_data(requestingSlv, VSs_MAGIC_NUMBER); 4.585 - lastTrans = langData->lastTransEntered; 4.586 - if( lastTrans->transID != langReq->transID ) 4.587 - { 4.588 - PR_PI__throw_exception( "trans incorrectly nested", requestingSlv, NULL ); 4.589 - } 4.590 - 4.591 - langData->lastTransEntered = langData->lastTransEntered->nextTrans; 4.592 - 4.593 - 4.594 - waitingSlv = readPrivQ( transStruc->waitingVPQ ); 4.595 - transStruc->VPCurrentlyExecuting = waitingSlv; 4.596 - 4.597 - if( waitingSlv != NULL ) 4.598 - PR_PI__make_slave_ready( waitingSlv, langEnv ); 4.599 - 4.600 - PR_PI__make_slave_ready( requestingSlv, langEnv ); 4.601 + implement_me(); 4.602 } 4.603 4.604 void
5.1 --- a/VSs_Request_Handlers.h Thu Feb 07 16:30:16 2013 -0800 5.2 +++ b/VSs_Request_Handlers.h Sat Mar 02 10:07:58 2013 -0800 5.3 @@ -15,31 +15,57 @@ 5.4 */ 5.5 5.6 SlaveVP * 5.7 -handleCreateThd( void *_langReq, SlaveVP *requestingSlv, void *_langEnv ); 5.8 +VSs__handleCreateThd( void *_langReq, SlaveVP *requestingSlv, void *_langEnv ); 5.9 void 5.10 -handleDissipate( void *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ); 5.11 +VSs__handleDissipate( void *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ); 5.12 5.13 void * 5.14 -handleSubmitTask( VSsLangReq *langReq, VSsLangEnv *langEnv); 5.15 +VSs__handleSubmitTask( VSsLangReq *langReq, SlaveVP *reqSlv, VSsLangEnv *langEnv); 5.16 void 5.17 -handleEndTask( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ); 5.18 +VSs__handleEndTask( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv ); 5.19 5.20 void 5.21 -handleSendTypeTo( VSsLangReq *langReq, SlaveVP *dummySlv, VSsLangEnv *langEnv); 5.22 +VSs__handleSendTypeTo( VSsLangReq *langReq, SlaveVP *dummySlv, VSsLangEnv *langEnv); 5.23 void 5.24 -handleSendFromTo( VSsLangReq *langReq, SlaveVP* dummySlv, VSsLangEnv *langEnv); 5.25 +VSs__handleSendFromTo( VSsLangReq *langReq, SlaveVP* dummySlv, VSsLangEnv *langEnv); 5.26 void 5.27 -handleReceiveTypeTo( VSsLangReq *langReq, SlaveVP *dummySlv, VSsLangEnv *langEnv); 5.28 +VSs__handleReceiveTypeTo( VSsLangReq *langReq, SlaveVP *dummySlv, VSsLangEnv *langEnv); 5.29 void 5.30 -handleReceiveFromTo( VSsLangReq *langReq, SlaveVP *dummySlv, VSsLangEnv *langEnv); 5.31 +VSs__handleReceiveFromTo( VSsLangReq *langReq, SlaveVP *dummySlv, VSsLangEnv *langEnv); 5.32 void 5.33 -handleTaskwait(VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv); 5.34 +VSs__handleTaskwait(VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv); 5.35 + 5.36 +//==================================== 5.37 +void 5.38 +VSs__lang_meta_task_freer( void *_langMetaTask ); 5.39 + 5.40 inline 5.41 void 5.42 -free_task_stub( VSsTaskStub *stubToFree ); 5.43 +VSs__free_langlet_part_of_lang_meta_task( VSsTaskStub *stubToFree ); 5.44 + 5.45 +void 5.46 +VSs__langDataFreer( void *_langData ); 5.47 5.48 VSsTaskStub * 5.49 VSs__create_generic_slave_task_stub_in_slave( SlaveVP *slave ); 5.50 5.51 +void 5.52 +VSs__handle_shutdown( void *_langEnv ); 5.53 +void * 5.54 +VSs__create_lang_data_in_slave( SlaveVP *slave ); 5.55 +void * 5.56 +VSs__create_empty_lang_meta_task_in_slave( SlaveVP *slave ); 5.57 + 5.58 + 5.59 +void 5.60 +VSs__handleWaitForVSsWorkToEnd( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv); 5.61 +void 5.62 +VSs__handleWaitThenShutdown( VSsLangReq *langReq, SlaveVP *requestingSlv, VSsLangEnv *langEnv); 5.63 + 5.64 +void 5.65 +VSs__resume_slave( SlaveVP *slave, void *_langEnv ); 5.66 +void 5.67 +VSs__make_task_ready( void *taskStub, void *_langEnv ); 5.68 + 5.69 #endif /* _VSs_REQ_H */ 5.70
6.1 --- a/VSs_SS.c Thu Feb 07 16:30:16 2013 -0800 6.2 +++ b/VSs_SS.c Sat Mar 02 10:07:58 2013 -0800 6.3 @@ -12,7 +12,7 @@ 6.4 #include "Hash_impl/PrivateHash.h" 6.5 6.6 #include "VSs.h" 6.7 -#include "Measurement/VSs_Counter_Recording.h" 6.8 +#include "PR_impl/Services_Offered_by_PR/Measurement_and_Stats/PR_MEAS__Counter_Recording.h" 6.9 6.10 //========================================================================== 6.11 6.12 @@ -26,11 +26,11 @@ 6.13 VSs__start( SlaveVP *seedSlv ) 6.14 { VSsLangEnv *langEnv; 6.15 int32 i; 6.16 - VSsLangData *langData; 6.17 + VSsLangData *langData; 6.18 VSsTaskStub *threadTaskStub, *parentTaskStub; 6.19 6.20 langEnv = 6.21 - PR_SS__create_lang_env( sizeof(VSsLangEnv), seedSlv, VSs_MAGIC_NUMBER); 6.22 + (VSsLangEnv *)PR_SS__create_lang_env( sizeof(VSsLangEnv), seedSlv, VSs_MAGIC_NUMBER); 6.23 6.24 //seed slave is a thread slave, so make a thread's task stub for it 6.25 // and then make another to stand for the seed's parent task. Make 6.26 @@ -44,7 +44,7 @@ 6.27 threadTaskStub->isWaitingForChildTasksToEnd = FALSE; 6.28 6.29 parentTaskStub = 6.30 - PR_int__create_lang_meta_task(sizeof(VSsTaskStub), &VSs__lang_meta_task_freer, seedSlv, VSs_MAGIC_NUMBER); 6.31 + PR_int__create_lang_meta_task(sizeof(VSsTaskStub), &VSs__lang_meta_task_freer, VSs_MAGIC_NUMBER); 6.32 6.33 parentTaskStub->isEnded = TRUE; 6.34 parentTaskStub->numLiveChildThreads = 1; //so dissipate works for seed 6.35 @@ -53,20 +53,11 @@ 6.36 6.37 //register the langlet's handlers with PR 6.38 PR_SS__register_assigner( &VSs__assign_work_to_slot, seedSlv, VSs_MAGIC_NUMBER ); 6.39 - PR_SS__register_shutdown_handler( &VSs__handle_shutdown, seedSlv, VSs_MAGIC_NUMBER ); 6.40 + PR_SS__register_lang_shutdown_handler( &VSs__handle_shutdown, seedSlv, VSs_MAGIC_NUMBER ); 6.41 PR_SS__register_lang_data_creator( &VSs__create_lang_data_in_slave, seedSlv, VSs_MAGIC_NUMBER ); 6.42 PR_SS__register_lang_meta_task_creator( &VSs__create_empty_lang_meta_task_in_slave, seedSlv, VSs_MAGIC_NUMBER ); 6.43 - PR_SS__register_make_slave_ready_fn( &VSs__resume_slave ); 6.44 - PR_SS__register_make_task_ready_fn( &VSs__make_task_ready ); 6.45 -/* 6.46 - PR_SS__register_create_task_handler( &createTaskHandler, seedVP, VSs_MAGIC_NUMBER ); 6.47 - PR_SS__register_end_task_handler( &endTaskHandler, seedVP, VSs_MAGIC_NUMBER ); 6.48 - PR_SS__register_create_slave_handler( &createThreadHandler, seedVP, VSs_MAGIC_NUMBER ); 6.49 - PR_SS__register_dissipate_slave_handler( &endThreadHandler, seedVP, VSs_MAGIC_NUMBER ); 6.50 - RequestHandler createInitialLangDataFn; 6.51 - RequestHandler resetLangDataFn; 6.52 - PR_SS__register_request_handler( &VSs__Request_Handler, seedSlv, VSs_MAGIC_NUMBER ); 6.53 - */ 6.54 + PR_SS__register_make_slave_ready_fn( &VSs__resume_slave, seedSlv, VSs_MAGIC_NUMBER ); 6.55 + PR_SS__register_make_task_ready_fn( &VSs__make_task_ready, seedSlv, VSs_MAGIC_NUMBER ); 6.56 6.57 #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS 6.58 _PRTopEnv->counterHandler = &PR_MEAS__counter_handler; 6.59 @@ -95,13 +86,17 @@ 6.60 memset(langEnv->last_in_slot,0,sizeof(NUM_CORES * NUM_ANIM_SLOTS * sizeof(Unit))); 6.61 #endif 6.62 6.63 - MEAS__Make_Meas_Hists_for_VSs 6.64 + MEAS__Make_Meas_Hists_for_VSs(seedSlv, VSs_MAGIC_NUMBER); 6.65 } 6.66 6.67 6.68 -/*This shuts down the langlet 6.69 + 6.70 +/*This runs inside the MasterVP. 6.71 + *It shuts down the langlet 6.72 * Frees any memory allocated by VSs__init() and deletes any slaves or tasks 6.73 * still in ready Qs. 6.74 + * 6.75 + *Note: it needs the special lang-shutdown-request-handler prototype 6.76 */ 6.77 void 6.78 VSs__handle_shutdown( void *_langEnv ) 6.79 @@ -229,36 +224,28 @@ 6.80 SlaveVP *slave; 6.81 VSsTaskStub *task; 6.82 6.83 - //dissipate any slaves still in the readyQ 6.84 + //Not clear what to do with ready slaves still in readyQ.. reasonable to 6.85 + // end them.. also reasonable to send them over to PRServ. 6.86 + //Decided to send ready slaves over to PRServ 6.87 queue = langEnv->slavesReadyToResumeQ; 6.88 slave = readPrivQ( queue ); 6.89 while( slave != NULL ) 6.90 - { handleShutdownDissipate( slave ); 6.91 - PR_int__recycle_slave( slave ); //recycler is for all of PR 6.92 + { PR_PI__resume_slave_in_PRServ( slave ); //recycler is for all of PR 6.93 slave = readPrivQ( queue ); 6.94 } 6.95 freePrivQ( queue ); 6.96 6.97 - //end any tasks still in the readyQ 6.98 + //delete any tasks in the readyQ 6.99 queue = langEnv->taskReadyQ; 6.100 task = readPrivQ( queue ); 6.101 while( task != NULL ) 6.102 - { handleFreeTask( task ); 6.103 + { VSs__free_waiting_task( task ); 6.104 task = readPrivQ( queue ); 6.105 } 6.106 freePrivQ( queue ); 6.107 6.108 freeHashTable( langEnv->commHashTbl ); 6.109 freeHashTable( langEnv->argPtrHashTbl ); 6.110 - 6.111 - int32 i; 6.112 - for( i = 0; i < NUM_STRUCS_IN_LANG_ENV; i++ ) 6.113 - { 6.114 - freePrivQ( langEnv->fnSingletons[i].waitQ ); 6.115 - freePrivQ( langEnv->transactionStrucs[i].waitingVPQ ); 6.116 - } 6.117 - 6.118 - PR_int__free_lang_env( langEnv ); 6.119 } 6.120 6.121