#include #include #include "trick/Executive.hh" #include "trick/ExecutiveException.hh" #include "trick/exec_proto.h" #include "trick/message_proto.h" #include "trick/message_type.h" /** @details -# Set the mode to Freeze. Requirement [@ref r_exec_mode_2] -# Call freeze_init jobs. Requirement [@ref r_exec_discrete_2]. -# While mode is Freeze -# Call the freeze jobs Requirement [@ref r_exec_periodic_1]. -# If the exec_command is set to RunCmd, set the mode to Run. -# If the exec_command is set to ExitCmd, call exec_terminate_with_return -# Call unfreeze jobs. Requirement [@ref r_exec_discrete_3]. */ int Trick::Executive::freeze_loop() { int ret ; /* Set the mode to Freeze */ mode = Freeze; /* Execute the Freeze Init Jobs. */ freeze_init_queue.reset_curr_index() ; while ( (curr_job = freeze_init_queue.get_next_job()) != NULL ) { curr_job->call() ; } message_publish(MSG_INFO, "Freeze ON. Simulation time holding at %f seconds.\n" , get_sim_time()) ; while (mode == Freeze) { /* Run the Freeze Scheduled Jobs. */ while ( freeze_time_tics < next_freeze_frame_check_tics ) { /* Call all freeze loop jobs that are scheduled to run at the current freeze loop time step. */ freeze_scheduled_queue.reset_curr_index() ; while ( (curr_job = freeze_scheduled_queue.find_next_job( freeze_time_tics )) != NULL ) { ret = curr_job->call() ; if ( ret != 0 ) { exec_terminate_with_return(ret , curr_job->name.c_str() , 0 , "job did not return 0") ; } if ( curr_job->system_job_class ) { freeze_scheduled_queue.test_next_job_call_time(curr_job , freeze_time_tics) ; } } // Get the next job call time. Set the freeze clock to this time freeze_time_tics = freeze_scheduled_queue.get_next_job_call_time() ; // If the next freeze frame time is smaller than then current freeze time, set it to the frame time if ( next_freeze_frame_check_tics < freeze_time_tics ) { freeze_time_tics = next_freeze_frame_check_tics ; } // Start the next job call time for the next loop to be 1 software frame from the current time. freeze_scheduled_queue.set_next_job_call_time(freeze_time_tics + freeze_frame_tics) ; } freeze_frame_count++ ; next_freeze_frame_check_tics += freeze_frame_tics ; /* Enter loop that continually executes the Freeze Jobs. */ freeze_queue.reset_curr_index() ; while ( (curr_job = freeze_queue.get_next_job()) != NULL ) { ret = curr_job->call() ; if ( ret != 0 ) { exec_terminate_with_return(ret , curr_job->name.c_str() , 0 , "job did not return 0") ; } } /* Exit loop executing freeze jobs if commanded from run() */ if (exec_command == RunCmd) { mode = Run ; exec_command = NoCmd ; } else if ( exec_command == FreezeCmd ) { /* redundant freeze command. Clear it. */ exec_command = NoCmd ; } /* Call Executive::exec_terminate_with_return(int , const char * , int , const char *) if exec_command equals ExitCmd. */ if (exec_command == ExitCmd) { exec_terminate_with_return( 0 , __FILE__ , __LINE__ , "Sim control Shutdown" ) ; } } message_publish(MSG_INFO,"Freeze OFF.\n") ; /* Execute the Unfreeze Jobs. */ unfreeze_queue.reset_curr_index() ; while ( (curr_job = unfreeze_queue.get_next_job()) != NULL ) { curr_job->call() ; } return(0) ; }