Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
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
