From 4bd389c9d0370d67464c2a508381abe326de3bdf Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 29 Jun 2018 16:46:52 -0700 Subject: systemc: Fill out sc_process_handle and create Process classes. The sc_process_handle class now primarily delegates to a Process object it points at. The Process object does book keeping as far as its internal state, but doesn't yet have a way to run its target function or to schedule itself or inject exceptions into its context of execution. Change-Id: I98389778abe29aa26e3e3a91bf02e6721acc8a9c Reviewed-on: https://gem5-review.googlesource.com/11613 Reviewed-by: Gabe Black Maintainer: Gabe Black --- src/systemc/ext/core/sc_module.hh | 37 ++++++++++++++++++++++-- src/systemc/ext/core/sc_process_handle.hh | 48 +++++++++++++++++++++++++++---- src/systemc/ext/core/sc_sensitive.hh | 22 ++++++++++++++ 3 files changed, 98 insertions(+), 9 deletions(-) (limited to 'src/systemc/ext/core') diff --git a/src/systemc/ext/core/sc_module.hh b/src/systemc/ext/core/sc_module.hh index fd4a802b1..746e0c71e 100644 --- a/src/systemc/ext/core/sc_module.hh +++ b/src/systemc/ext/core/sc_module.hh @@ -47,6 +47,12 @@ namespace sc_gem5 { class Module; +class Process; +struct ProcessFuncWrapper; + +Process *newMethodProcess(const char *name, ProcessFuncWrapper *func); +Process *newThreadProcess(const char *name, ProcessFuncWrapper *func); +Process *newCThreadProcess(const char *name, ProcessFuncWrapper *func); } // namespace sc_gem5 @@ -271,9 +277,34 @@ bool timed_out(); #define SC_HAS_PROCESS(name) typedef name SC_CURRENT_USER_MODULE -#define SC_METHOD(name) /* Implementation defined */ -#define SC_THREAD(name) /* Implementation defined */ -#define SC_CTHREAD(name, clk) /* Implementation defined */ +#define SC_METHOD(name) \ + { \ + ::sc_gem5::Process *p = \ + ::sc_gem5::newMethodProcess( \ + #name, new ::sc_gem5::ProcessMemberFuncWrapper< \ + SC_CURRENT_USER_MODULE>(this, \ + &SC_CURRENT_USER_MODULE::name)); \ + this->sensitive << p; \ + } +#define SC_THREAD(name) \ + { \ + ::sc_gem5::Process *p = \ + ::sc_gem5::newThreadProcess( \ + #name, new ::sc_gem5::ProcessMemberFuncWrapper< \ + SC_CURRENT_USER_MODULE>(this, \ + &SC_CURRENT_USER_MODULE::name)); \ + this->sensitive << p; \ + } +#define SC_CTHREAD(name, clk) \ + { \ + ::sc_gem5::Process *p = \ + ::sc_gem5::newCThreadProcess( \ + #name, new ::sc_gem5::ProcessMemberFuncWrapper< \ + SC_CURRENT_USER_MODULE>(this, \ + &SC_CURRENT_USER_MODULE::name)); \ + this->sensitive << p; \ + this->sensitive << clk; \ + } // Nonstandard // Documentation for this is very scarce, but it looks like it's supposed to diff --git a/src/systemc/ext/core/sc_process_handle.hh b/src/systemc/ext/core/sc_process_handle.hh index e577b9e47..2db553b7a 100644 --- a/src/systemc/ext/core/sc_process_handle.hh +++ b/src/systemc/ext/core/sc_process_handle.hh @@ -38,6 +38,40 @@ namespace sc_gem5 class Process; +struct ProcessFuncWrapper +{ + virtual void call() = 0; + virtual ~ProcessFuncWrapper() {} +}; + +template +struct ProcessMemberFuncWrapper : public ProcessFuncWrapper +{ + typedef void (T::*TFunc)(); + T *t; + TFunc func; + + ProcessMemberFuncWrapper(T *t, TFunc func) : t(t), func(func) {} + + void call() override { (t->*func)(); } +}; + +struct ExceptionWrapperBase +{ + virtual void throw_it() = 0; +}; + +template +struct ExceptionWrapper : public ExceptionWrapperBase +{ + const T &t; + ExceptionWrapper(const T &t) : t(t) {} + + void throw_it() { throw t; } +}; + +void throw_it_wrapper(Process *p, ExceptionWrapperBase &exc, bool inc_kids); + } // namespace sc_gem5 namespace sc_core @@ -133,7 +167,7 @@ class sc_process_handle bool operator == (const sc_process_handle &) const; bool operator != (const sc_process_handle &) const; bool operator < (const sc_process_handle &) const; - bool swap(sc_process_handle &); + void swap(sc_process_handle &); const char *name() const; sc_curr_proc_kind proc_kind() const; @@ -165,13 +199,15 @@ class sc_process_handle void sync_reset_off(sc_descendent_inclusion_info include_descendants= SC_NO_DESCENDANTS); - void warn_unimpl(const char *func); template - void throw_it(const T &user_defined_exception, - sc_descendent_inclusion_info include_descendants= - SC_NO_DESCENDANTS) + void + throw_it(const T &user_defined_exception, + sc_descendent_inclusion_info include_descendants= + SC_NO_DESCENDANTS) { - warn_unimpl(__PRETTY_FUNCTION__); + ::sc_gem5::ExceptionWrapper exc(user_defined_exception); + ::sc_gem5::throw_it_wrapper(_gem5_process, exc, + include_descendants == SC_INCLUDE_DESCENDANTS); } }; diff --git a/src/systemc/ext/core/sc_sensitive.hh b/src/systemc/ext/core/sc_sensitive.hh index 62f18b6d2..72d401f68 100644 --- a/src/systemc/ext/core/sc_sensitive.hh +++ b/src/systemc/ext/core/sc_sensitive.hh @@ -30,12 +30,20 @@ #ifndef __SYSTEMC_EXT_CORE_SC_SENSITIVE_HH__ #define __SYSTEMC_EXT_CORE_SC_SENSITIVE_HH__ +namespace sc_gem5 +{ + +class Process; + +} // namespace sc_gem5 + namespace sc_core { class sc_event; class sc_event_finder; class sc_interface; +class sc_module; class sc_port_base; class sc_sensitive @@ -45,6 +53,20 @@ class sc_sensitive sc_sensitive &operator << (const sc_interface &); sc_sensitive &operator << (const sc_port_base &); sc_sensitive &operator << (sc_event_finder &); + + sc_sensitive &operator << (::sc_gem5::Process *p); + + private: + friend class sc_module; + + // Install all the static events which may not have been ready at + // construction time, like the default_event of the peer of an unbound + // port. + void finalize(); + + sc_sensitive(); + + ::sc_gem5::Process *currentProcess; }; } // namespace sc_core -- cgit v1.2.3