changeset 241:e10973504ed3 Dev__startup_and_shutdown_ver_2

New brch -- changing startup and shutdown to new version
author Some Random Person <seanhalle@yahoo.com>
date Sun, 06 May 2012 12:49:28 -0700
parents 1cfcf49dc7ab
children
files VMS__startup_and_shutdown.c __brch__Common_ancestor __brch__Dev__startup_and_shutdown_ver_2
diffstat 3 files changed, 241 insertions(+), 214 deletions(-) [+]
line diff
     1.1 --- a/VMS__startup_and_shutdown.c	Sun Apr 01 13:53:46 2012 -0700
     1.2 +++ b/VMS__startup_and_shutdown.c	Sun May 06 12:49:28 2012 -0700
     1.3 @@ -26,67 +26,163 @@
     1.4   * int: internal to the VMS implementation
     1.5   */
     1.6  
     1.7 -
     1.8 -//===========================================================================
     1.9 -AnimSlot **
    1.10 -create_anim_slots( int32 coreSlotsAreOn );
    1.11 -
    1.12 -void
    1.13 -create_masterEnv();
    1.14 -
    1.15 -void
    1.16 -create_the_coreCtlr_OS_threads();
    1.17 -
    1.18 -MallocProlog *
    1.19 -create_free_list();
    1.20 -
    1.21 -void
    1.22 -endOSThreadFn( void *initData, SlaveVP *animatingSlv );
    1.23 -
    1.24 -
    1.25 -//===========================================================================
    1.26 -
    1.27 -/*Setup has two phases:
    1.28 - * 1) Semantic layer first calls init_VMS, which creates masterEnv, and puts
    1.29 - *    the master Slv into the work-queue, ready for first "call"
    1.30 - * 2) Semantic layer then does its own init, which creates the seed virt
    1.31 - *    slave inside the semantic layer, ready to assign it when
    1.32 - *    asked by the first run of the animationMaster.
    1.33 - *
    1.34 - *This part is bit weird because VMS really wants to be "always there", and
    1.35 - * have applications attach and detach..  for now, this VMS is part of
    1.36 - * the app, so the VMS system starts up as part of running the app.
    1.37 - *
    1.38 - *The semantic layer is isolated from the VMS internals by making the
    1.39 - * semantic layer do setup to a state that it's ready with its
    1.40 - * initial Slvs, ready to assign them to slots when the animationMaster
    1.41 - * asks.  Without this pattern, the semantic layer's setup would
    1.42 - * have to modify slots directly to assign the initial virt-procrs, and put
    1.43 - * them into the readyToAnimateQ itself, breaking the isolation completely.
    1.44 - *
    1.45 - * 
    1.46 - *The semantic layer creates the initial Slv(s), and adds its
    1.47 - * own environment to masterEnv, and fills in the pointers to
    1.48 - * the requestHandler and slaveAssigner plug-in functions
    1.49 +//==================== Version 2.0 Startup & Shutdown =======================
    1.50 +//
    1.51 +/*Version 2.0  Startup and shutdown is explicitly managed in the base
    1.52 + * language..  VMS is explicitly started, then VMS-language programs are
    1.53 + * explicitly executed, returning a processID
    1.54 + * The processID is used to communicate with the program, wait for it to
    1.55 + * finish, and so on.
    1.56   */
    1.57  
    1.58 -/*This allocates VMS data structures, populates the master VMSProc,
    1.59 - * and master environment, and returns the master environment to the semantic
    1.60 - * layer.
    1.61 +
    1.62 +/*This structure holds all the information VMS needs to manage a program.  VMS
    1.63 + * stores information about what percent of CPU time the program is getting, what
    1.64 + * language it uses, the request handlers to call for its slaves, and so on.
    1.65 + */
    1.66 +typedef struct
    1.67 + { void               *semEnv;
    1.68 +   RequestHdlrFnPtr    requestHandler;
    1.69 +   SlaveAssignerFnPtr  slaveAssigner;
    1.70 +   int32               numSlavesLive;
    1.71 +   void               *resultToReturn;
    1.72 +  
    1.73 +   TopLevelFnPtr   seedFnPtr;
    1.74 +   void           *dataForSeed;
    1.75 +   bool32          executionIsComplete;
    1.76 +   pthread_mutex_t doneLock;
    1.77 +   pthread_cond_t  doneCond;
    1.78 + }
    1.79 +VMSProcess;
    1.80 +
    1.81 +
    1.82 +         
    1.83 +void
    1.84 +VMS__start_VMS_running()
    1.85 + {
    1.86 +   create_masterEnv();
    1.87 +   
    1.88 +   #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
    1.89 +      //Nothing else to create for sequential mode
    1.90 +   #else
    1.91 +      create_the_coreCtlr_OS_threads();
    1.92 +   #endif    
    1.93 + }
    1.94 +
    1.95 +
    1.96 +/*A pointer to the startup-function for the language is given as the last
    1.97 + * argument to the call.  Use this to initialize a program in the language.
    1.98 + * This creates a data structure that encapsulates the bookkeeping info
    1.99 + * VMS uses to track and schedule a program run.
   1.100 + */
   1.101 +VMSProcess *
   1.102 +VMS__spawn_processes_on_data_in_Lang( TopLevelFnPtr prog_seed_fn, void *data,
   1.103 +                                      LangPtr langPtr )
   1.104 + { VMSProcess *newProcess;
   1.105 +   newProcess = malloc( sizeof(VMSProcess) );
   1.106 +   /*a lock + cond-var is used to signal from process to the base language
   1.107 +    * when the process is complete.
   1.108 +    */
   1.109 +   newProcess->doneLock = PTHREAD_MUTEX_INITIALIZER;
   1.110 +   newProcess->doneCond = PTHREAD_COND_INITIALIZER;
   1.111 +   newProcess->executionIsComplete = FALSE; //plugin sets to true
   1.112 +   newProcess->numSlavesLive = 0;
   1.113 +   
   1.114 +   newProcess->langPtr = langPtr;
   1.115 +   
   1.116 +   newProcess->dataForSeed = data;
   1.117 +   newProcess->seedFnPtr   = prog_seed_fn;
   1.118 +   
   1.119 +      //The language's spawn-process function fills in the plugin function-ptrs in
   1.120 +      // the VMSProcess struct, gives the struct to VMS, which then makes and
   1.121 +      // queues the seed SlaveVP, which starts processors made from the code being
   1.122 +      // animated.
   1.123 +   langInitFnPtr = langPtr->langInitFnPtr;
   1.124 +   
   1.125 +   (*langInitFnPtr)( newProcess );  
   1.126 +   
   1.127 +   return newProcess;
   1.128 + }
   1.129 +
   1.130 +
   1.131 +/*When all SlaveVPs owned by the program-run associated to the process have
   1.132 + * dissipated, then return from this call.  There is no language to cleanup,
   1.133 + * and VMS does not shutdown..  but the process bookkeeping structure,
   1.134 + * which is used by VMS to track and schedule the program, is freed.
   1.135 + *The VMSProcess structure is kept until this call collects the results from it,
   1.136 + * then freed.  If the process is not done yet when VMS gets this
   1.137 + * call, then this call waits..  the challenge here is that this call comes from
   1.138 + * a live OS thread that's outside VMS..  so, inside here, it waits on a 
   1.139 + * condition..  then it's a VMS thread that signals this to wake up..
   1.140 + *First checks whether the process is done, if yes, calls the clean-up fn then
   1.141 + * returns the result extracted from the VMSProcess struct.
   1.142 + *If process not done yet, then performs a wait (in a loop to be sure the
   1.143 + * wakeup is not spurious, which can happen).  VMS registers the wait, and upon
   1.144 + * the process ending (last SlaveVP owned by it dissipates), then VMS signals
   1.145 + * this to wakeup.  This then calls the cleanup fn and returns the result.
   1.146 + */
   1.147 +void *
   1.148 +VMS__when_process_done_give_results_for( VMSProcess *process )
   1.149 + { void *result;
   1.150 +   
   1.151 +   pthread_mutex_lock( process->doneLock );
   1.152 +   while( !(process->executionIsComplete) )
   1.153 +    {
   1.154 +      pthread_cond_wait( process->doneCond,
   1.155 +                         process->doneLock );
   1.156 +    }
   1.157 +   pthread_mutex_unlock( process->doneLock );
   1.158 +   
   1.159 +   result = process->resultToReturn;
   1.160 +   
   1.161 +   VMS_SS__dissipate_process( process );
   1.162 +   free( process );  //was malloc'd above, so free it here
   1.163 +   
   1.164 +   return result;
   1.165 + }
   1.166 +
   1.167 +/*When a process is dissipated, there is VMS state that has to be modified
   1.168 + * and the language may have process-dissipation code it needs to run
   1.169 + *Not sure yet whether can use the same dissipate for both complete
   1.170 + * processes, as well as partial processes that are stopped in the middle
   1.171 + * by this.
   1.172 + *This should remove the process from any internal structures VMS uses to
   1.173 + * decide which process's slaves get scheduled next, which has effect of
   1.174 + * removing the process from VMS's awareness, for scheduling..  so that's
   1.175 + * good..  there shouldn't be any other ways the active VMS is aware of
   1.176 + * a process..
   1.177   */
   1.178  void
   1.179 -VMS_SS__init()
   1.180 +VMS_SS__dissipate_process( VMSProcess *process )
   1.181   {
   1.182 -   #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
   1.183 -      create_masterEnv();
   1.184 -      printf( "\n\n Running in SEQUENTIAL mode \n\n" );
   1.185 -   #else
   1.186 -      create_masterEnv();
   1.187 -      DEBUG__printf1(TRUE,"Offset of lock in masterEnv: %d ", (int32)offsetof(MasterEnv,masterLock) );
   1.188 -      create_the_coreCtlr_OS_threads();
   1.189 -   #endif
   1.190 +   
   1.191   }
   1.192  
   1.193 +/*Turns off the VMS system, and frees all data associated with it.  Does this
   1.194 + * by creating shutdown SlaveVPs and inserting them into animation slots.
   1.195 + * Will probably have to wake up sleeping cores as part of this -- the fn that
   1.196 + * inserts the new SlaveVPs should handle the wakeup..
   1.197 + */
   1.198 +void
   1.199 +VMS__shutdown()
   1.200 + {
   1.201 +   for( cores )
   1.202 +    { slave = VMS_int__create_new_SlaveVP( endOSThreadFn, NULL );
   1.203 +      VMS_int__insert_slave_onto_core( SlaveVP *slave, coreNum );
   1.204 +    }
   1.205 + }
   1.206 +
   1.207 +
   1.208 +VMS__start_VMS_running();
   1.209 +
   1.210 +VMSProcess matrixMultProcess;
   1.211 +   
   1.212 +matrixMultProcess =
   1.213 +    VMS__spawn_process_on_data_in_Lang( &prog_seed_fn, data, Vthread_lang );
   1.214 +   
   1.215 +resMatrix = VMS__give_results_when_done_for( matrixMultProcess );
   1.216 +   
   1.217 +VMS__shutdown();
   1.218  
   1.219  /*TODO: finish implementing
   1.220   *This function returns information about the version of VMS, the language
   1.221 @@ -132,141 +228,72 @@
   1.222     //--------------------------
   1.223   }
   1.224   */
   1.225 - 
   1.226 -/*This structure holds all the information VMS needs to manage a program.  VMS
   1.227 - * stores information about what percent of CPU time the program is getting, what
   1.228 - * language it uses, the request handlers to call for its slaves, and so on.
   1.229 - */
   1.230 -/*
   1.231 -typedef struct
   1.232 - { void               *semEnv;
   1.233 -   RequestHdlrFnPtr    requestHandler;
   1.234 -   SlaveAssignerFnPtr  slaveAssigner;
   1.235 -   int32               numSlavesLive;
   1.236 -   void               *resultToReturn;
   1.237 -  
   1.238 -   TopLevelFnPtr   seedFnPtr;
   1.239 -   void           *dataForSeed;
   1.240 -   bool32          executionIsComplete;
   1.241 -   pthread_mutex_t doneLock;
   1.242 -   pthread_cond_t  doneCond;
   1.243 - }
   1.244 -VMSProcess;
   1.245 -*/
   1.246  
   1.247 -         
   1.248 -/*
   1.249 -void
   1.250 -VMS__start_VMS_running()
   1.251 - {
   1.252 -   create_masterEnv();
   1.253 -   
   1.254 -   #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
   1.255 -      //Nothing else to create for sequential mode
   1.256 -   #else
   1.257 -      create_the_coreCtlr_OS_threads();
   1.258 -   #endif    
   1.259 - }
   1.260 -*/
   1.261  
   1.262 -/*A pointer to the startup-function for the language is given as the last
   1.263 - * argument to the call.  Use this to initialize a program in the language.
   1.264 - * This creates a data structure that encapsulates the bookkeeping info
   1.265 - * VMS uses to track and schedule a program run.
   1.266 - */
   1.267 -/*
   1.268 -VMSProcess *
   1.269 -VMS__spawn_program_on_data_in_Lang( TopLevelFnPtr prog_seed_fn, void *data,
   1.270 -                                    LangInitFnPtr langInitFnPtr )
   1.271 - { VMSProcess *newProcess;
   1.272 -   newProcess = malloc( sizeof(VMSProcess) );
   1.273 -   newProcess->doneLock = PTHREAD_MUTEX_INITIALIZER;
   1.274 -   newProcess->doneCond = PTHREAD_COND_INITIALIZER;
   1.275 -   newProcess->executionIsComplete = FALSE;
   1.276 -   newProcess->numSlavesLive = 0;
   1.277 -   
   1.278 -   newProcess->dataForSeed = data;
   1.279 -   newProcess->seedFnPtr   = prog_seed_fn;
   1.280 -   
   1.281 -      //The language's spawn-process function fills in the plugin function-ptrs in
   1.282 -      // the VMSProcess struct, gives the struct to VMS, which then makes and
   1.283 -      // queues the seed SlaveVP, which starts processors made from the code being
   1.284 -      // animated.
   1.285 -    
   1.286 -   (*langInitFnPtr)( newProcess );  
   1.287 -   
   1.288 -   return newProcess;
   1.289 - }
   1.290 -*/
   1.291 -
   1.292 -/*When all SlaveVPs owned by the program-run associated to the process have
   1.293 - * dissipated, then return from this call.  There is no language to cleanup,
   1.294 - * and VMS does not shutdown..  but the process bookkeeping structure,
   1.295 - * which is used by VMS to track and schedule the program, is freed.
   1.296 - *The VMSProcess structure is kept until this call collects the results from it,
   1.297 - * then freed.  If the process is not done yet when VMS gets this
   1.298 - * call, then this call waits..  the challenge here is that this call comes from
   1.299 - * a live OS thread that's outside VMS..  so, inside here, it waits on a 
   1.300 - * condition..  then it's a VMS thread that signals this to wake up..
   1.301 - *First checks whether the process is done, if yes, calls the clean-up fn then
   1.302 - * returns the result extracted from the VMSProcess struct.
   1.303 - *If process not done yet, then performs a wait (in a loop to be sure the
   1.304 - * wakeup is not spurious, which can happen).  VMS registers the wait, and upon
   1.305 - * the process ending (last SlaveVP owned by it dissipates), then VMS signals
   1.306 - * this to wakeup.  This then calls the cleanup fn and returns the result.
   1.307 - */
   1.308 -/*
   1.309 -void *
   1.310 -VMS__give_results_when_done_for( VMSProcess *process )
   1.311 - { void *result;
   1.312 -   
   1.313 -   pthread_mutex_lock( process->doneLock );
   1.314 -   while( !(process->executionIsComplete) )
   1.315 -    {
   1.316 -      pthread_cond_wait( process->doneCond,
   1.317 -                         process->doneLock );
   1.318 -    }
   1.319 -   pthread_mutex_unlock( process->doneLock );
   1.320 -   
   1.321 -   result = process->resultToReturn;
   1.322 -   
   1.323 -   VMS_int__cleanup_process_after_done( process );
   1.324 -   free( process );  //was malloc'd above, so free it here
   1.325 -   
   1.326 -   return result;
   1.327 - }
   1.328 -*/
   1.329 -
   1.330 -/*Turns off the VMS system, and frees all data associated with it.  Does this
   1.331 - * by creating shutdown SlaveVPs and inserting them into animation slots.
   1.332 - * Will probably have to wake up sleeping cores as part of this -- the fn that
   1.333 - * inserts the new SlaveVPs should handle the wakeup..
   1.334 - */
   1.335 -/*
   1.336 -void
   1.337 -VMS_SS__shutdown(); //already defined -- look at it
   1.338 +//=================== Version 1.0 Startup & Shutdown ========================
   1.339 +//
   1.340 +AnimSlot **
   1.341 +create_anim_slots( int32 coreSlotsAreOn );
   1.342  
   1.343  void
   1.344 -VMS__shutdown()
   1.345 +create_masterEnv();
   1.346 +
   1.347 +void
   1.348 +create_the_coreCtlr_OS_threads();
   1.349 +
   1.350 +MallocProlog *
   1.351 +create_free_list();
   1.352 +
   1.353 +void
   1.354 +endOSThreadFn( void *initData, SlaveVP *animatingSlv );
   1.355 +
   1.356 +
   1.357 +//===========================================================================
   1.358 +
   1.359 +/*Setup has two phases:
   1.360 + * 1) Semantic layer first calls init_VMS, which creates masterEnv, and puts
   1.361 + *    the master Slv into the work-queue, ready for first "call"
   1.362 + * 2) Semantic layer then does its own init, which creates the seed virt
   1.363 + *    slave inside the semantic layer, ready to assign it when
   1.364 + *    asked by the first run of the animationMaster.
   1.365 + *
   1.366 + *This part is bit weird because VMS really wants to be "always there", and
   1.367 + * have applications attach and detach..  for now, this VMS is part of
   1.368 + * the app, so the VMS system starts up as part of running the app.
   1.369 + *
   1.370 + *The semantic layer is isolated from the VMS internals by making the
   1.371 + * semantic layer do setup to a state that it's ready with its
   1.372 + * initial Slvs, ready to assign them to slots when the animationMaster
   1.373 + * asks.  Without this pattern, the semantic layer's setup would
   1.374 + * have to modify slots directly to assign the initial virt-procrs, and put
   1.375 + * them into the readyToAnimateQ itself, breaking the isolation completely.
   1.376 + *
   1.377 + * 
   1.378 + *The semantic layer creates the initial Slv(s), and adds its
   1.379 + * own environment to masterEnv, and fills in the pointers to
   1.380 + * the requestHandler and slaveAssigner plug-in functions
   1.381 + */
   1.382 +
   1.383 +/*This allocates VMS data structures, populates the master VMSProc,
   1.384 + * and master environment, and returns the master environment to the semantic
   1.385 + * layer.
   1.386 + */
   1.387 +void
   1.388 +VMS_SS__init()
   1.389   {
   1.390 -   for( cores )
   1.391 -    { slave = VMS_int__create_new_SlaveVP( endOSThreadFn, NULL );
   1.392 -      VMS_int__insert_slave_onto_core( SlaveVP *slave, coreNum );
   1.393 -    }
   1.394 +   #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
   1.395 +      create_masterEnv();
   1.396 +      printf( "\n\n Running in SEQUENTIAL mode \n\n" );
   1.397 +   #else
   1.398 +      create_masterEnv();
   1.399 +      DEBUG__printf1(TRUE,"Offset of lock in masterEnv: %d ", (int32)offsetof(MasterEnv,masterLock) );
   1.400 +      create_the_coreCtlr_OS_threads();
   1.401 +   #endif
   1.402   }
   1.403 -*/
   1.404  
   1.405 -/* VMS__start_VMS_running();
   1.406  
   1.407 -   VMSProcess matrixMultProcess;
   1.408 -   
   1.409 -   matrixMultProcess =
   1.410 -    VMS__spawn_program_on_data_in_Lang( &prog_seed_fn, data, Vthread_lang );
   1.411 -   
   1.412 -   resMatrix = VMS__give_results_when_done_for( matrixMultProcess );
   1.413 -   
   1.414 -   VMS__shutdown();
   1.415 - */
   1.416 +
   1.417 +
   1.418  
   1.419  void
   1.420  create_masterEnv()
     2.1 --- a/__brch__Common_ancestor	Sun Apr 01 13:53:46 2012 -0700
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,33 +0,0 @@
     2.4 -A HW branch for:
     2.5 -
     2.6 -generic MultiCore machines with x86 64bit instruction set
     2.7 -
     2.8 -This branch shouldn't be used, except as a lazy fall-back.  Instead, try out other branches tuned to specific hardware platforms to find the one that performs best on your machine.  Use the "exe_time_vs_task_size" project to generate curves of overhead, and compare result from various branches.
     2.9 -
    2.10 -Note, if this branch is used, then NUM_CORES in VMS_HW_specific_defs.h file has to be updated with the number of cores in your machine
    2.11 -
    2.12 -========  Background on branch naming  =========
    2.13 -
    2.14 -There are two kinds of branchs: ones used to develop features, and ones tuned to particular hardware.  A given HW branch may combine features from several feature-branches, picking and choosing among them.
    2.15 -
    2.16 -After Feb 2012, branches are named by the scheme:
    2.17 -
    2.18 -feat__<feat_descr>__<HW_feat_dev_on>
    2.19 -
    2.20 -HW__<desc_of_HW_brch_tuned_for>
    2.21 -
    2.22 -where <HW_feat_dev_on> and <desc_of_HW_brch_tuned_for> follow the pattern:
    2.23 -
    2.24 -<num_socket> x <num_cores>_<Manuf>_<special_features>
    2.25 -
    2.26 -Examples:
    2.27 -
    2.28 -feat__exp_array_malloc
    2.29 -
    2.30 -feat__rand_backoff__4x10_Intel_WestmereEx
    2.31 -
    2.32 -HW__1x4_Intel_SandyBridge
    2.33 -
    2.34 -HW__4x10_Intel_WestmereEx
    2.35 -
    2.36 -HW__1x4_AMD_mobile
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/__brch__Dev__startup_and_shutdown_ver_2	Sun May 06 12:49:28 2012 -0700
     3.3 @@ -0,0 +1,33 @@
     3.4 +A HW branch for:
     3.5 +
     3.6 +generic MultiCore machines with x86 64bit instruction set
     3.7 +
     3.8 +This branch shouldn't be used, except as a lazy fall-back.  Instead, try out other branches tuned to specific hardware platforms to find the one that performs best on your machine.  Use the "exe_time_vs_task_size" project to generate curves of overhead, and compare result from various branches.
     3.9 +
    3.10 +Note, if this branch is used, then NUM_CORES in VMS_HW_specific_defs.h file has to be updated with the number of cores in your machine
    3.11 +
    3.12 +========  Background on branch naming  =========
    3.13 +
    3.14 +There are two kinds of branchs: ones used to develop features, and ones tuned to particular hardware.  A given HW branch may combine features from several feature-branches, picking and choosing among them.
    3.15 +
    3.16 +After Feb 2012, branches are named by the scheme:
    3.17 +
    3.18 +feat__<feat_descr>__<HW_feat_dev_on>
    3.19 +
    3.20 +HW__<desc_of_HW_brch_tuned_for>
    3.21 +
    3.22 +where <HW_feat_dev_on> and <desc_of_HW_brch_tuned_for> follow the pattern:
    3.23 +
    3.24 +<num_socket> x <num_cores>_<Manuf>_<special_features>
    3.25 +
    3.26 +Examples:
    3.27 +
    3.28 +feat__exp_array_malloc
    3.29 +
    3.30 +feat__rand_backoff__4x10_Intel_WestmereEx
    3.31 +
    3.32 +HW__1x4_Intel_SandyBridge
    3.33 +
    3.34 +HW__4x10_Intel_WestmereEx
    3.35 +
    3.36 +HW__1x4_AMD_mobile