From b1f5117bf6e8677ad44e4cae9e5354d2804f3f04 Mon Sep 17 00:00:00 2001 From: Philipp A Hartmann Date: Sat, 28 Apr 2018 16:28:09 +0200 Subject: [PATCH] sc_*_process: remove dynamic processes from process_table Processes spawned during start_of_simulation() are considered dynamic processes, yet are still stored in the kernel's process table during initialization. The check in the destructors needs to catch these processes as well to avoid corruption of the process table during simulation teardown. This patch distinguishes between * SPAWN_ELAB (spawned during elaboration, static processes) * SPAWN_START (spawned during simulation start, dynamic process) * SPAWN_SIM (spawned during simulation, dynamic process) and to categorize dynamic() processes and remove all entries correctly from the process table. --- src/sysc/kernel/sc_method_process.cpp | 3 ++- src/sysc/kernel/sc_process.cpp | 7 ++++++- src/sysc/kernel/sc_process.h | 11 +++++++++-- src/sysc/kernel/sc_thread_process.cpp | 3 ++- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/sysc/kernel/sc_method_process.cpp b/src/sysc/kernel/sc_method_process.cpp index fe1befffe..a9500eb4c 100644 --- a/src/sysc/kernel/sc_method_process.cpp +++ b/src/sysc/kernel/sc_method_process.cpp @@ -372,7 +372,8 @@ sc_method_process::sc_method_process( const char* name_p, //------------------------------------------------------------------------------ sc_method_process::~sc_method_process() { - if( !dynamic() ) { + // Remove from simcontext, if not spawned during simulation + if( m_dynamic_proc != SPAWN_SIM ) { simcontext()->remove_process(this); } } diff --git a/src/sysc/kernel/sc_process.cpp b/src/sysc/kernel/sc_process.cpp index c942f6d6e..c549e16be 100644 --- a/src/sysc/kernel/sc_process.cpp +++ b/src/sysc/kernel/sc_process.cpp @@ -553,7 +553,7 @@ sc_process_b::sc_process_b( const char* name_p, bool is_thread, bool free_host, m_active_areset_n(0), m_active_reset_n(0), m_dont_init( false ), - m_dynamic_proc( simcontext()->elaboration_done() ), + m_dynamic_proc(), m_event_p(0), m_event_count(0), m_event_list_p(0), @@ -583,6 +583,11 @@ sc_process_b::sc_process_b( const char* name_p, bool is_thread, bool free_host, m_trigger_type(STATIC), m_unwinding(false) { + // Check spawn phase: m_ready_to_simulate is set *after* elaboration_done() + unsigned spawned = SPAWN_ELAB; + spawned += simcontext()->elaboration_done(); // -> SPAWN_START, if true + spawned += simcontext()->m_ready_to_simulate; // -> SPAWN_SIM, if true + m_dynamic_proc = static_cast(spawned); // THIS OBJECT INSTANCE IS NOW THE LAST CREATED PROCESS: diff --git a/src/sysc/kernel/sc_process.h b/src/sysc/kernel/sc_process.h index e38ab825d..aef08391f 100644 --- a/src/sysc/kernel/sc_process.h +++ b/src/sysc/kernel/sc_process.h @@ -331,6 +331,13 @@ class SC_API sc_process_b : public sc_object { AND_LIST_TIMEOUT }; + protected: + enum spawn_t { + SPAWN_ELAB = 0x0, // spawned during elaboration (static process) + SPAWN_START = 0x1, // spawned during simulation start (dynamic process) + SPAWN_SIM = 0x2 // spawned during simulation (dynamic process) + }; + public: sc_process_b( const char* name_p, bool is_thread, bool free_host, SC_ENTRY_FUNC method_p, sc_process_host* host_p, @@ -356,7 +363,7 @@ class SC_API sc_process_b : public sc_object { protected: virtual void add_child_object( sc_object* ); void add_static_event( const sc_event& ); - bool dynamic() const { return m_dynamic_proc; } + bool dynamic() const { return m_dynamic_proc != SPAWN_ELAB; } const char* gen_unique_name( const char* basename_, bool preserve_first ); inline sc_report* get_last_report() { return m_last_report_p; } inline bool is_disabled() const; @@ -418,7 +425,7 @@ class SC_API sc_process_b : public sc_object { int m_active_areset_n; // number of aresets active. int m_active_reset_n; // number of resets active. bool m_dont_init; // true: no initialize call. - bool m_dynamic_proc; // true: after elaboration. + spawn_t m_dynamic_proc; // SPAWN_ELAB, SPAWN_START, SPAWN_SIM const sc_event* m_event_p; // Dynamic event waiting on. int m_event_count; // number of events. const sc_event_list* m_event_list_p; // event list waiting on. diff --git a/src/sysc/kernel/sc_thread_process.cpp b/src/sysc/kernel/sc_thread_process.cpp index 46d28f43c..f5cd6a279 100644 --- a/src/sysc/kernel/sc_thread_process.cpp +++ b/src/sysc/kernel/sc_thread_process.cpp @@ -480,7 +480,8 @@ sc_thread_process::~sc_thread_process() m_cor_p = 0; } - if( !dynamic() ) { + // Remove from simcontext, if not spawned during simulation + if( m_dynamic_proc != SPAWN_SIM ) { simcontext()->remove_process(this); } }