| /***************************************************************************** | |
| Licensed to Accellera Systems Initiative Inc. (Accellera) under one or | |
| more contributor license agreements. See the NOTICE file distributed | |
| with this work for additional information regarding copyright ownership. | |
| Accellera licenses this file to you under the Apache License, Version 2.0 | |
| (the "License"); you may not use this file except in compliance with the | |
| License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
| implied. See the License for the specific language governing | |
| permissions and limitations under the License. | |
| *****************************************************************************/ | |
| /***************************************************************************** | |
| sc_process_handle.h -- Process access support. | |
| Original Author: Andy Goodrich, Forte Design Systems, 17 June 2003 | |
| CHANGE LOG AT THE END OF THE FILE | |
| *****************************************************************************/ | |
| // $Log: sc_process_handle.h,v $ | |
| // Revision 1.21 2011/08/26 21:54:04 acg | |
| // Torsten Maehne: Simplify use of dynamic_cast<> for initializing m_target. | |
| // | |
| // Revision 1.20 2011/08/26 20:46:10 acg | |
| // Andy Goodrich: moved the modification log to the end of the file to | |
| // eliminate source line number skew when check-ins are done. | |
| // | |
| #if !defined(sc_process_handle_h_INCLUDED) | |
| #define sc_process_handle_h_INCLUDED | |
| #include "sysc/kernel/sc_module.h" | |
| namespace sc_core { | |
| // forward operator declarations: | |
| class sc_process_handle; | |
| bool | |
| operator == ( const sc_process_handle& left, const sc_process_handle& right ); | |
| bool | |
| operator != ( const sc_process_handle& left, const sc_process_handle& right ); | |
| bool | |
| operator < ( const sc_process_handle& left, const sc_process_handle& right ); | |
| //============================================================================= | |
| // CLASS sc_process_handle | |
| // | |
| // This class provides access to an sc_process_b object instance in a | |
| // manner which allows some persistence after the deletion of the actual | |
| // process. | |
| //============================================================================= | |
| class sc_simcontext; | |
| class sc_process_handle { | |
| typedef sc_process_handle this_type; | |
| friend bool operator == ( const this_type& left, const this_type& right ); | |
| friend bool operator != ( const this_type& left, const this_type& right ); | |
| friend bool operator < ( const this_type& left, const this_type& right ); | |
| friend class sc_object; | |
| friend class sc_join; | |
| friend class sc_module; | |
| friend class sc_reset; | |
| friend class sc_sensitive; | |
| friend class sc_sensitive_pos; | |
| friend class sc_sensitive_neg; | |
| friend class sc_thread_process; | |
| public: | |
| inline sc_process_handle(); | |
| inline explicit sc_process_handle( sc_object* object_p ); | |
| inline explicit sc_process_handle( sc_process_b* process_p ); | |
| inline sc_process_handle( const sc_process_handle& orig ); | |
| inline ~sc_process_handle(); | |
| inline sc_process_handle& operator = ( sc_process_handle src ); | |
| inline void swap( sc_process_handle& other ); | |
| public: | |
| inline void disable( | |
| sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS ); | |
| inline bool dynamic() const; | |
| inline void enable( | |
| sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS ); | |
| inline const std::vector<sc_event*>& get_child_events() const; | |
| inline const std::vector<sc_object*>& get_child_objects() const; | |
| inline sc_object* get_parent_object() const; | |
| inline sc_object* get_process_object() const; | |
| inline bool is_unwinding() const; | |
| inline void kill( | |
| sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS ); | |
| inline const char* name() const; | |
| inline sc_curr_proc_kind proc_kind() const; | |
| inline void reset( | |
| sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS ); | |
| inline sc_event& reset_event() const; | |
| inline void resume( | |
| sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS ); | |
| inline void suspend( | |
| sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS ); | |
| inline void sync_reset_off( | |
| sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS ); | |
| inline void sync_reset_on( | |
| sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS ); | |
| inline sc_event& terminated_event(); | |
| inline bool terminated() const; | |
| template<typename EXCEPT> | |
| inline void throw_it( const EXCEPT& exception, | |
| sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS ); | |
| inline bool valid() const; | |
| public: // implementation specific methods: | |
| inline std::string dump_state() const; | |
| protected: | |
| inline bool dont_initialize() const | |
| { return m_target_p ? m_target_p->dont_initialize() : false; } | |
| inline void dont_initialize( bool dont ); | |
| public: | |
| operator sc_process_b* () | |
| { return m_target_p; } | |
| operator sc_cthread_handle (); | |
| operator sc_method_handle (); | |
| operator sc_thread_handle (); | |
| protected: | |
| sc_process_b* m_target_p; // Target for this object instance. | |
| protected: | |
| static std::vector<sc_event*> empty_event_vector; // If m_target_p == 0. | |
| static std::vector<sc_object*> empty_object_vector; // If m_target_p == 0. | |
| static sc_event non_event; // If m_target_p == 0. | |
| }; | |
| inline bool operator == ( | |
| const sc_process_handle& left, const sc_process_handle& right ) | |
| { | |
| return (left.m_target_p != 0) && (right.m_target_p != 0) && | |
| (left.m_target_p == right.m_target_p); | |
| } | |
| inline bool operator != ( | |
| const sc_process_handle& left, const sc_process_handle& right ) | |
| { | |
| return (left.m_target_p == 0) || (right.m_target_p == 0) || | |
| (left.m_target_p != right.m_target_p); | |
| } | |
| inline bool operator < ( | |
| const sc_process_handle& left, const sc_process_handle& right ) | |
| { | |
| return left.m_target_p < right.m_target_p; | |
| } | |
| //------------------------------------------------------------------------------ | |
| //"sc_process_handle::sc_process_handle - non-pointer constructor" | |
| // | |
| // This version of the object instance constructor for this class creates | |
| // an object instance whose target needs to be supplied via an assignment. | |
| //------------------------------------------------------------------------------ | |
| inline sc_process_handle::sc_process_handle() : m_target_p(0) | |
| { | |
| } | |
| //------------------------------------------------------------------------------ | |
| //"sc_process_handle::sc_process_handle - pointer constructor" | |
| // | |
| // This version of the object instance constructor for this class creates | |
| // an object instance whose target is the supplied sc_object instance. | |
| // The supplied sc_object must in fact be an sc_process_b instance. | |
| // object_p -> sc_object instance this is handle for. | |
| //------------------------------------------------------------------------------ | |
| inline sc_process_handle::sc_process_handle( sc_object* object_p ) : | |
| m_target_p(DCAST<sc_process_b*>(object_p)) | |
| { | |
| if ( m_target_p ) m_target_p->reference_increment(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| //"sc_process_handle::sc_process_handle - pointer constructor" | |
| // | |
| // This version of the object instance constructor for this class creates | |
| // an object instance whose target is the supplied sc_process_b instance. | |
| // This saves a dynamic cast compared to the sc_object* case. | |
| // process_p -> process instance this is handle for. | |
| //------------------------------------------------------------------------------ | |
| inline sc_process_handle::sc_process_handle( sc_process_b* process_p ) : | |
| m_target_p(process_p) | |
| { | |
| if ( m_target_p ) m_target_p->reference_increment(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| //"sc_process_handle::sc_process_handle - copy constructor" | |
| // | |
| // This version of the object instance constructor for this class provides | |
| // the copy constructor for the class. It clones the supplied original | |
| // handle and increments the references to its target. | |
| // orig = sc_process_handle object instance to be copied from. | |
| //------------------------------------------------------------------------------ | |
| inline sc_process_handle::sc_process_handle( const sc_process_handle& orig ) : | |
| m_target_p(orig.m_target_p) | |
| { | |
| if ( m_target_p ) m_target_p->reference_increment(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| //"sc_process_handle::operator =" | |
| // | |
| // This assignment operator signature is call by value rather than reference. | |
| // This means that an sc_process_handle instance will be created and the | |
| // target for that instance will be incremented before the assignment is done. | |
| // The assignment is done using the swap() method, which simply swaps the | |
| // targets of 'orig' and this object instance. We don't need to increment | |
| // the reference count for our new target since that was done when 'orig' | |
| // was created. Our old target's reference count will be decremented when | |
| // 'orig' is deleted. | |
| // orig = sc_process_handle object instance to be copied from. | |
| // Result is a reference for this object instance. | |
| //------------------------------------------------------------------------------ | |
| inline sc_process_handle& | |
| sc_process_handle::operator = ( sc_process_handle orig ) | |
| { | |
| swap( orig ); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| //"sc_process_handle::~sc_process_handle" | |
| // | |
| // This is the object instance destructor for this class. It decrements | |
| // the reference count for its target. | |
| //------------------------------------------------------------------------------ | |
| inline sc_process_handle::~sc_process_handle() | |
| { | |
| if ( m_target_p ) m_target_p->reference_decrement(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| //"sc_process_handle::inline methods" | |
| // | |
| // These are short inline methods. | |
| //------------------------------------------------------------------------------ | |
| // disable this object instance's target. | |
| inline void sc_process_handle::disable(sc_descendant_inclusion_info descendants) | |
| { | |
| if ( m_target_p ) | |
| m_target_p->disable_process(descendants); | |
| else | |
| SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "disable()"); | |
| } | |
| // call dont_initialize() on this object instance's target. | |
| inline void sc_process_handle::dont_initialize( bool dont ) | |
| { | |
| if ( m_target_p ) | |
| m_target_p->dont_initialize( dont ); | |
| else | |
| SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "dont_initialize()"); | |
| } | |
| // dump the status of this object instance's target: | |
| inline std::string sc_process_handle::dump_state() const | |
| { | |
| return m_target_p ? m_target_p->dump_state() : std::string("NO TARGET"); | |
| } | |
| // return whether this object instance's target is dynamic or not. | |
| inline bool sc_process_handle::dynamic() const | |
| { | |
| return m_target_p ? m_target_p->dynamic() : false; | |
| } | |
| // enable this object instance's target. | |
| inline void sc_process_handle::enable(sc_descendant_inclusion_info descendants) | |
| { | |
| if ( m_target_p ) | |
| m_target_p->enable_process(descendants); | |
| else | |
| SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "enable()"); | |
| } | |
| // return the child objects for this object instance's target. | |
| inline | |
| const std::vector<sc_event*>& sc_process_handle::get_child_events() const | |
| { | |
| return m_target_p ? m_target_p->get_child_events() : empty_event_vector; | |
| } | |
| // return the child objects for this object instance's target. | |
| inline | |
| const std::vector<sc_object*>& sc_process_handle::get_child_objects() const | |
| { | |
| return m_target_p ? m_target_p->get_child_objects() : empty_object_vector; | |
| } | |
| // return the parent object for this object instance's target. | |
| inline sc_object* sc_process_handle::get_parent_object() const | |
| { | |
| return m_target_p ? m_target_p->get_parent_object() : NULL; | |
| } | |
| // return this object instance's target. | |
| inline sc_object* sc_process_handle::get_process_object() const | |
| { | |
| return m_target_p; | |
| } | |
| // return whether this object instance is unwinding or not. | |
| inline bool sc_process_handle::is_unwinding() const | |
| { | |
| if ( m_target_p ) | |
| return m_target_p->is_unwinding(); | |
| else { | |
| SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "is_unwinding()"); | |
| return false; | |
| } | |
| } | |
| // kill this object instance's target. | |
| inline void sc_process_handle::kill( sc_descendant_inclusion_info descendants ) | |
| { | |
| if ( m_target_p ) | |
| m_target_p->kill_process( descendants ); | |
| else | |
| SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "kill()"); | |
| } | |
| // return the name of this object instance's target. | |
| inline const char* sc_process_handle::name() const | |
| { | |
| return m_target_p ? m_target_p->name() : ""; | |
| } | |
| // return the process kind for this object instance's target. | |
| inline sc_curr_proc_kind sc_process_handle::proc_kind() const | |
| { | |
| return m_target_p ? m_target_p->proc_kind() : SC_NO_PROC_; | |
| } | |
| // reset this object instance's target. | |
| inline void sc_process_handle::reset( sc_descendant_inclusion_info descendants ) | |
| { | |
| if ( m_target_p ) | |
| m_target_p->reset_process( sc_process_b::reset_asynchronous, | |
| descendants ); | |
| else | |
| SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "reset()"); | |
| } | |
| // return the reset event for this object instance's target. | |
| inline sc_event& sc_process_handle::reset_event() const | |
| { | |
| if ( m_target_p ) | |
| return m_target_p->reset_event(); | |
| else | |
| { | |
| SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "reset()"); | |
| return sc_process_handle::non_event; | |
| } | |
| } | |
| // resume this object instance's target. | |
| inline void sc_process_handle::resume(sc_descendant_inclusion_info descendants) | |
| { | |
| if ( m_target_p ) | |
| m_target_p->resume_process(descendants); | |
| else | |
| SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "resume()"); | |
| } | |
| // suspend this object instance's target. | |
| inline void sc_process_handle::suspend(sc_descendant_inclusion_info descendants) | |
| { | |
| if ( m_target_p ) | |
| m_target_p->suspend_process(descendants); | |
| else | |
| SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "suspend()"); | |
| } | |
| // swap targets of this process handle with the supplied one. | |
| inline void sc_process_handle::swap( sc_process_handle& other ) | |
| { | |
| sc_process_b* tmp = m_target_p; | |
| m_target_p = other.m_target_p; | |
| other.m_target_p = tmp; | |
| } | |
| // turn sync_reset off for this object instance's target. | |
| inline void sc_process_handle::sync_reset_off( | |
| sc_descendant_inclusion_info descendants) | |
| { | |
| if ( m_target_p ) | |
| m_target_p->reset_process( sc_process_b::reset_synchronous_off, | |
| descendants); | |
| else | |
| SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "sync_reset_off()"); | |
| } | |
| // turn sync_reset on for this object instance's target. | |
| inline void sc_process_handle::sync_reset_on( | |
| sc_descendant_inclusion_info descendants) | |
| { | |
| if ( m_target_p ) | |
| { | |
| m_target_p->reset_process(sc_process_b::reset_synchronous_on, | |
| descendants); | |
| } | |
| else | |
| { | |
| SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "sync_reset_on()"); | |
| } | |
| } | |
| // terminate this object instance's target. | |
| inline bool sc_process_handle::terminated() const | |
| { | |
| return m_target_p ? m_target_p->terminated() : false; | |
| } | |
| // return the termination event for this object instance's target. | |
| inline sc_event& sc_process_handle::terminated_event() | |
| { | |
| if ( m_target_p ) | |
| return m_target_p->terminated_event(); | |
| else | |
| { | |
| SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "terminated_event()"); | |
| return sc_process_handle::non_event; | |
| } | |
| } | |
| // return true if this object instance has a target, false it not. | |
| inline bool sc_process_handle::valid() const | |
| { | |
| return m_target_p ? true : false; | |
| } | |
| //------------------------------------------------------------------------------ | |
| //"sc_process_handle::sc_throw_it" | |
| // | |
| // This method throws the supplied exception to the process whose handle this | |
| // object instance is, and optionally to the process' descendants. Once the | |
| // exception is thrown the currently executed process will suspend to allow | |
| // the exception to be propagated. Once the propagation has occurred the | |
| // current process will be resumed. | |
| // | |
| // Notes: | |
| // (1) We allocate the helper function on the stack, see the description of | |
| // sc_throw_it<EXCEPT>, in sc_process.h, for why. | |
| // | |
| // Arguments: | |
| // exception = exception to be thrown | |
| // descendants = indication of whether descendant processes should also | |
| // receive the throw. | |
| //------------------------------------------------------------------------------ | |
| template<typename EXCEPT> | |
| inline void sc_process_handle::throw_it( const EXCEPT& exception, | |
| sc_descendant_inclusion_info descendants) | |
| { | |
| sc_throw_it<EXCEPT> helper(exception); // helper to throw the exception. | |
| if ( !m_target_p ) | |
| { | |
| SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "throw_it()"); | |
| return; | |
| } | |
| m_target_p->throw_user(helper, descendants); | |
| } | |
| //------------------------------------------------------------------------------ | |
| //"sc_process_b::last_created_process_handle" | |
| // | |
| // This method returns the kind of this process. | |
| //------------------------------------------------------------------------------ | |
| inline sc_process_handle sc_process_b::last_created_process_handle() | |
| { | |
| return sc_process_handle(m_last_created_process_p); | |
| } | |
| inline sc_process_handle sc_get_last_created_process_handle() | |
| { | |
| return sc_process_b::last_created_process_handle(); | |
| } | |
| } // namespace sc_core | |
| // Revision 1.19 2011/08/24 22:05:51 acg | |
| // Torsten Maehne: initialization changes to remove warnings. | |
| // | |
| // Revision 1.18 2011/04/01 22:08:26 acg | |
| // Andy Goodrich: remove unused variable. | |
| // | |
| // Revision 1.17 2011/03/12 21:07:51 acg | |
| // Andy Goodrich: changes to kernel generated event support. | |
| // | |
| // Revision 1.16 2011/02/18 20:27:14 acg | |
| // Andy Goodrich: Updated Copyrights. | |
| // | |
| // Revision 1.15 2011/02/17 19:53:03 acg | |
| // Andy Goodrich: changed dump_status() to dump_state() with new signature. | |
| // | |
| // Revision 1.14 2011/02/13 21:47:37 acg | |
| // Andy Goodrich: update copyright notice. | |
| // | |
| // Revision 1.13 2011/02/13 21:33:30 acg | |
| // Andy Goodrich: added dump_status() to allow the dumping of the status | |
| // of a process handle's target. | |
| // | |
| // Revision 1.12 2011/02/01 23:01:53 acg | |
| // Andy Goodrich: removed dead code. | |
| // | |
| // Revision 1.11 2011/02/01 21:07:36 acg | |
| // Andy Goodrich: defering of run queue manipulations to the | |
| // sc_thread_process::throw_it() method. | |
| // | |
| // Revision 1.10 2011/01/25 20:50:37 acg | |
| // Andy Goodrich: changes for IEEE 1666 2011. | |
| // | |
| // Revision 1.9 2011/01/20 16:52:20 acg | |
| // Andy Goodrich: changes for IEEE 1666 2011. | |
| // | |
| // Revision 1.8 2011/01/19 23:21:50 acg | |
| // Andy Goodrich: changes for IEEE 1666 2011 | |
| // | |
| // Revision 1.7 2011/01/18 20:10:45 acg | |
| // Andy Goodrich: changes for IEEE1666_2011 semantics. | |
| // | |
| // Revision 1.6 2010/07/30 05:21:22 acg | |
| // Andy Goodrich: release 2.3 fixes. | |
| // | |
| // Revision 1.5 2010/07/22 20:02:33 acg | |
| // Andy Goodrich: bug fixes. | |
| // | |
| // Revision 1.4 2009/05/22 16:06:29 acg | |
| // Andy Goodrich: process control updates. | |
| // | |
| // Revision 1.3 2008/05/22 17:06:26 acg | |
| // Andy Goodrich: updated copyright notice to include 2008. | |
| // | |
| // Revision 1.2 2007/09/20 20:32:35 acg | |
| // Andy Goodrich: changes to the semantics of throw_it() to match the | |
| // specification. A call to throw_it() will immediately suspend the calling | |
| // thread until all the throwees have executed. At that point the calling | |
| // thread will be restarted before the execution of any other threads. | |
| // | |
| // Revision 1.1.1.1 2006/12/15 20:20:05 acg | |
| // SystemC 2.3 | |
| // | |
| // Revision 1.7 2006/05/08 17:58:24 acg | |
| // Andy Goodrich: added David Long's forward declarations for friend | |
| // functions, methods, and operators to keep the Microsoft compiler happy. | |
| // | |
| // Revision 1.6 2006/04/20 17:08:17 acg | |
| // Andy Goodrich: 3.0 style process changes. | |
| // | |
| // Revision 1.5 2006/04/11 23:13:21 acg | |
| // Andy Goodrich: Changes for reduced reset support that only includes | |
| // sc_cthread, but has preliminary hooks for expanding to method and thread | |
| // processes also. | |
| // | |
| // Revision 1.4 2006/01/24 20:49:05 acg | |
| // Andy Goodrich: changes to remove the use of deprecated features within the | |
| // simulator, and to issue warning messages when deprecated features are used. | |
| // | |
| // Revision 1.3 2006/01/13 18:44:30 acg | |
| // Added $Log to record CVS changes into the source. | |
| #endif // !defined(sc_spawn_h_INCLUDED) |