#include #include #include #if __linux #include #endif #include "trick/Executive.hh" #include "trick/ExecutiveException.hh" #include "trick/TrickConstant.hh" Trick::Executive * the_exec ; Trick::Executive::Executive() { /** @par Detailed Design: */ the_exec = this ; advance_sim_time_job = NULL ; attach_debugger = false ; curr_job = NULL ; struct stat st ; if ( stat("/usr/bin/gdb",&st) == 0 ) { debugger_command = std::string("/usr/bin/gdb") ; } else if ( stat("/usr/bin/lldb",&st) == 0 ) { debugger_command = std::string("/usr/bin/lldb") ; } enable_freeze = false ; except_return = 0 ; exec_command = NoCmd ; async_freeze_command = false ; freeze_command = false ; freeze_on_frame_boundary = false ; restart_called = false ; initialization_complete = false ; /** @li Assign default freeze_frame to be 1 second. */ freeze_frame = 1.0 ; job_call_time_tics = 0 ; mode = Initialization ; num_classes = 0 ; num_sim_objects = 0 ; rt_nap = true ; scheduled_start_index = 1000 ; num_scheduled_job_classes = 0 ; signal_caused_term = false ; sim_start = 0.0 ; /** @li Assign default software frame to be 1 second. */ software_frame = 1.0; frame_count = 0 ; stack_trace = true ; /** @li (if on new-enough Linux) allow any process to ptrace this one. * This allows stack trace / debugger attach when ptrace is * restricted (e.g. on Ubuntu 16). */ #if defined(PR_SET_PTRACER) && defined(PR_SET_PTRACER_ANY) prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY); #endif /** @li Assign default terminate time to MAX_LONG_LONG tics. */ terminate_time = TRICK_MAX_LONG_LONG - 1; time_last_pass_tics = 0 ; /** @li Assign default time_tic value to be 1 us. */ time_tics = 0 ; freeze_time_tics = 0 ; freeze_frame_count = 0 ; old_time_tic_value = 1000000 ; time_tic_value = 1000000 ; // Set the JobData copy of the time_tic_value to the executive value Trick::JobData::set_time_tic_value(time_tic_value) ; // These trap flags are set in init_signal_handlers() trap_sigbus = false ; trap_sigfpe = false ; trap_sigsegv = false ; trap_sigabrt = false ; trap_sigchld = false ; build_date = std::string("unknown") ; current_version = std::string("unknown") ; version_date_tag = std::string("unknown") ; num_all_jobs = 0 ; all_jobs_for_checkpoint = NULL ; software_frame_tics = (long long)(software_frame * time_tic_value) ; next_frame_check_tics = software_frame_tics ; freeze_frame_tics = (long long)(freeze_frame * time_tic_value) ; next_freeze_frame_check_tics = freeze_frame_tics ; freeze_job = NULL ; advance_sim_time_job = NULL ; curr_job = NULL ; /** @li Map non-scheduled job class strings to job queues. */ class_map["default_data"] = num_classes ; class_to_queue[num_classes++] = &default_data_queue ; class_map["input_processor"] = num_classes ; class_to_queue[num_classes++] = &input_processor_queue ; class_map["initialization"] = num_classes ; class_to_queue[num_classes++] = &initialization_queue ; class_map["input_processor_run"] = num_classes ; class_to_queue[num_classes++] = &input_processor_run_queue ; class_map["system_thread_sync"] = num_classes ; class_to_queue[num_classes++] = &thread_sync_queue ; class_map["top_of_frame"] = num_classes ; class_to_queue[num_classes++] = &top_of_frame_queue ; class_map["end_of_frame"] = num_classes ; class_to_queue[num_classes++] = &end_of_frame_queue ; class_map["shutdown"] = num_classes ; class_to_queue[num_classes++] = &shutdown_queue ; class_map["freeze_init"] = num_classes ; class_to_queue[num_classes++] = &freeze_init_queue ; class_map["freeze_scheduled"] = num_classes ; class_to_queue[num_classes++] = &freeze_scheduled_queue ; class_map["freeze_automatic"] = num_classes ; class_to_queue[num_classes++] = &freeze_scheduled_queue ; class_map["freeze"] = num_classes ; class_to_queue[num_classes++] = &freeze_queue ; class_map["unfreeze"] = num_classes ; class_to_queue[num_classes++] = &unfreeze_queue ; class_map["exec_time_tic_changed"] = num_classes ; class_to_queue[num_classes++] = &time_tic_changed_queue ; // Initialize all of default signal handlers init_signal_handlers() ; } Trick::Executive::~Executive() { while ( ! threads.empty() ) { delete threads.back() ; threads.pop_back() ; } } int Trick::Executive::get_all_jobs_vector(std::vector & in_jobs_vector) { in_jobs_vector = all_jobs_vector ; return(0) ; } bool Trick::Executive::get_attach_debugger() { return(attach_debugger) ; } const std::string & Trick::Executive::get_current_version() { return(current_version) ; } const std::string & Trick::Executive::get_debugger_command() { return(debugger_command) ; } SIM_COMMAND Trick::Executive::get_exec_command() { return(exec_command) ; } bool Trick::Executive::get_enable_freeze() { return(enable_freeze) ; } bool Trick::Executive::get_freeze_command() { return(freeze_command) ; } bool Trick::Executive::get_freeze_on_frame_boundary() { return(freeze_on_frame_boundary) ; } double Trick::Executive::get_freeze_frame() { return(freeze_frame) ; } long long Trick::Executive::get_freeze_frame_tics() { return(freeze_frame_tics) ; } SIM_MODE Trick::Executive::get_mode() { return(mode) ; } unsigned int Trick::Executive::get_num_threads() { return(threads.size()) ; } int Trick::Executive::get_old_time_tic_value() { return(old_time_tic_value) ; } bool Trick::Executive::get_rt_nap() { return(rt_nap) ; } int Trick::Executive::get_scheduled_start_index() { return(scheduled_start_index) ; } int Trick::Executive::get_sim_objects(std::vector & in_sim_objects) { in_sim_objects = sim_objects ; return(0) ; } double Trick::Executive::get_software_frame() { return(software_frame) ; } long long Trick::Executive::get_software_frame_tics() { return(software_frame_tics) ; } long long Trick::Executive::get_frame_count() { return(frame_count) ; } long long Trick::Executive::get_freeze_frame_count() { return(freeze_frame_count) ; } Trick::Threads * Trick::Executive::get_thread(unsigned int thread_id) { if ( thread_id < threads.size() ) { return threads[thread_id] ; } return NULL ; } pthread_t Trick::Executive::get_pthread_id(unsigned int thread_id) { if ( thread_id < threads.size() ) { return threads[thread_id]->get_pthread_id() ; } return 0 ; } bool Trick::Executive::get_stack_trace() { return(stack_trace) ; } double Trick::Executive::get_thread_amf_cycle_time(unsigned int thread_id) { if ( thread_id < threads.size() ) { return threads[thread_id]->amf_cycle ; } return -1.0 ; } double Trick::Executive::get_terminate_time() { return(terminate_time / time_tic_value) ; } int Trick::Executive::get_time_tic_value() { return(time_tic_value) ; } long long Trick::Executive::get_freeze_time_tics() { return(freeze_time_tics) ; } bool Trick::Executive::get_trap_sigbus() { return(trap_sigbus) ; } bool Trick::Executive::get_trap_sigfpe() { return(trap_sigfpe) ; } bool Trick::Executive::get_trap_sigsegv() { return(trap_sigsegv) ; } bool Trick::Executive::get_trap_sigabrt() { return(trap_sigabrt) ; } bool Trick::Executive::get_trap_sigchld() { return(trap_sigchld) ; } void Trick::Executive::reset_job_cycle_times() { unsigned int ii ; for ( ii = 0 ; ii < all_jobs_vector.size() ; ii++ ) { Trick::JobData * temp_job = all_jobs_vector[ii] ; temp_job->calc_cycle_tics() ; } return ; } void Trick::Executive::reset_job_call_times() { unsigned int ii ; for ( ii = 0 ; ii < all_jobs_vector.size() ; ii++ ) { Trick::JobData * temp_job = all_jobs_vector[ii] ; temp_job->start_tics = (long long)round((double)temp_job->start_tics / old_time_tic_value * time_tic_value) + time_tics ; if ( temp_job->disabled == false and (!temp_job->system_job_class or !temp_job->job_class_name.compare("system_advance_sim_time")) ) { if ( ! temp_job->job_class_name.compare("integ_loop")) { temp_job->next_tics = temp_job->cycle_tics + temp_job->start_tics ; } else { temp_job->next_tics = temp_job->start_tics ; } } } return ; } int Trick::Executive::set_attach_debugger(bool on_off) { attach_debugger = on_off ; return(0) ; } int Trick::Executive::set_debugger_command(std::string command) { debugger_command = command ; return(0) ; } int Trick::Executive::set_exec_command(SIM_COMMAND in_command) { exec_command = in_command ; return(0) ; } int Trick::Executive::set_enable_freeze(bool on_off) { enable_freeze = on_off ; return(0) ; } int Trick::Executive::set_freeze_command(bool on_off) { freeze_command = on_off ; return(0) ; } int Trick::Executive::set_freeze_on_frame_boundary(bool on_off) { freeze_on_frame_boundary = on_off ; return(0) ; } int Trick::Executive::set_freeze_frame(double in_frame) { freeze_frame = in_frame ; freeze_frame_tics = (long long)(freeze_frame * time_tic_value) ; return(0) ; } int Trick::Executive::set_rt_nap(bool on_off) { rt_nap = on_off ; return(0) ; } int Trick::Executive::set_software_frame(double in_frame) { software_frame = in_frame ; software_frame_tics = (long long)(software_frame * time_tic_value) ; next_frame_check_tics = (long long)((sim_start * time_tic_value) + software_frame_tics) ; return(0) ; } int Trick::Executive::set_stack_trace(bool on_off) { stack_trace = on_off ; return(0) ; } int Trick::Executive::set_terminate_time(double in_time) { terminate_time = (long long)(in_time * time_tic_value) ; return(0) ; } int Trick::Executive::set_time(double in_time) { time_tics = (long long)(in_time * time_tic_value) ; for (unsigned int ii = 0 ; ii < threads.size() ; ii++ ) { threads[ii]->curr_time_tics = time_tics ; } reset_job_call_times() ; return(0) ; } int Trick::Executive::set_time_tics(long long in_tics) { time_tics = in_tics ; reset_job_call_times() ; return(0) ; } int Trick::Executive::set_version_date_tag(std::string tag) { this->version_date_tag = tag ; return(0) ; } int Trick::Executive::set_build_date(std::string date) { this->build_date = date ; return(0) ; } int Trick::Executive::set_current_version(std::string version) { this->current_version = version ; return(0) ; } int Trick::Executive::get_except_return() const { return except_return; }