diff --git a/docs/documentation/building_a_simulation/Simulation-Definition-File.md b/docs/documentation/building_a_simulation/Simulation-Definition-File.md
index cdbed4b8d..b8b9fb839 100644
--- a/docs/documentation/building_a_simulation/Simulation-Definition-File.md
+++ b/docs/documentation/building_a_simulation/Simulation-Definition-File.md
@@ -254,7 +254,7 @@ requires a job class.
SELF-SCHEDULING jobs in the scheduled job loop that must schedule themselves when to run
CYCLIC jobs in the scheduled job loop that run cyclically according to their specified cycle time
FREEZE jobs that are run during the freeze execution mode
-CHECKPOINT jobs that are run when a checkpoint is dumpded or loaded
+CHECKPOINT jobs that are run when a checkpoint is dumped or loaded
Table SD_1 Trick-Provided Job Classes
diff --git a/docs/documentation/running_a_simulation/Input-File.md b/docs/documentation/running_a_simulation/Input-File.md
index 1153cbe25..9888b85c3 100644
--- a/docs/documentation/running_a_simulation/Input-File.md
+++ b/docs/documentation/running_a_simulation/Input-File.md
@@ -450,19 +450,31 @@ trick.freeze(trick.exec_get_sim_time() + 5.0)
## Checkpoint the Simulation
-To checkpoint a simulation call `trick.checkpoint([])`. `trick.checkpoint()` called with no
-arguments will checkpoint immediately. An optional checkpoint time may be provided to checkpoint some time
-in the future.
+`trick.checkpoint()` called with no arguments will checkpoint immediately. To checkpoint a simulation call `trick.checkpoint()`.
+An optional checkpoint time may be provided to checkpoint some time in the future. When you supply a name, you can save the checkpoint to a specific file. For example, `trick.checkpoint()` creates a checkpoint in a file with the given name immediately. `trick.checkpoint(, )` saves a checkpoint in
+the described file at the given time.
```python
# Checkpoints immediately
trick.checkpoint()
+# Checkpoints immediately, saving to 'checkpoint_save'
+trick.checkpoint("checkpoint_save")
+
# Checkpoints at an absolute time
trick.checkpoint(100.0)
+# Checkpoints at an absolute time, saving to 'late_checkpoint'
+trick.checkpoint(100.0, "late_checkpoint")
+
# Checkpoints 5 seconds relative from the current sim_time
trick.checkpoint(trick.exec_get_sim_time() + 5.0)
+
+# Checkpoints to 'checkpoint.txt' immediately
+trick.checkpoint("checkpoint.txt")
+
+# Checkpoints to 'checkpoint2.txt' at an absolute time
+trick.checkpoint(50.0, "checkpoint.txt")
```
## Stopping the Simulation
diff --git a/docs/documentation/simulation_capabilities/Checkpoints.md b/docs/documentation/simulation_capabilities/Checkpoints.md
index 0f9aedb3f..eaa2e9fcd 100644
--- a/docs/documentation/simulation_capabilities/Checkpoints.md
+++ b/docs/documentation/simulation_capabilities/Checkpoints.md
@@ -13,8 +13,12 @@ trick.checkpoint_post_init(True|False)
trick.checkpoint_end(True|False)
# Save a checkpoint at a time in the future
trick.checkpoint()
+# Save a checkpoint at a time in the future to a specified file
+trick.checkpoint(, )
# Save a checkpoint now
trick.checkpoint()
+# Save a checkpoint now to a specified file
+trick.checkpoint()
# Set the CPU to use for checkpoints
trick.checkpoint_cpu()
diff --git a/docs/howto_guides/Checkpointing-Best-Practices.md b/docs/howto_guides/Checkpointing-Best-Practices.md
index 2226d7173..ac676b229 100644
--- a/docs/howto_guides/Checkpointing-Best-Practices.md
+++ b/docs/howto_guides/Checkpointing-Best-Practices.md
@@ -98,7 +98,7 @@ A checkpoint of a simulation is usually initiated from the Input Processor. That
1. The input file, or
2. The variable server.
-```trick.checkpoint( )``` is called from Python. This Python function is bound to the corresponding C++ function. At a simulation frame boundary (so that data is time-homogeneous), three things happen:
+```trick.checkpoint( )``` is called from Python. This Python function is bound to the corresponding C++ function. At a simulation frame boundary (so that data is time-homogeneous), the simulation freezes and then three things happen:
1. The ```"checkpoint"``` jobs in the S_define file are executed. These job-classes allow you to prepare your sim to be checkpointed. Perhaps you want to transform simulation state data into a different form for checkpointing. This is up to you.
@@ -109,7 +109,7 @@ A checkpoint of a simulation is usually initiated from the Input Processor. That
### What Happens When You Load a Checkpoint.
Trick.load_checkpoint() is called from Python.
-At a simulation frame boundary, three things happen:
+At a simulation frame boundary, the simulation freezes and then three things happen:
1. The ```“preload_checkpoint”``` jobs are called. These job-classes allow you to prepare your sim for a checkpoint-restore, in whatever way you see fit.
diff --git a/docs/not_referenced/Input-File-Quick-Reference.md b/docs/not_referenced/Input-File-Quick-Reference.md
index d53685714..5fd71c7a7 100644
--- a/docs/not_referenced/Input-File-Quick-Reference.md
+++ b/docs/not_referenced/Input-File-Quick-Reference.md
@@ -84,8 +84,12 @@ trick.checkpoint_post_init(True|False)
trick.checkpoint_end(True|False)
# Save a checkpoint at a time in the future
trick.checkpoint()
+# Save a checkpoint at a time in the future to a specified file
+trick.checkpoint(, )
# Save a checkpoint now
trick.checkpoint()
+# Save a checkpoint now to a specified file
+trick.checkpoint()
# Set the CPU to use for checkpoints
trick.checkpoint_cpu()
diff --git a/include/trick/CheckPointRestart.hh b/include/trick/CheckPointRestart.hh
index b83d772e3..652585947 100644
--- a/include/trick/CheckPointRestart.hh
+++ b/include/trick/CheckPointRestart.hh
@@ -6,11 +6,12 @@
#ifndef MMWRAPPER_HH
#define MMWRAPPER_HH
+#include "trick/Scheduler.hh"
+
+#include
+#include
#include
#include
-#include
-
-#include "trick/Scheduler.hh"
namespace Trick {
@@ -21,6 +22,15 @@ namespace Trick {
*
*/
class CheckPointRestart : public Trick::Scheduler {
+ private:
+ /** Flag to track if an automatic freeze has been triggered for loading checkpoint */
+ bool chkpnt_load_auto_freeze = false; /* ** */
+
+ /** Map to track custom named checkpoints based on the scheduled times */
+ std::map chkpnt_names; /* ** */
+
+ /** Map to track whether a scheduled checkpoint should resume sim. */
+ std::map chkpnt_write_auto_resume_by_time; /* ** */
protected:
/** queue to hold jobs to be called before a checkpoint is dumped. */
@@ -198,15 +208,23 @@ namespace Trick {
virtual int checkpoint(std::string file_name = "", bool print_status = true , std::string obj_list_str = "") ;
/**
- @brief @userdesc Command to dump a checkpoint at in_time. (Sets checkpoint_time to the integral time tic value corresponding
- to the incoming in_time so that checkpoint occurs once at that time at the end of the execution frame.)
- The checkpointed file name is @e chkpnt_.
+ @brief @userdesc Command to dump a checkpoint at in_time. (Sets checkpoint_time to the integral time tic
+ value corresponding to the incoming in_time so that checkpoint occurs once at that time at the end of the
+ execution frame.) The checkpointed file name is @e chkpnt_ or @e .
@par Python Usage:
@code trick.checkpoint() @endcode
@param in_time - desired checkpoint time in seconds.
+ @param file_name - checkpoint file name. Defaults to blank in which case the checkpoint follows the
+ expecteed convention.
@return always 0
*/
- virtual int checkpoint(double in_time) ;
+ virtual int checkpoint(double in_time, std::string file_name = "");
+
+ /**
+ * Record that a non-checkpoint freeze was scheduled at a given time.
+ * @param in_time_tics - simulation time in tics
+ */
+ void note_scheduled_freeze(long long in_time_tics);
/**
* Executes the pre_init_checkpoint
diff --git a/include/trick/Executive.hh b/include/trick/Executive.hh
index 2be2d27ee..3af73d946 100644
--- a/include/trick/Executive.hh
+++ b/include/trick/Executive.hh
@@ -1238,6 +1238,14 @@ namespace Trick {
*/
virtual int freeze(double in_time) ;
+ /**
+ @brief Internal command to freeze the simulation at a future time.
+ @param in_time - time in simulation seconds to freeze
+ @param user_requested - whether the freeze was requested outside checkpoint scheduling
+ @return always 0
+ */
+ virtual int freeze(double in_time, bool user_requested);
+
/**
@userdesc Command to terminate the simulation now. Set exec_command to ExitCmd.
@par Python Usage:
diff --git a/include/trick/sim_mode.h b/include/trick/sim_mode.h
index 1bdbd2ace..d94c2b012 100644
--- a/include/trick/sim_mode.h
+++ b/include/trick/sim_mode.h
@@ -14,28 +14,41 @@
#ifndef SIMMODE_HH
#define SIMMODE_HH
-typedef enum {
+#ifdef __cplusplus
+extern "C"
+{
+#endif
- NoCmd = 0 , /* NoCmd */
- FreezeCmd = 2 , /* freeze */
- RunCmd = 3 , /* run */
- ExitCmd = 10 , /* exit */
+ typedef enum
+ {
-} SIM_COMMAND;
+ NoCmd = 0, /* NoCmd */
+ FreezeCmd = 2, /* freeze */
+ RunCmd = 3, /* run */
+ ExitCmd = 10, /* exit */
-/**
- * @enum SIM_MODE
- * The SIM_MODE enumeration represents the TRICK simulation modes.
- */
+ } SIM_COMMAND;
+
+ /**
+ * @enum SIM_MODE
+ * The SIM_MODE enumeration represents the TRICK simulation modes.
+ */
-typedef enum {
+ typedef enum
+ {
- Initialization = 0 , /* Initialization */
- Freeze = 1 , /* freeze */
- Step = 4 , /* Debug Stepping */
- Run = 5 , /* run */
- ExitMode = 6 /* exit */
+ Initialization = 0, /* Initialization */
+ Freeze = 1, /* freeze */
+ Step = 4, /* Debug Stepping */
+ Run = 5, /* run */
+ ExitMode = 6 /* exit */
-} SIM_MODE ;
+ } SIM_MODE;
+
+ const char* simModeCharString(SIM_MODE mode);
+
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/test/SIM_checkpoint_data_recording/RUN_test1/ref_log_foo.csv b/test/SIM_checkpoint_data_recording/RUN_test1/ref_log_foo.csv
index 37c97556b..75a5c16e7 100644
--- a/test/SIM_checkpoint_data_recording/RUN_test1/ref_log_foo.csv
+++ b/test/SIM_checkpoint_data_recording/RUN_test1/ref_log_foo.csv
@@ -1,4 +1,5 @@
sys.exec.out.time {s},testSimObject.my_foo.a {1},testSimObject.my_foo.b {1}
+ 5,6,12
5.1,6,12
5.2,6,12
5.3,6,12
diff --git a/test/SIM_checkpoint_data_recording/RUN_test11_redirect/ref_log_foo.csv b/test/SIM_checkpoint_data_recording/RUN_test11_redirect/ref_log_foo.csv
index 07b570d36..cd8d2073d 100644
--- a/test/SIM_checkpoint_data_recording/RUN_test11_redirect/ref_log_foo.csv
+++ b/test/SIM_checkpoint_data_recording/RUN_test11_redirect/ref_log_foo.csv
@@ -1,4 +1,5 @@
sys.exec.out.time {s},testSimObject.my_foo.a {1},testSimObject.my_foo.b {1}
+ 5.5,6,12
5.6,6,12
5.7,6,12
5.8,6,12
diff --git a/test/SIM_checkpoint_data_recording/RUN_test3/ref_log_foo.csv b/test/SIM_checkpoint_data_recording/RUN_test3/ref_log_foo.csv
index 37c97556b..75a5c16e7 100644
--- a/test/SIM_checkpoint_data_recording/RUN_test3/ref_log_foo.csv
+++ b/test/SIM_checkpoint_data_recording/RUN_test3/ref_log_foo.csv
@@ -1,4 +1,5 @@
sys.exec.out.time {s},testSimObject.my_foo.a {1},testSimObject.my_foo.b {1}
+ 5,6,12
5.1,6,12
5.2,6,12
5.3,6,12
diff --git a/test/SIM_checkpoint_data_recording/RUN_test4/ref_log_foo.csv b/test/SIM_checkpoint_data_recording/RUN_test4/ref_log_foo.csv
index 13327df84..b70298737 100644
--- a/test/SIM_checkpoint_data_recording/RUN_test4/ref_log_foo.csv
+++ b/test/SIM_checkpoint_data_recording/RUN_test4/ref_log_foo.csv
@@ -1,4 +1,5 @@
sys.exec.out.time {s},testSimObject.my_foo.a {1},testSimObject.my_foo.b {1}
+ 2,3,6
2.1,3,6
2.2,3,6
2.3,3,6
diff --git a/test/SIM_checkpoint_data_recording/RUN_test5/ref_log_foo.csv b/test/SIM_checkpoint_data_recording/RUN_test5/ref_log_foo.csv
index 306de1b40..490689651 100644
--- a/test/SIM_checkpoint_data_recording/RUN_test5/ref_log_foo.csv
+++ b/test/SIM_checkpoint_data_recording/RUN_test5/ref_log_foo.csv
@@ -1,4 +1,5 @@
sys.exec.out.time {s},testSimObject.my_foo.a {1},testSimObject.my_foo.b {1}
+ 7,8,16
7.1,8,16
7.2,8,16
7.3,8,16
diff --git a/test/SIM_checkpoint_data_recording/RUN_test6/ref_log_foo2.csv b/test/SIM_checkpoint_data_recording/RUN_test6/ref_log_foo2.csv
index f7b15a2b7..2ee326def 100644
--- a/test/SIM_checkpoint_data_recording/RUN_test6/ref_log_foo2.csv
+++ b/test/SIM_checkpoint_data_recording/RUN_test6/ref_log_foo2.csv
@@ -1,4 +1,5 @@
sys.exec.out.time {s},testSimObject.my_foo.b {1}
+ 7,16
8,18
9,20
10,22
diff --git a/test/SIM_checkpoint_data_recording/RUN_test7/ref_log_fooChange.csv b/test/SIM_checkpoint_data_recording/RUN_test7/ref_log_fooChange.csv
index 4d0c5bd16..6abcd599d 100644
--- a/test/SIM_checkpoint_data_recording/RUN_test7/ref_log_fooChange.csv
+++ b/test/SIM_checkpoint_data_recording/RUN_test7/ref_log_fooChange.csv
@@ -1,5 +1,5 @@
sys.exec.out.time {s},testSimObject.my_foo.a {1},testSimObject.my_foo.b {1},testSimObject.my_foo.q {1}
- 5.1,6,12,2
+ 5,6,12,2
8,9,18,3
11,12,24,4
14,15,30,5
diff --git a/test/SIM_checkpoint_data_recording/RUN_test8/dump.py b/test/SIM_checkpoint_data_recording/RUN_test8/dump.py
index a63985c11..5e8841eb1 100644
--- a/test/SIM_checkpoint_data_recording/RUN_test8/dump.py
+++ b/test/SIM_checkpoint_data_recording/RUN_test8/dump.py
@@ -6,6 +6,9 @@
def main():
exec(open("Modified_data/fooChange2.dr").read())
+ # Testing that separately scheduling a freeze and checkpoint at the same time still results in a checkpoint
+ # Commented freeze out because the test would stop at scheduled freeze time
+ #trick.freeze(5.0)
trick.checkpoint(5.0)
trick.stop(20.0)
diff --git a/test/SIM_checkpoint_data_recording/RUN_test8/ref_log_fooChange2.csv b/test/SIM_checkpoint_data_recording/RUN_test8/ref_log_fooChange2.csv
index 737209218..96eba9af7 100644
--- a/test/SIM_checkpoint_data_recording/RUN_test8/ref_log_fooChange2.csv
+++ b/test/SIM_checkpoint_data_recording/RUN_test8/ref_log_fooChange2.csv
@@ -1,5 +1,5 @@
sys.exec.out.time {s},testSimObject.my_foo.q {1}
- 5.1,2
+ 5,2
8,3
11,4
14,5
diff --git a/test/SIM_stls/RUN_test/setup.py b/test/SIM_stls/RUN_test/setup.py
index 208d871f9..498f3e311 100644
--- a/test/SIM_stls/RUN_test/setup.py
+++ b/test/SIM_stls/RUN_test/setup.py
@@ -5,7 +5,7 @@ def main():
trick.exec_set_job_onoff("the_object.stlc.test", 1, False)
trick.exec_set_job_onoff("the_object.stlc.print", 1, False)
- trick.add_read( 0.5, 'trick.checkpoint("chkpnt_in")')
+ trick.checkpoint(0.5, "chkpnt_in")
trick.exec_set_freeze_frame(0.10)
trick.stop(1.0)
diff --git a/trick_source/sim_services/CheckPointRestart/CheckPointRestart.cpp b/trick_source/sim_services/CheckPointRestart/CheckPointRestart.cpp
index 0259abea0..6ef71926c 100644
--- a/trick_source/sim_services/CheckPointRestart/CheckPointRestart.cpp
+++ b/trick_source/sim_services/CheckPointRestart/CheckPointRestart.cpp
@@ -1,24 +1,25 @@
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
#include "trick/CheckPointRestart.hh"
+
+#include "trick/Executive.hh"
#include "trick/MemoryManager.hh"
#include "trick/SimObject.hh"
-#include "trick/Executive.hh"
-#include "trick/exec_proto.hh"
-#include "trick/exec_proto.h"
+#include "trick/TrickConstant.hh"
#include "trick/command_line_protos.h"
+#include "trick/exec_proto.h"
+#include "trick/exec_proto.hh"
#include "trick/message_proto.h"
#include "trick/message_type.h"
-#include "trick/TrickConstant.hh"
+#include "trick/sim_mode.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
Trick::CheckPointRestart * the_cpr ;
@@ -112,8 +113,13 @@ int Trick::CheckPointRestart::find_write_checkpoint_jobs(std::string sim_object_
return(0) ;
}
-int Trick::CheckPointRestart::checkpoint(double in_time) {
-
+/**
+ * @brief Schedule a checkpoint to be written at a given time.
+ * @param in_time The time the checkpoint should be dumped
+ * @see write_checkpoint()
+ */
+int Trick::CheckPointRestart::checkpoint(double in_time, std::string file_name)
+{
long long curr_time = exec_get_time_tics() ;
long long new_time ;
@@ -124,6 +130,16 @@ int Trick::CheckPointRestart::checkpoint(double in_time) {
if ( new_time < write_checkpoint_job->next_tics ) {
write_checkpoint_job->next_tics = new_time ;
}
+
+ if (chkpnt_write_auto_resume_by_time.find(new_time) == chkpnt_write_auto_resume_by_time.end())
+ {
+ chkpnt_write_auto_resume_by_time[new_time] = true;
+ }
+
+ if (!file_name.empty())
+ chkpnt_names[new_time] = file_name;
+
+ the_exec->freeze(in_time, false);
//std::cout << "\033[33mSET CHECKPOINT TIME " << in_time << " " << new_time << "\033[0m" << std::endl ;
} else {
message_publish(MSG_ERROR, "Checkpoint time specified in the past. specified %f, current_time %f\n",
@@ -133,6 +149,14 @@ int Trick::CheckPointRestart::checkpoint(double in_time) {
return(0) ;
}
+void Trick::CheckPointRestart::note_scheduled_freeze(long long in_time_tics)
+{
+ // If a freeze is scheduled at the same time as a checkpoint, the checkpoint will be taken and sim will not resume
+ // afterwards. Otherwise, sim will resume after the checkpoint as the scheduled checkpoint auto freezes sim before
+ // taking the checkpoint.
+ chkpnt_write_auto_resume_by_time[in_time_tics] = false;
+}
+
int Trick::CheckPointRestart::set_safestore_time(double in_time) {
long long software_frame_tics ;
@@ -174,6 +198,19 @@ int Trick::CheckPointRestart::do_checkpoint(std::string file_name, bool print_st
JobData * curr_job ;
pid_t pid;
+ SIM_MODE mode;
+
+ mode = the_exec->get_mode();
+
+ if (mode != Freeze)
+ {
+ std::string msg_format
+ = "WARNING: Saving a checkpoint not in 'Freeze' mode may cause non time-homogeneous data. ";
+ msg_format += "Current Mode: %s (%d)\n";
+ message_publish(MSG_WARNING, msg_format.c_str(), simModeCharString(mode), mode);
+
+ return 0;
+ }
if ( ! file_name.compare("") ) {
std::stringstream file_name_stream ;
@@ -238,9 +275,14 @@ int Trick::CheckPointRestart::do_checkpoint(std::string file_name, bool print_st
return 0 ;
}
+/**
+ * @brief Writes a scheduled checkpoint if it is the correct time.
+ * @see checkpoint(double in_time)
+ */
int Trick::CheckPointRestart::write_checkpoint() {
long long curr_time = exec_get_time_tics() ;
+ bool should_resume_sim = true;
// checkpoint time is set in a read event that occurs at top of frame
if ( curr_time == checkpoint_times.top() ) {
@@ -256,13 +298,33 @@ int Trick::CheckPointRestart::write_checkpoint() {
write_checkpoint_job->next_tics = TRICK_MAX_LONG_LONG ;
}
+ if (chkpnt_write_auto_resume_by_time.find(curr_time) != chkpnt_write_auto_resume_by_time.end())
+ {
+ should_resume_sim = chkpnt_write_auto_resume_by_time[curr_time];
+ chkpnt_write_auto_resume_by_time.erase(curr_time);
+ }
+
double sim_time = exec_get_sim_time() ;
- std::stringstream chk_name_stream ;
+ std::string file_name = "";
- chk_name_stream << "chkpnt_" << std::fixed << std::setprecision(6) << sim_time ;
+ if (chkpnt_names.find(curr_time) == chkpnt_names.end())
+ {
+ std::stringstream chk_name_stream;
+ chk_name_stream << "chkpnt_" << std::fixed << std::setprecision(6) << sim_time;
+ file_name = chk_name_stream.str();
+ }
+ else
+ {
+ file_name = chkpnt_names[curr_time];
+ chkpnt_names.erase(curr_time);
+ }
- checkpoint( chk_name_stream.str() );
+ checkpoint(file_name);
+ if (should_resume_sim)
+ {
+ the_exec->run();
+ }
}
return(0) ;
@@ -304,6 +366,21 @@ int Trick::CheckPointRestart::safestore_checkpoint() {
}
void Trick::CheckPointRestart::load_checkpoint(std::string file_name) {
+ SIM_MODE mode = the_exec->get_mode();
+
+ if (mode == Run)
+ {
+ std::string msg_format = "WARNING: Loading a checkpoint in 'Run Mode' may cause non time-homogeneous data. ";
+ msg_format += "Current Mode: %s (%d)\n";
+
+ message_publish(MSG_WARNING, msg_format.c_str(), file_name.c_str(), simModeCharString(mode), mode);
+ // If in RUN mode, this will freeze the simulation and notify the code to unfreeze later.
+ // To forbid loading a checkpoint in RUN mode, remove the following two lines and the second to last line in
+ // load_checkpoint_job()
+ the_exec->freeze();
+ chkpnt_load_auto_freeze = true;
+ }
+
load_checkpoint_file_name = file_name ;
}
@@ -335,8 +412,8 @@ int Trick::CheckPointRestart::load_checkpoint_job() {
JobData * curr_job ;
struct stat temp_buf ;
- if ( ! load_checkpoint_file_name.empty() ) {
-
+ if (!load_checkpoint_file_name.empty() && the_exec->get_mode() != Run)
+ {
if ( stat( load_checkpoint_file_name.c_str() , &temp_buf) == 0 ) {
preload_checkpoint_queue.reset_curr_index() ;
while ( (curr_job = preload_checkpoint_queue.get_next_job()) != NULL ) {
@@ -373,6 +450,8 @@ int Trick::CheckPointRestart::load_checkpoint_job() {
message_publish(MSG_INFO, "Could not find checkpoint file %s.\n", load_checkpoint_file_name.c_str()) ;
}
load_checkpoint_file_name.clear() ;
+ if (chkpnt_load_auto_freeze)
+ the_exec->run();
}
return(0) ;
diff --git a/trick_source/sim_services/Executive/Executive_freeze.cpp b/trick_source/sim_services/Executive/Executive_freeze.cpp
index 736b543f9..8c2472df4 100644
--- a/trick_source/sim_services/Executive/Executive_freeze.cpp
+++ b/trick_source/sim_services/Executive/Executive_freeze.cpp
@@ -1,13 +1,16 @@
+#include "trick/Executive.hh"
-#include
-#include
-
+#include "trick/CheckPointRestart.hh"
#include "trick/TrickConstant.hh"
-#include "trick/Executive.hh"
#include "trick/exec_proto.h"
#include "trick/message_proto.h"
#include "trick/message_type.h"
+#include
+#include
+
+extern Trick::CheckPointRestart* the_cpr;
+
int Trick::Executive::get_freeze_job(std::string sim_object_name) {
freeze_job = get_job(sim_object_name + ".sched_freeze_to_exec_command") ;
if ( freeze_job == NULL ) {
@@ -31,12 +34,18 @@ int Trick::Executive::freeze() {
}
-int Trick::Executive::freeze(double in_time) {
+int Trick::Executive::freeze(double in_time) { return freeze(in_time, true); }
+int Trick::Executive::freeze(double in_time, bool user_requested)
+{
long long new_time ;
new_time = (long long)(in_time * time_tic_value) ;
if (new_time > time_tics ) {
+ if (user_requested && the_cpr != NULL)
+ {
+ the_cpr->note_scheduled_freeze(new_time);
+ }
freeze_times.push(new_time) ;
if ( new_time < freeze_job->next_tics ) {
freeze_job->next_tics = new_time ;
@@ -47,8 +56,7 @@ int Trick::Executive::freeze(double in_time) {
in_time , get_sim_time()) ;
}
- return(0) ;
-
+ return (0);
}
/**
@@ -83,7 +91,5 @@ int Trick::Executive::sched_freeze_to_exec_command(bool end_of_frame) {
}
}
- return(0) ;
-
+ return (0);
}
-
diff --git a/trick_source/sim_services/Executive/Executive_freeze_loop.cpp b/trick_source/sim_services/Executive/Executive_freeze_loop.cpp
index 19d5ef4bd..76d3edd12 100644
--- a/trick_source/sim_services/Executive/Executive_freeze_loop.cpp
+++ b/trick_source/sim_services/Executive/Executive_freeze_loop.cpp
@@ -1,13 +1,16 @@
-
-#include
-#include
-
#include "trick/Executive.hh"
+
+#include "trick/CheckPointRestart.hh"
#include "trick/ExecutiveException.hh"
#include "trick/exec_proto.h"
#include "trick/message_proto.h"
#include "trick/message_type.h"
+#include
+#include
+
+extern Trick::CheckPointRestart* the_cpr;
+
/**
@details
-# Set the mode to Freeze. Requirement [@ref r_exec_mode_2]
@@ -33,6 +36,11 @@ int Trick::Executive::freeze_loop() {
message_publish(MSG_INFO, "Freeze ON. Simulation time holding at %f seconds.\n" , get_sim_time()) ;
+ if (!the_cpr->checkpoint_times.empty())
+ {
+ the_cpr->write_checkpoint();
+ }
+
while (mode == Freeze) {
/* Run the Freeze Scheduled Jobs. */
diff --git a/trick_source/sim_services/VariableServer/Makefile_deps b/trick_source/sim_services/VariableServer/Makefile_deps
index 8d83bab4e..d585865ae 100644
--- a/trick_source/sim_services/VariableServer/Makefile_deps
+++ b/trick_source/sim_services/VariableServer/Makefile_deps
@@ -1,3 +1,6 @@
+
+object_${TRICK_HOST_CPU}/simModeCharString.o: simModeCharString.c \
+ ${TRICK_HOME}/include/trick/sim_mode.h
object_${TRICK_HOST_CPU}/VariableServerSessionThread_loop.o: VariableServerSessionThread_loop.cpp \
${TRICK_HOME}/include/trick/VariableServer.hh \
${TRICK_HOME}/include/trick/tc.h \
diff --git a/trick_source/sim_services/VariableServer/simModeCharString.c b/trick_source/sim_services/VariableServer/simModeCharString.c
new file mode 100644
index 000000000..44469509e
--- /dev/null
+++ b/trick_source/sim_services/VariableServer/simModeCharString.c
@@ -0,0 +1,20 @@
+#include "trick/sim_mode.h"
+
+const char* simModeCharString(SIM_MODE mode)
+{
+ switch (mode)
+ {
+ case Initialization:
+ return "Initialization";
+ case Run:
+ return "Run";
+ case Step:
+ return "Step";
+ case Freeze:
+ return "Freeze";
+ case ExitMode:
+ return "ExitMode";
+ default:
+ return "InvalidMode";
+ }
+}