From 7e94be8bccbba568594cc84349e39992f2188cfd Mon Sep 17 00:00:00 2001 From: Hong Chen Date: Tue, 20 Feb 2024 10:37:34 -0600 Subject: [PATCH] Add rt nap stats for sim shutdown that includes total number of rt naps that are greater than 10% software frame, the longest rt nap, and the shortest rt nap. --- include/trick/Executive.hh | 19 +++++++++++++++++++ trick_source/sim_services/Clock/Clock.cpp | 5 +++++ .../sim_services/Executive/Executive.cpp | 16 ++++++++++++++++ .../Executive/Executive_loop_multi_thread.cpp | 11 ++++++++++- .../Executive_scheduled_thread_sync.cpp | 6 +++++- .../Executive/Executive_shutdown.cpp | 10 ++++++++++ .../Executive/Executive_thread_sync.cpp | 5 +++++ .../sim_services/Executive/Threads_child.cpp | 6 ++++++ 8 files changed, 76 insertions(+), 2 deletions(-) diff --git a/include/trick/Executive.hh b/include/trick/Executive.hh index a545253e7..5e58a4ef2 100644 --- a/include/trick/Executive.hh +++ b/include/trick/Executive.hh @@ -276,6 +276,15 @@ namespace Trick { /** S_run_summary - Trick version.\n */ std::string current_version; /**< trick_units(--) */ + /** rt_nap statistics - total number of rt_nap that is longer than 10% of the software frame.\n */ + int rt_nap_count; /**< trick_units(--) */ + + /** rt_nap statistics - the longest rt_nap.\n */ + double longest_rt_nap; /**< trick_units(s) */ + + /** rt_nap statistics - the shortest rt_nap.\n */ + double shortest_rt_nap; /**< trick_units(s) */ + /** @userdesc Command to reset job cycle times after the time_tic_value has changed. @return void @@ -875,6 +884,16 @@ namespace Trick { */ int set_current_version(std::string version) ; + /** + @userdesc Set stats after each RELEASE() when rt_nap is true. The stats contains the counts of + RELEASE() if the time delta between before and after RELEASE() is greater than 10% of the + software frame time, the longest delta, and the shortest delta of before and after RELEASE(). + @param clock_time_before_rt_nap - clock time before RELEASE() is called when rt_nap is true. + @param clock_time_after_rt_nap - clock time after RELEASE() is done when rt_nap is true. + @reutnr void + */ + void set_rt_nap_stats(long long clock_time_before_rt_nap, long long clock_time_after_rt_nap) ; + // END GET and SET FUNCTIONS /** diff --git a/trick_source/sim_services/Clock/Clock.cpp b/trick_source/sim_services/Clock/Clock.cpp index 420ded5ad..0b762415e 100644 --- a/trick_source/sim_services/Clock/Clock.cpp +++ b/trick_source/sim_services/Clock/Clock.cpp @@ -10,6 +10,7 @@ #include "trick/Clock.hh" #include "trick/exec_proto.h" +#include "trick/exec_proto.hh" #include "trick/release.h" Trick::Clock * the_clock = NULL ; @@ -84,11 +85,15 @@ long long Trick::Clock::clock_time() { */ long long Trick::Clock::clock_spin(long long req_time) { long long curr_time ; + long long time_before_rt_nap, time_after_rt_nap ; curr_time = clock_time() ; /* Perform spin loop to allow current time to catch up to requested time */ while (curr_time < req_time) { if ( exec_get_rt_nap() == 1 ) { + time_before_rt_nap = wall_clock_time() ; RELEASE(); + time_after_rt_nap = wall_clock_time() ; + exec_get_exec_cpp()->set_rt_nap_stats(time_before_rt_nap, time_after_rt_nap) ; } curr_time = clock_time(); } diff --git a/trick_source/sim_services/Executive/Executive.cpp b/trick_source/sim_services/Executive/Executive.cpp index 5b4759a7e..75e49ed41 100644 --- a/trick_source/sim_services/Executive/Executive.cpp +++ b/trick_source/sim_services/Executive/Executive.cpp @@ -417,3 +417,19 @@ int Trick::Executive::set_current_version(std::string version) { int Trick::Executive::get_except_return() const { return except_return; } + +void Trick::Executive::set_rt_nap_stats(long long clock_time_before_rt_nap, long long clock_time_after_rt_nap) { + double rt_nap_elapsed_time = (double)(clock_time_after_rt_nap - clock_time_before_rt_nap) / time_tic_value ; + if (rt_nap_elapsed_time / software_frame > 0.1) { + rt_nap_count++ ; + } + if (longest_rt_nap < rt_nap_elapsed_time) { + longest_rt_nap = rt_nap_elapsed_time ; + } + + if (shortest_rt_nap == 0.0) { + shortest_rt_nap = rt_nap_elapsed_time ; + } else if (shortest_rt_nap > rt_nap_elapsed_time) { + shortest_rt_nap = rt_nap_elapsed_time ; + } +} \ No newline at end of file diff --git a/trick_source/sim_services/Executive/Executive_loop_multi_thread.cpp b/trick_source/sim_services/Executive/Executive_loop_multi_thread.cpp index 34e348c1d..cd0b3b69c 100644 --- a/trick_source/sim_services/Executive/Executive_loop_multi_thread.cpp +++ b/trick_source/sim_services/Executive/Executive_loop_multi_thread.cpp @@ -6,6 +6,8 @@ #include "trick/Executive.hh" #include "trick/exec_proto.h" #include "trick/release.h" +#include "trick/clock_proto.h" +#include "trick/Executive.hh" /** @details @@ -40,13 +42,17 @@ int Trick::Executive::loop_multi_thread() { unsigned int ii ; Trick::ScheduledJobQueue * main_sched_queue ; int ret = 0 ; + long long time_before_rt_nap, time_after_rt_nap; /* Wait for all threads to finish initializing and set the child_complete flag. */ for (ii = 1; ii < threads.size() ; ii++) { Threads * curr_thread = threads[ii] ; while (curr_thread->child_complete == false ) { if (rt_nap == true) { - RELEASE(); + time_before_rt_nap = clock_wall_time() ; + RELEASE() ; + time_after_rt_nap = clock_wall_time() ; + set_rt_nap_stats(time_before_rt_nap, time_after_rt_nap) ; } } } @@ -146,7 +152,10 @@ int Trick::Executive::loop_multi_thread() { depend_job = curr_job->depends[ii] ; while (! depend_job->complete) { if (rt_nap == true) { + time_before_rt_nap = clock_wall_time() ; RELEASE(); + time_after_rt_nap = clock_wall_time() ; + set_rt_nap_stats(time_before_rt_nap, time_after_rt_nap) ; } } } diff --git a/trick_source/sim_services/Executive/Executive_scheduled_thread_sync.cpp b/trick_source/sim_services/Executive/Executive_scheduled_thread_sync.cpp index 59f631e27..032095562 100644 --- a/trick_source/sim_services/Executive/Executive_scheduled_thread_sync.cpp +++ b/trick_source/sim_services/Executive/Executive_scheduled_thread_sync.cpp @@ -3,6 +3,7 @@ #include "trick/Executive.hh" #include "trick/release.h" +#include "trick/clock_proto.h" /** @design @@ -12,14 +13,17 @@ int Trick::Executive::scheduled_thread_sync() { unsigned int ii ; - + long long time_before_rt_nap, time_after_rt_nap ; /* Wait for synchronous threads to finish before testing for adjusting time_tics */ for (ii = 1; ii < threads.size() ; ii++) { Threads * curr_thread = threads[ii] ; if ( curr_thread->enabled and curr_thread->process_type == PROCESS_TYPE_SCHEDULED) { while (curr_thread->child_complete == false ) { if (rt_nap == true) { + time_before_rt_nap = clock_wall_time() ; RELEASE(); + time_after_rt_nap = clock_wall_time() ; + set_rt_nap_stats(time_before_rt_nap, time_after_rt_nap) ; } } } diff --git a/trick_source/sim_services/Executive/Executive_shutdown.cpp b/trick_source/sim_services/Executive/Executive_shutdown.cpp index 9e431eb46..2c91e875b 100644 --- a/trick_source/sim_services/Executive/Executive_shutdown.cpp +++ b/trick_source/sim_services/Executive/Executive_shutdown.cpp @@ -125,6 +125,16 @@ int Trick::Executive::shutdown() { user_cpu_time, kernal_cpu_time, sim_to_cpu, user_cpu_init, kernal_cpu_init, sim_mem) ; + if (rt_nap == true) { + message_publish(MSG_NORMAL , "\n\n" + " SIMULATION RT NAP STATS\n" + " RT NAP COUNTS: %17d\n" + " (RT NAP / SOFTWARE FRAME > 0.1)\n" + " LONGEST RT NAP: %12.15f\n" + " SHORTEST RT NAP: %12.15f\n", + rt_nap_count, longest_rt_nap, shortest_rt_nap) ; + } + /* Kill all threads. */ for (ii = 1; ii < threads.size() ; ii++) { if ( threads[ii]->running ) { diff --git a/trick_source/sim_services/Executive/Executive_thread_sync.cpp b/trick_source/sim_services/Executive/Executive_thread_sync.cpp index 79022d6c6..a43a546a9 100644 --- a/trick_source/sim_services/Executive/Executive_thread_sync.cpp +++ b/trick_source/sim_services/Executive/Executive_thread_sync.cpp @@ -3,6 +3,7 @@ #include "trick/Executive.hh" #include "trick/release.h" +#include "trick/clock_proto.h" /** @design @@ -22,6 +23,7 @@ int Trick::Executive::thread_sync() { unsigned int ii ; + long long time_before_rt_nap, time_after_rt_nap ; /* Wait for async_must finish to complete at the current time_tics */ for (ii = 1; ii < threads.size() ; ii++) { @@ -30,7 +32,10 @@ int Trick::Executive::thread_sync() { (curr_thread->amf_next_tics == time_tics )) { while (curr_thread->child_complete == false ) { if (rt_nap == true) { + time_before_rt_nap = clock_wall_time() ; RELEASE(); + time_after_rt_nap = clock_wall_time() ; + set_rt_nap_stats(time_before_rt_nap, time_after_rt_nap) ; } } } diff --git a/trick_source/sim_services/Executive/Threads_child.cpp b/trick_source/sim_services/Executive/Threads_child.cpp index 3a9ac40b9..4b38118cb 100644 --- a/trick_source/sim_services/Executive/Threads_child.cpp +++ b/trick_source/sim_services/Executive/Threads_child.cpp @@ -22,10 +22,12 @@ #include "trick/Threads.hh" #include "trick/release.h" +#include "trick/Executive.hh" #include "trick/ExecutiveException.hh" #include "trick/exec_proto.h" #include "trick/TrickConstant.hh" #include "trick/message_proto.h" +#include "trick/clock_proto.h" /** @@ -41,6 +43,7 @@ static int call_next_job(Trick::JobData * curr_job, Trick::ScheduledJobQueue & j Trick::JobData * depend_job ; unsigned int ii ; int ret = 0 ; + long long time_before_rt_nap, time_after_rt_nap ; //cout << "time = " << curr_time_tics << " " << curr_job->name << " job next = " // << curr_job->next_tics << " id = " << curr_job->id << endl ; @@ -50,7 +53,10 @@ static int call_next_job(Trick::JobData * curr_job, Trick::ScheduledJobQueue & j depend_job = curr_job->depends[ii] ; while (! depend_job->complete) { if (rt_nap == true) { + time_before_rt_nap = clock_wall_time() ; RELEASE(); + time_after_rt_nap = clock_wall_time() ; + the_exec->set_rt_nap_stats(time_before_rt_nap, time_after_rt_nap) ; } } }