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