1 /*****************************************************************************
2 
3   Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4   more contributor license agreements.  See the NOTICE file distributed
5   with this work for additional information regarding copyright ownership.
6   Accellera licenses this file to you under the Apache License, Version 2.0
7   (the "License"); you may not use this file except in compliance with the
8   License.  You may obtain a copy of the License at
9 
10     http://www.apache.org/licenses/LICENSE-2.0
11 
12   Unless required by applicable law or agreed to in writing, software
13   distributed under the License is distributed on an "AS IS" BASIS,
14   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15   implied.  See the License for the specific language governing
16   permissions and limitations under the License.
17 
18  *****************************************************************************/
19 
20 /*****************************************************************************
21 
22   sc_process.h -- Process base class support.
23 
24   Original Author: Andy Goodrich, Forte Design Systems, 04 August 2005
25 
26 
27   CHANGE LOG AT THE END OF THE FILE
28  *****************************************************************************/
29 
30 
31 #if !defined(sc_process_h_INCLUDED)
32 #define sc_process_h_INCLUDED
33 
34 #include "sysc/kernel/sc_constants.h"
35 #include "sysc/kernel/sc_object.h"
36 #include "sysc/kernel/sc_kernel_ids.h"
37 #include "sysc/communication/sc_export.h"
38 
39 #if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
40 #pragma warning(push)
41 #pragma warning(disable: 4251) // DLL import for std::vector
42 #endif
43 
44 namespace sc_core {
45 
46 // Forward declarations:
47 class sc_process_handle;
48 class sc_thread_process;
49 class sc_reset;
50 
51 SC_API const char* sc_gen_unique_name( const char*, bool preserve_first );
52 SC_API  sc_process_handle sc_get_current_process_handle();
53 void sc_thread_cor_fn( void* arg );
54 SC_API bool timed_out( sc_simcontext* );
55 
56 SC_API extern bool sc_allow_process_control_corners; // see sc_simcontext.cpp.
57 
58 
59 // Process handles as forward references:
60 
61 typedef class sc_cthread_process* sc_cthread_handle;
62 typedef class sc_method_process*  sc_method_handle;
63 typedef class sc_thread_process*  sc_thread_handle;
64 
65 
66 // Standard process types:
67 
68 enum sc_curr_proc_kind
69 {
70     SC_NO_PROC_,
71     SC_METHOD_PROC_,
72     SC_THREAD_PROC_,
73     SC_CTHREAD_PROC_
74 };
75 
76 // Descendant information for process hierarchy operations:
77 
78 enum sc_descendant_inclusion_info {
79     SC_NO_DESCENDANTS=0,
80     SC_INCLUDE_DESCENDANTS,
81     SC_INVALID_DESCENDANTS
82 };
83 
84 
85 //==============================================================================
86 // CLASS sc_process_host
87 //
88 // This is the base class for objects which may have processes defined for
89 // their methods (e.g., sc_module)
90 //==============================================================================
91 
92 class SC_API sc_process_host
93 {
94   public:
sc_process_host()95     sc_process_host() {}
~sc_process_host()96     virtual ~sc_process_host() { } // Needed for cast check for sc_module.
defunct()97     void defunct() {}
98 };
99 
100 
101 //==============================================================================
102 // CLASS sc_process_monitor
103 //
104 // This class provides a way of monitoring a process' status (e.g., waiting
105 // for a thread to complete its execution.) This class is intended to be a base
106 // class for classes which need to monitor a process or processes (e.g.,
107 // sc_join.) Its methods should be overloaded where notifications are desired.
108 //==============================================================================
109 
110 class SC_API sc_process_monitor {
111   public:
112     enum {
113         spm_exit = 0
114     };
~sc_process_monitor()115     virtual ~sc_process_monitor() {}
116     virtual void signal(sc_thread_handle thread_p, int type);
117 };
signal(sc_thread_handle,int)118 inline void sc_process_monitor::signal(sc_thread_handle , int ) {}
119 
120 //------------------------------------------------------------------------------
121 // PROCESS INVOCATION METHOD OR FUNCTION:
122 //
123 //  Define SC_USE_MEMBER_FUNC_PTR if we want to use member function pointers
124 //  to implement process dispatch. Otherwise, we'll use a hack that involves
125 //  creating a templated invocation object which will invoke the member
126 //  function. This should not be necessary, but some compilers (e.g., VC++)
127 //  do not allow the conversion from `void (callback_tag::*)()' to
128 //  `void (sc_process_host::*)()'. This is supposed to be OK as long as the
129 //  dynamic type is correct.  C++ Standard 5.4 "Explicit type conversion",
130 //  clause 7: a pointer to member of derived class type may be explicitly
131 //  converted to a pointer to member of an unambiguous non-virtual base class
132 //  type.
133 //-----------------------------------------------------------------------------
134 
135 #if defined(_MSC_VER)
136 #if ( _MSC_VER > 1200 )
137 #   define SC_USE_MEMBER_FUNC_PTR
138 #endif
139 #else
140 #   define SC_USE_MEMBER_FUNC_PTR
141 #endif
142 
143 
144 // COMPILER DOES SUPPORT CAST TO void (sc_process_host::*)() from (T::*)():
145 
146 #if defined(SC_USE_MEMBER_FUNC_PTR)
147 
148     typedef void (sc_process_host::*SC_ENTRY_FUNC)();
149 #   define SC_DECL_HELPER_STRUCT(callback_tag, func) /*EMPTY*/
150 #   define SC_MAKE_FUNC_PTR(callback_tag, func) \
151         static_cast<sc_core::SC_ENTRY_FUNC>(&callback_tag::func)
152 
153 
154 // COMPILER NOT DOES SUPPORT CAST TO void (sc_process_host::*)() from (T::*)():
155 
156 #else // !defined(SC_USE_MEMBER_FUNC_PTR)
157     class SC_API sc_process_call_base {
158       public:
sc_process_call_base()159         inline sc_process_call_base()
160         {
161         }
162 
~sc_process_call_base()163         virtual ~sc_process_call_base()
164         {
165         }
166 
invoke(sc_process_host * host_p)167         virtual void invoke(sc_process_host* host_p)
168         {
169         }
170     };
171     extern sc_process_call_base sc_process_defunct;
172 
173     template<class T>
174     class sc_process_call : public sc_process_call_base {
175       public:
sc_process_call(void (T::* method_p)())176         sc_process_call( void (T::*method_p)() ) :
177             sc_process_call_base()
178         {
179              m_method_p = method_p;
180         }
181 
~sc_process_call()182         virtual ~sc_process_call()
183         {
184         }
185 
invoke(sc_process_host * host_p)186         virtual void invoke(sc_process_host* host_p)
187         {
188             (((T*)host_p)->*m_method_p)();
189         }
190 
191       protected:
192         void (T::*m_method_p)();  // Method implementing the process.
193     };
194 
195     typedef sc_process_call_base* SC_ENTRY_FUNC;
196 #   define SC_DECL_HELPER_STRUCT(callback_tag, func) /*EMPTY*/
197 #   define SC_MAKE_FUNC_PTR(callback_tag, func) \
198         (::sc_core::SC_ENTRY_FUNC) (new \
199         ::sc_core::sc_process_call<callback_tag>(&callback_tag::func))
200 
201 #endif // !defined(SC_USE_MEMBER_FUNC_PTR)
202 
203 
204 extern SC_API void sc_set_stack_size( sc_thread_handle, std::size_t );
205 
206 class sc_event;
207 class sc_event_list;
208 class sc_name_gen;
209 class sc_spawn_options;
210 class sc_unwind_exception;
211 
212 //==============================================================================
213 // CLASS sc_throw_it<EXCEPT> - ARBITRARY EXCEPTION CLASS
214 //
215 // This class serves as a way of throwing an execption for an aribtrary type
216 // without knowing what that type is. A true virtual method in the base
217 // class is used to actually throw the execption. A pointer to the base
218 // class is used internally removing the necessity of knowing what the type
219 // of EXCEPT is for code internal to the library.
220 //
221 // Note the clone() true virtual method. This is used to allow instances
222 // of the sc_throw_it<EXCEPT> class to be easily garbage collected. Since
223 // an exception may be propogated to more than one process knowing when
224 // to garbage collect is non-trivial. So when a call is made to
225 // sc_process_handle::throw_it() an instance of sc_throw_it<EXCEPT> is
226 // allocated on the stack. For each process throwing the exception a copy is
227 // made via clone(). That allows those objects to be deleted by the individual
228 // processes when they are no longer needed (in this implementation of SystemC
229 // that deletion will occur each time a new exception is thrown ( see
230 // sc_thread_process::suspend_me() ).
231 //==============================================================================
232 class SC_API sc_throw_it_helper {
233   public:
234     virtual sc_throw_it_helper* clone() const = 0;
235     virtual void throw_it() = 0;
sc_throw_it_helper()236     sc_throw_it_helper() {}
~sc_throw_it_helper()237     virtual ~sc_throw_it_helper() {}
238 };
239 
240 template<typename EXCEPT>
241 class sc_throw_it : public sc_throw_it_helper
242 {
243     typedef sc_throw_it<EXCEPT> this_type;
244   public:
sc_throw_it(const EXCEPT & value)245     sc_throw_it( const EXCEPT& value ) : m_value(value) { }
~sc_throw_it()246     virtual ~sc_throw_it() {}
clone()247     virtual inline this_type* clone() const { return new this_type(m_value); }
throw_it()248     virtual inline void throw_it() { throw m_value; }
249   protected:
250     EXCEPT m_value;  // value to be thrown.
251 };
252 
253 //==============================================================================
254 // CLASS sc_process_b - USER INITIATED DYNAMIC PROCESS SUPPORT:
255 //
256 // This class implements the base class for a threaded process_base process
257 // whose semantics are provided by the true virtual method semantics().
258 // Classes derived from this one will provide a version of semantics which
259 // implements the desired semantics. See the sc_spawn_xxx classes below.
260 //
261 // Notes:
262 //   (1) Object instances of this class maintain a reference count of
263 //       outstanding handles. When the handle count goes to zero the
264 //       object will be deleted.
265 //   (2) Descriptions of the methods and operators in this class appear with
266 //       their implementations.
267 //   (3) The m_sticky_reset field is used to handle synchronous resets that
268 //       are enabled via the sc_process_handle::sync_reset_on() method. These
269 //       resets are not generated by a signal, but rather are modal by
270 //       method call: sync_reset_on - sync_reset_off.
271 //
272 //==============================================================================
273 class SC_API sc_process_b : public sc_object {
274     friend class sc_simcontext;      // Allow static processes to have base.
275     friend class sc_cthread_process; // Child can access parent.
276     friend class sc_method_process;  // Child can access parent.
277     friend class sc_process_handle;  // Allow handles to modify ref. count.
278     friend class sc_process_table;   // Allow process_table to modify ref. count.
279     friend class sc_thread_process;  // Child can access parent.
280 
281     friend class sc_event;
282     friend class sc_object;
283     friend class sc_port_base;
284     friend class sc_runnable;
285     friend class sc_sensitive;
286     friend class sc_sensitive_pos;
287     friend class sc_sensitive_neg;
288     friend class sc_module;
289     friend class sc_report_handler;
290     friend class sc_reset;
291     friend class sc_reset_finder;
292     friend class sc_unwind_exception;
293 
294     friend SC_API const char* sc_gen_unique_name( const char*, bool preserve_first );
295     friend SC_API sc_process_handle sc_get_current_process_handle();
296     friend void sc_thread_cor_fn( void* arg );
297     friend SC_API bool timed_out( sc_simcontext* );
298 
299   public:
300     enum process_throw_type {
301         THROW_NONE = 0,
302 	THROW_KILL,
303         THROW_USER,
304         THROW_ASYNC_RESET,
305         THROW_SYNC_RESET
306     };
307 
308     enum process_state {
309 	ps_bit_disabled = 1,      // process is disabled.
310 	ps_bit_ready_to_run = 2,  // process is ready to run.
311         ps_bit_suspended = 4,     // process is suspended.
312 	ps_bit_zombie = 8,        // process is a zombie.
313         ps_normal = 0             // must be zero.
314     };
315 
316     enum reset_type {             // types for sc_process_b::reset_process()
317         reset_asynchronous = 0,   // asynchronous reset.
318         reset_synchronous_off,    // turn off synchronous reset sticky bit.
319         reset_synchronous_on      // turn on synchronous reset sticky bit.
320     };
321 
322     enum trigger_t
323     {
324         STATIC,
325         EVENT,
326         OR_LIST,
327         AND_LIST,
328         TIMEOUT,
329         EVENT_TIMEOUT,
330         OR_LIST_TIMEOUT,
331         AND_LIST_TIMEOUT
332     };
333 
334   protected:
335     enum spawn_t {
336       SPAWN_ELAB  = 0x0, // spawned during elaboration      (static process)
337       SPAWN_START = 0x1, // spawned during simulation start (dynamic process)
338       SPAWN_SIM   = 0x2  // spawned during simulation       (dynamic process)
339     };
340 
341   public:
342     sc_process_b( const char* name_p, bool is_thread, bool free_host,
343         SC_ENTRY_FUNC method_p, sc_process_host* host_p,
344         const sc_spawn_options* opt_p );
345 
346   protected:
347     // may not be deleted manually (called from destroy_process())
348     virtual ~sc_process_b();
349 
350   public:
current_state()351     inline int current_state() { return m_state; }
dont_initialize()352     bool dont_initialize() const { return m_dont_init; }
353     virtual void dont_initialize( bool dont );
354     std::string dump_state() const;
355     const ::std::vector<sc_object*>& get_child_objects() const;
356     inline sc_curr_proc_kind proc_kind() const;
357     sc_event& reset_event();
358     sc_event& terminated_event();
359 
360   public:
361     static inline sc_process_handle last_created_process_handle();
362 
363   protected:
364     virtual void add_child_object( sc_object* );
365     void add_static_event( const sc_event& );
dynamic()366     bool dynamic() const { return m_dynamic_proc != SPAWN_ELAB; }
367     const char* gen_unique_name( const char* basename_, bool preserve_first );
get_last_report()368     inline sc_report* get_last_report() { return m_last_report_p; }
369     inline bool is_disabled() const;
370     inline bool is_runnable() const;
371     static inline sc_process_b* last_created_process_base();
372     virtual bool remove_child_object( sc_object* );
373     void remove_dynamic_events( bool skip_timeout = false );
374     void remove_static_events();
set_last_report(sc_report * last_p)375     inline void set_last_report( sc_report* last_p )
376         {
377             delete m_last_report_p;
378             m_last_report_p = last_p;
379         }
380     inline bool timed_out() const;
381     void report_error( const char* msgid, const char* msg = "" ) const;
382     void report_immediate_self_notification() const;
383 
384   protected: // process control methods:
385     virtual void disable_process(
386         sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
387     void disconnect_process();
388     virtual void enable_process(
389         sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
390     inline void initially_in_reset( bool async );
391     inline bool is_unwinding() const;
392     inline bool start_unwinding();
393     inline bool clear_unwinding();
394     virtual void kill_process(
395         sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
396     void reset_changed( bool async, bool asserted );
397     void reset_process( reset_type rt,
398         sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
399     virtual void resume_process(
400         sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
401     virtual void suspend_process(
402         sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
403     virtual void throw_user( const sc_throw_it_helper& helper,
404         sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS ) = 0;
405     virtual void throw_reset( bool async ) = 0;
406     virtual bool terminated() const;
407     void trigger_reset_event();
408 
409   private:
410     void        delete_process();
411     inline void reference_decrement();
412     inline void reference_increment();
413 
414   protected:
415     inline void semantics();
416 
417     // debugging stuff:
418 
419   public:
420     const char*                 file;
421     int                         lineno;
422     int                         proc_id;
423 
424   protected:
425     int                          m_active_areset_n; // number of aresets active.
426     int                          m_active_reset_n;  // number of resets active.
427     bool                         m_dont_init;       // true: no initialize call.
428     spawn_t                      m_dynamic_proc;    // SPAWN_ELAB, SPAWN_START, SPAWN_SIM
429     const sc_event*              m_event_p;         // Dynamic event waiting on.
430     int                          m_event_count;     // number of events.
431     const sc_event_list*         m_event_list_p;    // event list waiting on.
432     sc_process_b*                m_exist_p;         // process existence link.
433     bool                         m_free_host;       // free sc_semantic_host_p.
434     bool                         m_has_reset_signal;  // has reset_signal_is.
435     bool                         m_has_stack;       // true is stack present.
436     bool                         m_is_thread;       // true if this is thread.
437     sc_report*                   m_last_report_p;   // last report this process.
438     sc_name_gen*                 m_name_gen_p;      // subprocess name generator
439     sc_curr_proc_kind            m_process_kind;    // type of process.
440     int                          m_references_n;    // outstanding handles.
441     std::vector<sc_reset*>       m_resets;          // resets for process.
442     sc_event*                    m_reset_event_p;   // reset event.
443     sc_event*                    m_resume_event_p;  // resume event.
444     sc_process_b*                m_runnable_p;      // sc_runnable link
445     sc_process_host*             m_semantics_host_p;   // host for semantics.
446     SC_ENTRY_FUNC                m_semantics_method_p; // method for semantics.
447     int                          m_state;           // process state.
448     std::vector<const sc_event*> m_static_events;   // static events waiting on.
449     bool                         m_sticky_reset;    // see note 3 above.
450     sc_event*                    m_term_event_p;    // terminated event.
451     sc_throw_it_helper*          m_throw_helper_p;  // what to throw.
452     process_throw_type           m_throw_status;    // exception throwing status
453     bool                         m_timed_out;       // true if we timed out.
454     sc_event*                    m_timeout_event_p; // timeout event.
455     trigger_t                    m_trigger_type;    // type of trigger using.
456     bool                         m_unwinding;       // true if unwinding stack.
457 
458   protected:
459     static sc_process_b* m_last_created_process_p; // Last process created.
460 };
461 
462 typedef sc_process_b sc_process_b;  // For compatibility.
463 
464 
465 //------------------------------------------------------------------------------
466 //"sc_process_b::XXXX_child_YYYYY"
467 //
468 // These methods provide child object support.
469 //------------------------------------------------------------------------------
470 inline void
add_child_object(sc_object * object_p)471 sc_process_b::add_child_object( sc_object* object_p )
472 {
473     sc_object::add_child_object( object_p );
474     reference_increment();
475 }
476 
477 inline bool
remove_child_object(sc_object * object_p)478 sc_process_b::remove_child_object( sc_object* object_p )
479 {
480     if ( sc_object::remove_child_object( object_p ) ) {
481 	    reference_decrement();
482             return true;
483     }
484     else
485     {
486         return false;
487     }
488 }
489 
490 inline const ::std::vector<sc_object*>&
get_child_objects()491 sc_process_b::get_child_objects() const
492 {
493     return m_child_objects;
494 }
495 
496 
497 //------------------------------------------------------------------------------
498 //"sc_process_b::initially_in_reset"
499 //
500 // This inline method is a callback to indicate that a reset is active at
501 // start up. This is because the signal will have been initialized before
502 // a reset linkage for it is set up, so we won't get a reset_changed()
503 // callback.
504 //     async = true if this an asynchronous reset.
505 //------------------------------------------------------------------------------
initially_in_reset(bool async)506 inline void sc_process_b::initially_in_reset( bool async )
507 {
508     if ( async )
509         m_active_areset_n++;
510     else
511         m_active_reset_n++;
512 }
513 
514 //------------------------------------------------------------------------------
515 //"sc_process_b::is_disabled"
516 //
517 // This method returns true if this process is disabled.
518 //------------------------------------------------------------------------------
is_disabled()519 inline bool sc_process_b::is_disabled() const
520 {
521     return (m_state & ps_bit_disabled) ? true : false;
522 }
523 
524 //------------------------------------------------------------------------------
525 //"sc_process_b::is_runnable"
526 //
527 // This method returns true if this process is runnable. That is indicated
528 // by a non-zero m_runnable_p field.
529 //------------------------------------------------------------------------------
is_runnable()530 inline bool sc_process_b::is_runnable() const
531 {
532     return m_runnable_p != 0;
533 }
534 
535 //------------------------------------------------------------------------------
536 //"sc_process_b::is_unwinding"
537 //
538 // This method returns true if this process is unwinding from a kill or reset.
539 //------------------------------------------------------------------------------
is_unwinding()540 inline bool sc_process_b::is_unwinding() const
541 {
542     return m_unwinding;
543 }
544 
545 //------------------------------------------------------------------------------
546 //"sc_process_b::start_unwinding"
547 //
548 // This method flags that this object instance should start unwinding if the
549 // current throw status requires an unwind.
550 //
551 // Result is true if the flag is set, false if the flag is already set.
552 //------------------------------------------------------------------------------
start_unwinding()553 inline bool sc_process_b::start_unwinding()
554 {
555     if ( !m_unwinding )
556     {
557 	switch( m_throw_status )
558 	{
559 	  case THROW_KILL:
560 	  case THROW_ASYNC_RESET:
561 	  case THROW_SYNC_RESET:
562 	    m_unwinding = true;
563 	     return true;
564 	  case THROW_USER:
565 	   default:
566 	     break;
567 	 }
568     }
569     return false;
570 }
571 
572 //------------------------------------------------------------------------------
573 //"sc_process_b::clear_unwinding"
574 //
575 // This method clears this object instance's throw status and always returns
576 // true.
577 //------------------------------------------------------------------------------
clear_unwinding()578 inline bool sc_process_b::clear_unwinding()
579 {
580     m_unwinding = false;
581     return true;
582 }
583 
584 
585 //------------------------------------------------------------------------------
586 //"sc_process_b::last_created_process_base"
587 //
588 // This virtual method returns the sc_process_b pointer for the last
589 // created process. It is only used internally by the simulator.
590 //------------------------------------------------------------------------------
last_created_process_base()591 inline sc_process_b* sc_process_b::last_created_process_base()
592 {
593     return m_last_created_process_p;
594 }
595 
596 
597 
598 //------------------------------------------------------------------------------
599 //"sc_process_b::proc_kind"
600 //
601 // This method returns the kind of this process.
602 //------------------------------------------------------------------------------
proc_kind()603 inline sc_curr_proc_kind sc_process_b::proc_kind() const
604 {
605     return m_process_kind;
606 }
607 
608 
609 //------------------------------------------------------------------------------
610 //"sc_process_b::reference_decrement"
611 //
612 // This inline method decrements the number of outstanding references to this
613 // object instance. If the number of references goes to zero, this object
614 // can be deleted in "sc_process_b::delete_process()".
615 //------------------------------------------------------------------------------
reference_decrement()616 inline void sc_process_b::reference_decrement()
617 {
618     m_references_n--;
619     if ( m_references_n == 0 ) delete_process();
620 }
621 
622 
623 //------------------------------------------------------------------------------
624 //"sc_process_b::reference_increment"
625 //
626 // This inline method increments the number of outstanding references to this
627 // object instance.
628 //------------------------------------------------------------------------------
reference_increment()629 inline void sc_process_b::reference_increment()
630 {
631     sc_assert(m_references_n != 0);
632     m_references_n++;
633 }
634 
635 //------------------------------------------------------------------------------
636 //"sc_process_b::semantics"
637 //
638 // This inline method invokes the semantics for this object instance.
639 // We check to see if we are initially in reset and then invoke the
640 // process semantics.
641 //
642 // Notes:
643 //   (1) For a description of the process reset mechanism see the top of
644 //       the file sc_reset.cpp.
645 //------------------------------------------------------------------------------
646 struct SC_API scoped_flag
647 {
scoped_flagscoped_flag648     scoped_flag( bool& b ) : ref(b){ ref = true;  }
~scoped_flagscoped_flag649     ~scoped_flag()                 { ref = false; }
650     bool& ref;
651 private:
652     scoped_flag& operator=(const scoped_flag&) /* = delete */;
653 };
semantics()654 inline void sc_process_b::semantics()
655 {
656 
657     // within this function, the process has a stack associated
658 
659     scoped_flag scoped_stack_flag( m_has_stack );
660 
661     sc_assert( m_process_kind != SC_NO_PROC_ );
662 
663     // Determine the reset status of this object instance and potentially
664     // trigger its notify event:
665 
666     // See if we need to trigger the notify event:
667 
668     if ( m_reset_event_p &&
669          ( (m_throw_status == THROW_SYNC_RESET) ||
670 	   (m_throw_status == THROW_ASYNC_RESET) )
671     ) {
672         trigger_reset_event();
673     }
674 
675     // Set the new reset status of this object based on the reset counts:
676 
677     m_throw_status = m_active_areset_n ? THROW_ASYNC_RESET :
678         ( m_active_reset_n  ?  THROW_SYNC_RESET : THROW_NONE);
679 
680     // Dispatch the actual semantics for the process:
681 
682 #   ifndef SC_USE_MEMBER_FUNC_PTR
683         m_semantics_method_p->invoke( m_semantics_host_p );
684 #   else
685         (m_semantics_host_p->*m_semantics_method_p)();
686 #   endif
687 }
688 
689 
690 //------------------------------------------------------------------------------
691 //"sc_process_b::terminated"
692 //
693 // This inline method returns true if this object has terminated.
694 //------------------------------------------------------------------------------
terminated()695 inline bool sc_process_b::terminated() const
696 {
697     return (m_state & ps_bit_zombie) != 0;
698 }
699 
700 
701 //------------------------------------------------------------------------------
702 //"sc_process_b::timed_out"
703 //
704 // This inline method returns true if this object instance timed out.
705 //------------------------------------------------------------------------------
timed_out()706 inline bool sc_process_b::timed_out() const
707 {
708     return m_timed_out;
709 }
710 
711 } // namespace sc_core
712 
713 #if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
714 #pragma warning(pop)
715 #endif
716 
717 /*****************************************************************************
718 
719   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
720   changes you are making here.
721 
722       Name, Affiliation, Date: Andy Goodrich, Forte Design Systems, 12 Aug 05
723   Description of Modification: This is the rewrite of process support. It
724                                contains some code from the original
725                                sc_process.h by Stan Liao, and the now-defunct
726                                sc_process_b.h by Stan Liao and Martin
727                                Janssen, all of Synopsys, Inc., It also contains
728                                code from the original sc_process_b.h by
729                                Andy Goodrich of Forte Design Systems and
730                                Bishnupriya Bhattacharya of Cadence Design
731                                Systems.
732 
733       Name, Affiliation, Date:
734   Description of Modification:
735 
736  *****************************************************************************/
737 
738 // $Log: sc_process.h,v $
739 // Revision 1.36  2011/08/26 22:44:30  acg
740 //  Torsten Maehne: eliminate unused argument warning.
741 //
742 // Revision 1.35  2011/08/26 20:46:10  acg
743 //  Andy Goodrich: moved the modification log to the end of the file to
744 //  eliminate source line number skew when check-ins are done.
745 //
746 // Revision 1.34  2011/08/24 22:05:51  acg
747 //  Torsten Maehne: initialization changes to remove warnings.
748 //
749 // Revision 1.33  2011/08/15 16:43:24  acg
750 //  Torsten Maehne: changes to remove unused argument warnings.
751 //
752 // Revision 1.32  2011/07/24 11:20:03  acg
753 //  Philipp A. Hartmann: process control error message improvements:
754 //  (1) Downgrade error to warning for re-kills of processes.
755 //  (2) Add process name to process messages.
756 //  (3) drop some superfluous colons in messages.
757 //
758 // Revision 1.31  2011/04/13 02:44:26  acg
759 //  Andy Goodrich: added m_unwinding flag in place of THROW_NOW because the
760 //  throw status will be set back to THROW_*_RESET if reset is active and
761 //  the check for an unwind being complete was expecting THROW_NONE as the
762 //  clearing of THROW_NOW.
763 //
764 // Revision 1.30  2011/04/11 22:07:27  acg
765 //  Andy Goodrich: check for reset event notification before resetting the
766 //  throw_status value.
767 //
768 // Revision 1.29  2011/04/10 22:17:36  acg
769 //  Andy Goodrich: added trigger_reset_event() to allow sc_process.h to
770 //  contain the run_process() inline method. sc_process.h cannot have
771 //  sc_simcontext information because of recursive includes.
772 //
773 // Revision 1.28  2011/04/08 22:34:06  acg
774 //  Andy Goodrich: moved the semantics() method to this file and made it
775 //  an inline method. Added reset processing to the semantics() method.
776 //
777 // Revision 1.27  2011/04/08 18:24:48  acg
778 //  Andy Goodrich: moved reset_changed() to .cpp since it needs visibility
779 //  to sc_simcontext.
780 //
781 // Revision 1.26  2011/04/01 21:24:57  acg
782 //  Andy Goodrich: removed unused code.
783 //
784 // Revision 1.25  2011/03/28 13:02:51  acg
785 //  Andy Goodrich: Changes for disable() interactions.
786 //
787 // Revision 1.24  2011/03/20 13:43:23  acg
788 //  Andy Goodrich: added async_signal_is() plus suspend() as a corner case.
789 //
790 // Revision 1.23  2011/03/12 21:07:51  acg
791 //  Andy Goodrich: changes to kernel generated event support.
792 //
793 // Revision 1.22  2011/03/08 20:49:31  acg
794 //  Andy Goodrich: implement coarse checking for synchronous reset - suspend
795 //  interaction.
796 //
797 // Revision 1.21  2011/03/07 17:38:43  acg
798 //  Andy Goodrich: tightening up of checks for undefined interaction between
799 //  synchronous reset and suspend.
800 //
801 // Revision 1.20  2011/03/06 19:57:11  acg
802 //  Andy Goodrich: refinements for the illegal suspend - synchronous reset
803 //  interaction.
804 //
805 // Revision 1.19  2011/03/05 19:44:20  acg
806 //  Andy Goodrich: changes for object and event naming and structures.
807 //
808 // Revision 1.18  2011/02/19 08:30:53  acg
809 //  Andy Goodrich: Moved process queueing into trigger_static from
810 //  sc_event::notify.
811 //
812 // Revision 1.17  2011/02/18 20:27:14  acg
813 //  Andy Goodrich: Updated Copyrights.
814 //
815 // Revision 1.16  2011/02/18 20:10:44  acg
816 //  Philipp A. Hartmann: force return expression to be a bool to keep MSVC
817 //  happy.
818 //
819 // Revision 1.15  2011/02/17 19:52:45  acg
820 //  Andy Goodrich:
821 //    (1) Simplified process control usage.
822 //    (2) Changed dump_status() to dump_state() with new signature.
823 //
824 // Revision 1.14  2011/02/16 22:37:30  acg
825 //  Andy Goodrich: clean up to remove need for ps_disable_pending.
826 //
827 // Revision 1.13  2011/02/13 21:47:37  acg
828 //  Andy Goodrich: update copyright notice.
829 //
830 // Revision 1.12  2011/02/13 21:41:34  acg
831 //  Andy Goodrich: get the log messages for the previous check in correct.
832 //
833 // Revision 1.11  2011/02/13 21:32:24  acg
834 //  Andy Goodrich: moved sc_process_b::reset_process() implementation
835 //  from header to cpp file . Added dump_status() to print out the status of a
836 //  process.
837 //
838 // Revision 1.10  2011/02/11 13:25:24  acg
839 //  Andy Goodrich: Philipp A. Hartmann's changes:
840 //    (1) Removal of SC_CTHREAD method overloads.
841 //    (2) New exception processing code.
842 //
843 // Revision 1.9  2011/02/04 15:27:36  acg
844 //  Andy Goodrich: changes for suspend-resume semantics.
845 //
846 // Revision 1.8  2011/02/01 21:06:12  acg
847 //  Andy Goodrich: new layout for the process_state enum.
848 //
849 // Revision 1.7  2011/01/25 20:50:37  acg
850 //  Andy Goodrich: changes for IEEE 1666 2011.
851 //
852 // Revision 1.6  2011/01/19 23:21:50  acg
853 //  Andy Goodrich: changes for IEEE 1666 2011
854 //
855 // Revision 1.5  2011/01/18 20:10:45  acg
856 //  Andy Goodrich: changes for IEEE1666_2011 semantics.
857 //
858 // Revision 1.4  2010/07/22 20:02:33  acg
859 //  Andy Goodrich: bug fixes.
860 //
861 // Revision 1.3  2009/05/22 16:06:29  acg
862 //  Andy Goodrich: process control updates.
863 //
864 // Revision 1.2  2008/05/22 17:06:26  acg
865 //  Andy Goodrich: updated copyright notice to include 2008.
866 //
867 // Revision 1.1.1.1  2006/12/15 20:20:05  acg
868 // SystemC 2.3
869 //
870 // Revision 1.11  2006/05/08 17:58:10  acg
871 // Andy Goodrich: added David Long's forward declarations for friend
872 //   functions, methods, and operators to keep the Microsoft compiler happy.
873 //
874 // Revision 1.10  2006/04/28 23:29:01  acg
875 //  Andy Goodrich: added an sc_core:: prefix to SC_FUNC_PTR in the
876 //  SC_MAKE_FUNC_PTR macro to allow its transpareuse outside of the sc_core
877 //  namespace.
878 //
879 // Revision 1.9  2006/04/28 21:52:57  acg
880 //  Andy Goodrich: changed SC_MAKE_FUNC_PTR to use a static cast to address
881 //  and AIX issue wrt sc_module's inherited classes.
882 //
883 // Revision 1.8  2006/04/20 17:08:17  acg
884 //  Andy Goodrich: 3.0 style process changes.
885 //
886 // Revision 1.7  2006/04/11 23:13:21  acg
887 //   Andy Goodrich: Changes for reduced reset support that only includes
888 //   sc_cthread, but has preliminary hooks for expanding to method and thread
889 //   processes also.
890 //
891 // Revision 1.6  2006/03/13 20:26:50  acg
892 //  Andy Goodrich: Addition of forward class declarations, e.g.,
893 //  sc_reset, to keep gcc 4.x happy.
894 //
895 // Revision 1.5  2006/01/31 20:09:10  acg
896 //  Andy Goodrich: added explaination of static vs dynamic waits to
897 //  sc_process_b::trigger_static.
898 //
899 // Revision 1.4  2006/01/24 20:49:05  acg
900 // Andy Goodrich: changes to remove the use of deprecated features within the
901 // simulator, and to issue warning messages when deprecated features are used.
902 //
903 // Revision 1.3  2006/01/13 18:44:30  acg
904 // Added $Log to record CVS changes into the source.
905 
906 #endif // !defined(sc_process_h_INCLUDED)
907