# HG changeset patch # User Some Random Person # Date 1336333768 25200 # Node ID e10973504ed39628c9f3f63e69880ff57bd1627b # Parent 1cfcf49dc7ab67b9bb18b52d60c74027cadb6360 New brch -- changing startup and shutdown to new version diff -r 1cfcf49dc7ab -r e10973504ed3 VMS__startup_and_shutdown.c --- a/VMS__startup_and_shutdown.c Sun Apr 01 13:53:46 2012 -0700 +++ b/VMS__startup_and_shutdown.c Sun May 06 12:49:28 2012 -0700 @@ -26,67 +26,163 @@ * int: internal to the VMS implementation */ - -//=========================================================================== -AnimSlot ** -create_anim_slots( int32 coreSlotsAreOn ); - -void -create_masterEnv(); - -void -create_the_coreCtlr_OS_threads(); - -MallocProlog * -create_free_list(); - -void -endOSThreadFn( void *initData, SlaveVP *animatingSlv ); - - -//=========================================================================== - -/*Setup has two phases: - * 1) Semantic layer first calls init_VMS, which creates masterEnv, and puts - * the master Slv into the work-queue, ready for first "call" - * 2) Semantic layer then does its own init, which creates the seed virt - * slave inside the semantic layer, ready to assign it when - * asked by the first run of the animationMaster. - * - *This part is bit weird because VMS really wants to be "always there", and - * have applications attach and detach.. for now, this VMS is part of - * the app, so the VMS system starts up as part of running the app. - * - *The semantic layer is isolated from the VMS internals by making the - * semantic layer do setup to a state that it's ready with its - * initial Slvs, ready to assign them to slots when the animationMaster - * asks. Without this pattern, the semantic layer's setup would - * have to modify slots directly to assign the initial virt-procrs, and put - * them into the readyToAnimateQ itself, breaking the isolation completely. - * - * - *The semantic layer creates the initial Slv(s), and adds its - * own environment to masterEnv, and fills in the pointers to - * the requestHandler and slaveAssigner plug-in functions +//==================== Version 2.0 Startup & Shutdown ======================= +// +/*Version 2.0 Startup and shutdown is explicitly managed in the base + * language.. VMS is explicitly started, then VMS-language programs are + * explicitly executed, returning a processID + * The processID is used to communicate with the program, wait for it to + * finish, and so on. */ -/*This allocates VMS data structures, populates the master VMSProc, - * and master environment, and returns the master environment to the semantic - * layer. + +/*This structure holds all the information VMS needs to manage a program. VMS + * stores information about what percent of CPU time the program is getting, what + * language it uses, the request handlers to call for its slaves, and so on. + */ +typedef struct + { void *semEnv; + RequestHdlrFnPtr requestHandler; + SlaveAssignerFnPtr slaveAssigner; + int32 numSlavesLive; + void *resultToReturn; + + TopLevelFnPtr seedFnPtr; + void *dataForSeed; + bool32 executionIsComplete; + pthread_mutex_t doneLock; + pthread_cond_t doneCond; + } +VMSProcess; + + + +void +VMS__start_VMS_running() + { + create_masterEnv(); + + #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE + //Nothing else to create for sequential mode + #else + create_the_coreCtlr_OS_threads(); + #endif + } + + +/*A pointer to the startup-function for the language is given as the last + * argument to the call. Use this to initialize a program in the language. + * This creates a data structure that encapsulates the bookkeeping info + * VMS uses to track and schedule a program run. + */ +VMSProcess * +VMS__spawn_processes_on_data_in_Lang( TopLevelFnPtr prog_seed_fn, void *data, + LangPtr langPtr ) + { VMSProcess *newProcess; + newProcess = malloc( sizeof(VMSProcess) ); + /*a lock + cond-var is used to signal from process to the base language + * when the process is complete. + */ + newProcess->doneLock = PTHREAD_MUTEX_INITIALIZER; + newProcess->doneCond = PTHREAD_COND_INITIALIZER; + newProcess->executionIsComplete = FALSE; //plugin sets to true + newProcess->numSlavesLive = 0; + + newProcess->langPtr = langPtr; + + newProcess->dataForSeed = data; + newProcess->seedFnPtr = prog_seed_fn; + + //The language's spawn-process function fills in the plugin function-ptrs in + // the VMSProcess struct, gives the struct to VMS, which then makes and + // queues the seed SlaveVP, which starts processors made from the code being + // animated. + langInitFnPtr = langPtr->langInitFnPtr; + + (*langInitFnPtr)( newProcess ); + + return newProcess; + } + + +/*When all SlaveVPs owned by the program-run associated to the process have + * dissipated, then return from this call. There is no language to cleanup, + * and VMS does not shutdown.. but the process bookkeeping structure, + * which is used by VMS to track and schedule the program, is freed. + *The VMSProcess structure is kept until this call collects the results from it, + * then freed. If the process is not done yet when VMS gets this + * call, then this call waits.. the challenge here is that this call comes from + * a live OS thread that's outside VMS.. so, inside here, it waits on a + * condition.. then it's a VMS thread that signals this to wake up.. + *First checks whether the process is done, if yes, calls the clean-up fn then + * returns the result extracted from the VMSProcess struct. + *If process not done yet, then performs a wait (in a loop to be sure the + * wakeup is not spurious, which can happen). VMS registers the wait, and upon + * the process ending (last SlaveVP owned by it dissipates), then VMS signals + * this to wakeup. This then calls the cleanup fn and returns the result. + */ +void * +VMS__when_process_done_give_results_for( VMSProcess *process ) + { void *result; + + pthread_mutex_lock( process->doneLock ); + while( !(process->executionIsComplete) ) + { + pthread_cond_wait( process->doneCond, + process->doneLock ); + } + pthread_mutex_unlock( process->doneLock ); + + result = process->resultToReturn; + + VMS_SS__dissipate_process( process ); + free( process ); //was malloc'd above, so free it here + + return result; + } + +/*When a process is dissipated, there is VMS state that has to be modified + * and the language may have process-dissipation code it needs to run + *Not sure yet whether can use the same dissipate for both complete + * processes, as well as partial processes that are stopped in the middle + * by this. + *This should remove the process from any internal structures VMS uses to + * decide which process's slaves get scheduled next, which has effect of + * removing the process from VMS's awareness, for scheduling.. so that's + * good.. there shouldn't be any other ways the active VMS is aware of + * a process.. */ void -VMS_SS__init() +VMS_SS__dissipate_process( VMSProcess *process ) { - #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE - create_masterEnv(); - printf( "\n\n Running in SEQUENTIAL mode \n\n" ); - #else - create_masterEnv(); - DEBUG__printf1(TRUE,"Offset of lock in masterEnv: %d ", (int32)offsetof(MasterEnv,masterLock) ); - create_the_coreCtlr_OS_threads(); - #endif + } +/*Turns off the VMS system, and frees all data associated with it. Does this + * by creating shutdown SlaveVPs and inserting them into animation slots. + * Will probably have to wake up sleeping cores as part of this -- the fn that + * inserts the new SlaveVPs should handle the wakeup.. + */ +void +VMS__shutdown() + { + for( cores ) + { slave = VMS_int__create_new_SlaveVP( endOSThreadFn, NULL ); + VMS_int__insert_slave_onto_core( SlaveVP *slave, coreNum ); + } + } + + +VMS__start_VMS_running(); + +VMSProcess matrixMultProcess; + +matrixMultProcess = + VMS__spawn_process_on_data_in_Lang( &prog_seed_fn, data, Vthread_lang ); + +resMatrix = VMS__give_results_when_done_for( matrixMultProcess ); + +VMS__shutdown(); /*TODO: finish implementing *This function returns information about the version of VMS, the language @@ -132,141 +228,72 @@ //-------------------------- } */ - -/*This structure holds all the information VMS needs to manage a program. VMS - * stores information about what percent of CPU time the program is getting, what - * language it uses, the request handlers to call for its slaves, and so on. - */ -/* -typedef struct - { void *semEnv; - RequestHdlrFnPtr requestHandler; - SlaveAssignerFnPtr slaveAssigner; - int32 numSlavesLive; - void *resultToReturn; - - TopLevelFnPtr seedFnPtr; - void *dataForSeed; - bool32 executionIsComplete; - pthread_mutex_t doneLock; - pthread_cond_t doneCond; - } -VMSProcess; -*/ - -/* -void -VMS__start_VMS_running() - { - create_masterEnv(); - - #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE - //Nothing else to create for sequential mode - #else - create_the_coreCtlr_OS_threads(); - #endif - } -*/ -/*A pointer to the startup-function for the language is given as the last - * argument to the call. Use this to initialize a program in the language. - * This creates a data structure that encapsulates the bookkeeping info - * VMS uses to track and schedule a program run. - */ -/* -VMSProcess * -VMS__spawn_program_on_data_in_Lang( TopLevelFnPtr prog_seed_fn, void *data, - LangInitFnPtr langInitFnPtr ) - { VMSProcess *newProcess; - newProcess = malloc( sizeof(VMSProcess) ); - newProcess->doneLock = PTHREAD_MUTEX_INITIALIZER; - newProcess->doneCond = PTHREAD_COND_INITIALIZER; - newProcess->executionIsComplete = FALSE; - newProcess->numSlavesLive = 0; - - newProcess->dataForSeed = data; - newProcess->seedFnPtr = prog_seed_fn; - - //The language's spawn-process function fills in the plugin function-ptrs in - // the VMSProcess struct, gives the struct to VMS, which then makes and - // queues the seed SlaveVP, which starts processors made from the code being - // animated. - - (*langInitFnPtr)( newProcess ); - - return newProcess; - } -*/ - -/*When all SlaveVPs owned by the program-run associated to the process have - * dissipated, then return from this call. There is no language to cleanup, - * and VMS does not shutdown.. but the process bookkeeping structure, - * which is used by VMS to track and schedule the program, is freed. - *The VMSProcess structure is kept until this call collects the results from it, - * then freed. If the process is not done yet when VMS gets this - * call, then this call waits.. the challenge here is that this call comes from - * a live OS thread that's outside VMS.. so, inside here, it waits on a - * condition.. then it's a VMS thread that signals this to wake up.. - *First checks whether the process is done, if yes, calls the clean-up fn then - * returns the result extracted from the VMSProcess struct. - *If process not done yet, then performs a wait (in a loop to be sure the - * wakeup is not spurious, which can happen). VMS registers the wait, and upon - * the process ending (last SlaveVP owned by it dissipates), then VMS signals - * this to wakeup. This then calls the cleanup fn and returns the result. - */ -/* -void * -VMS__give_results_when_done_for( VMSProcess *process ) - { void *result; - - pthread_mutex_lock( process->doneLock ); - while( !(process->executionIsComplete) ) - { - pthread_cond_wait( process->doneCond, - process->doneLock ); - } - pthread_mutex_unlock( process->doneLock ); - - result = process->resultToReturn; - - VMS_int__cleanup_process_after_done( process ); - free( process ); //was malloc'd above, so free it here - - return result; - } -*/ - -/*Turns off the VMS system, and frees all data associated with it. Does this - * by creating shutdown SlaveVPs and inserting them into animation slots. - * Will probably have to wake up sleeping cores as part of this -- the fn that - * inserts the new SlaveVPs should handle the wakeup.. - */ -/* -void -VMS_SS__shutdown(); //already defined -- look at it +//=================== Version 1.0 Startup & Shutdown ======================== +// +AnimSlot ** +create_anim_slots( int32 coreSlotsAreOn ); void -VMS__shutdown() +create_masterEnv(); + +void +create_the_coreCtlr_OS_threads(); + +MallocProlog * +create_free_list(); + +void +endOSThreadFn( void *initData, SlaveVP *animatingSlv ); + + +//=========================================================================== + +/*Setup has two phases: + * 1) Semantic layer first calls init_VMS, which creates masterEnv, and puts + * the master Slv into the work-queue, ready for first "call" + * 2) Semantic layer then does its own init, which creates the seed virt + * slave inside the semantic layer, ready to assign it when + * asked by the first run of the animationMaster. + * + *This part is bit weird because VMS really wants to be "always there", and + * have applications attach and detach.. for now, this VMS is part of + * the app, so the VMS system starts up as part of running the app. + * + *The semantic layer is isolated from the VMS internals by making the + * semantic layer do setup to a state that it's ready with its + * initial Slvs, ready to assign them to slots when the animationMaster + * asks. Without this pattern, the semantic layer's setup would + * have to modify slots directly to assign the initial virt-procrs, and put + * them into the readyToAnimateQ itself, breaking the isolation completely. + * + * + *The semantic layer creates the initial Slv(s), and adds its + * own environment to masterEnv, and fills in the pointers to + * the requestHandler and slaveAssigner plug-in functions + */ + +/*This allocates VMS data structures, populates the master VMSProc, + * and master environment, and returns the master environment to the semantic + * layer. + */ +void +VMS_SS__init() { - for( cores ) - { slave = VMS_int__create_new_SlaveVP( endOSThreadFn, NULL ); - VMS_int__insert_slave_onto_core( SlaveVP *slave, coreNum ); - } + #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE + create_masterEnv(); + printf( "\n\n Running in SEQUENTIAL mode \n\n" ); + #else + create_masterEnv(); + DEBUG__printf1(TRUE,"Offset of lock in masterEnv: %d ", (int32)offsetof(MasterEnv,masterLock) ); + create_the_coreCtlr_OS_threads(); + #endif } -*/ -/* VMS__start_VMS_running(); - VMSProcess matrixMultProcess; - - matrixMultProcess = - VMS__spawn_program_on_data_in_Lang( &prog_seed_fn, data, Vthread_lang ); - - resMatrix = VMS__give_results_when_done_for( matrixMultProcess ); - - VMS__shutdown(); - */ + + void create_masterEnv() diff -r 1cfcf49dc7ab -r e10973504ed3 __brch__Common_ancestor --- a/__brch__Common_ancestor Sun Apr 01 13:53:46 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -A HW branch for: - -generic MultiCore machines with x86 64bit instruction set - -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. - -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 - -======== Background on branch naming ========= - -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. - -After Feb 2012, branches are named by the scheme: - -feat____ - -HW__ - -where and follow the pattern: - - x __ - -Examples: - -feat__exp_array_malloc - -feat__rand_backoff__4x10_Intel_WestmereEx - -HW__1x4_Intel_SandyBridge - -HW__4x10_Intel_WestmereEx - -HW__1x4_AMD_mobile diff -r 1cfcf49dc7ab -r e10973504ed3 __brch__Dev__startup_and_shutdown_ver_2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/__brch__Dev__startup_and_shutdown_ver_2 Sun May 06 12:49:28 2012 -0700 @@ -0,0 +1,33 @@ +A HW branch for: + +generic MultiCore machines with x86 64bit instruction set + +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. + +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 + +======== Background on branch naming ========= + +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. + +After Feb 2012, branches are named by the scheme: + +feat____ + +HW__ + +where and follow the pattern: + + x __ + +Examples: + +feat__exp_array_malloc + +feat__rand_backoff__4x10_Intel_WestmereEx + +HW__1x4_Intel_SandyBridge + +HW__4x10_Intel_WestmereEx + +HW__1x4_AMD_mobile