/** @details -# If real-time synchronization is active -# If the sim time is 0 or higher (do not run in real time for negative sim time) -# Reset the real-time clock to the incoming reference time -# Save the current real-time as the start of the frame reference -# Start the sleep timer -# Else reset active to false and enable_flag to true */ int Trick::RealtimeSync::start_realtime(double in_frame_time , long long ref_time) { if ( active ) { /* Only run in real time when sim time reaches 0.0 */ if (exec_get_time_tics() >= 0) { /* Reset the clock reference time to the desired reference time */ rt_clock->clock_reset(ref_time) ; /* Set top of frame time for 1st frame (used in frame logging). */ last_clock_time = rt_clock->clock_time() ; /* Start the sleep timer hardware */ start_sleep_timer(); /* Start the sleep timer */ sleep_timer->start(in_frame_time / rt_clock->get_rt_clock_ratio()) ; } else { /* Reset active and enable_flag so rt_monitor will try and start real time at the end of next software frame */ active = false; enable_flag = true; } } return(0) ; }
/** @details -# If real-time synchronization has been enabled: -# Set the active flag to true. -# If real-time synchronization has been disabled set the active flag to false. */ int Trick::RealtimeSync::initialize() { if ( enable_flag ) { active = true ; enable_flag = false ; } if ( disable_flag ) { active = false ; disable_flag = false ; } tics_per_sec = exec_get_time_tic_value(); /* Start the sleep timer hardware if realtime is active */ start_sleep_timer(); if ( align_sim_to_wall_clock ) { rt_clock->sync_to_wall_clock( align_tic_mult , tics_per_sec ) ; message_publish(MSG_INFO, "Syncing sim to %f second wall clock interval\n", align_tic_mult ) ; if ( exec_get_mode() == Freeze ) { rt_clock->clock_spin(exec_get_freeze_time_tics()) ; } else { rt_clock->clock_spin(exec_get_time_tics()) ; } } return(0) ; }
//Command to manually fire the event once NOW (enter manual mode, bypasses normal condition processing). void Trick::IPPythonEvent::manual_fire() { manual = true ; manual_fired = true ; hold = false ; fired = false ; process_user_event(exec_get_time_tics()) ; }
/** @details -# If real-time synchronization is active -# Set the sleep timer frame period to freeze frame period -# Start real-time setting the real-time clock at 0. */ int Trick::RealtimeSync::freeze_init(double freeze_frame_sec) { if ( active ) { sleep_timer->start( freeze_frame_sec / rt_clock->get_rt_clock_ratio()) ; } freeze_frame = (long long)(freeze_frame_sec * tics_per_sec) ; freeze_time_tics = exec_get_time_tics() ; return 0 ; }
/** @details -# If real-time synchronization is active -# Call the real-time clock initialization routine [@ref clock_init] -# Call the sleep timer initialization -# Set the sleep timer frame period to software frame period -# Calculate the maximum overrun time in simulation tics. */ int Trick::RealtimeSync::start_sleep_timer() { if ( active && (exec_get_time_tics() >= 0.0)) { /* Call sleep timer init to start sleep timer hardware */ sleep_timer->init() ; if ( rt_max_overrun_time > 1e36 ) { rt_max_overrun_time_tics = TRICK_MAX_LONG_LONG ; } else { rt_max_overrun_time_tics = (long long)(rt_max_overrun_time * tics_per_sec) ; } } return(0) ; }
int Trick::SlaveInfo::write_master_status() { /** @par Detailed Design: */ /** @li If the slave is an active synchronization partner (activated == true) */ /** @li and we are not currently waiting for slave to reconnect, */ if (( activated == true ) && (reconnect_count == 0)) { /** @li write the current time according to the master to the slave */ connection->write_time(exec_get_time_tics()) ; /** @li write the current exec_command according to the master to the slave */ connection->write_command((MS_SIM_COMMAND)exec_get_exec_command()) ; } if ((MS_SIM_COMMAND)exec_get_exec_command() == MS_ChkpntLoadBinCmd) { // dmtcp slave will exit, so stop writing status to slave until it reconnects // reconnect_count prevents us from writing status to slave, & is incremented every freeze cycle until we have reconnected reconnect_count = 1; } return(0) ; }
int Trick::VariableServerThread::var_set_copy_mode(int mode) { if ( mode >= VS_COPY_ASYNC and mode <= VS_COPY_TOP_OF_FRAME ) { copy_mode = (VS_COPY_MODE)mode ; if ( copy_mode == VS_COPY_SCHEDULED ) { long long sim_time_tics ; sim_time_tics = exec_get_time_tics() ; // round the next call time to a multiple of the cycle sim_time_tics -= sim_time_tics % cycle_tics ; next_tics = sim_time_tics + cycle_tics ; sim_time_tics = exec_get_freeze_time_tics() ; // round the next call time to a multiple of the cycle sim_time_tics -= sim_time_tics % cycle_tics ; freeze_next_tics = sim_time_tics + cycle_tics ; } else { next_tics = TRICK_MAX_LONG_LONG ; } return 0 ; } return -1 ; }
int Trick::VariableServerThread::copy_sim_data() { unsigned int ii ; VariableReference * curr_var ; if ( vars.size() == 0 ) { return 0 ; } if ( pthread_mutex_trylock(©_mutex) == 0 ) { // Get the simulation time we start this copy time = (double)exec_get_time_tics() / exec_get_time_tic_value() ; for ( ii = 0 ; ii < vars.size() ; ii++ ) { curr_var = vars[ii] ; // if this variable is unresolved, try to resolve it if ( retry_bad_ref ) { if (curr_var->ref->address == &bad_ref_int) { REF2 *new_ref = ref_attributes(const_cast<char*>(curr_var->ref->reference)); if (new_ref != NULL) { curr_var->ref = new_ref; } } } // if there's a pointer somewhere in the address path, follow it in case pointer changed if ( curr_var->ref->pointer_present == 1 ) { curr_var->address = follow_address_path(curr_var->ref) ; if ( curr_var->address == NULL ) { std::string save_name(curr_var->ref->reference) ; if ( curr_var->ref->attr) { free(curr_var->ref->attr) ; } free(curr_var->ref) ; curr_var->ref = make_error_ref(save_name) ; curr_var->address = curr_var->ref->address ; } else { curr_var->ref->address = curr_var->address ; } } // if this variable is a string we need to get the raw character string out of it. if (( curr_var->string_type == TRICK_STRING ) && !curr_var->need_deref) { std::string * str_ptr = (std::string *)curr_var->ref->address ; curr_var->address = (void *)(str_ptr->c_str()) ; } // if this variable itself is a pointer, dereference it if ( curr_var->need_deref) { curr_var->address = *(void**)curr_var->ref->address ; } // handle c++ string and char* if ( curr_var->string_type == TRICK_STRING ) { if (curr_var->address == NULL) { curr_var->size = 0 ; } else { curr_var->size = strlen((char*)curr_var->address) + 1 ; } } // handle c++ wstring and wchar_t* if ( curr_var->string_type == TRICK_WSTRING ) { if (curr_var->address == NULL) { curr_var->size = 0 ; } else { curr_var->size = wcslen((wchar_t *)curr_var->address) * sizeof(wchar_t); } } memcpy( curr_var->buffer_in , curr_var->address , curr_var->size ) ; } retry_bad_ref = false ; // Indicate that sim data has been written and is now ready in the buffer_in's of the vars variable list. var_data_staged = true; packets_copied++ ; pthread_mutex_unlock(©_mutex) ; } return (0) ; }
TEST_F(ExecutiveTest , IntegerTime) { //req.add_requirement("2618149062"); //"The Executive Scheduler shall track simulation elapsed time by an integer count of tics/second") ; EXPECT_EQ(exec_get_time_tics(), 0) ; }