SystemC  2.3.1
Accellera SystemC proof-of-concept library
sc_thread_process.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  The following code is derived, directly or indirectly, from the SystemC
4  source code Copyright (c) 1996-2014 by all Contributors.
5  All Rights reserved.
6 
7  The contents of this file are subject to the restrictions and limitations
8  set forth in the SystemC Open Source License (the "License");
9  You may not use this file except in compliance with such restrictions and
10  limitations. You may obtain instructions on how to receive a copy of the
11  License at http://www.accellera.org/. Software distributed by Contributors
12  under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
13  ANY KIND, either express or implied. See the License for the specific
14  language governing rights and limitations under the License.
15 
16  *****************************************************************************/
17 
18 /*****************************************************************************
19 
20  sc_thread_process.h -- Thread process declarations
21 
22  Original Author: Andy Goodrich, Forte Design Systems, 4 August 2005
23 
24 
25  CHANGE LOG AT THE END OF THE FILE
26  *****************************************************************************/
27 
28 
29 #if !defined(sc_thread_process_h_INCLUDED)
30 #define sc_thread_process_h_INCLUDED
31 
33 #include "sysc/kernel/sc_process.h"
34 #include "sysc/kernel/sc_cor.h"
35 #include "sysc/kernel/sc_event.h"
36 #include "sysc/kernel/sc_except.h"
37 #include "sysc/kernel/sc_reset.h"
38 
39 // DEBUGGING MACROS:
40 //
41 // DEBUG_MSG(NAME,P,MSG)
42 // MSG = message to print
43 // NAME = name that must match the process for the message to print, or
44 // null if the message should be printed unconditionally.
45 // P = pointer to process message is for, or NULL in which case the
46 // message will not print.
47 #if 0
48 # define DEBUG_NAME ""
49 # define DEBUG_MSG(NAME,P,MSG) \
50  { \
51  if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
52  std::cout << "**** " << sc_time_stamp() << " (" \
53  << sc_get_current_process_name() << "): " << MSG \
54  << " - " << P->name() << std::endl; \
55  }
56 #else
57 # define DEBUG_MSG(NAME,P,MSG)
58 #endif
59 
60 
61 namespace sc_core {
62 
63 // forward references:
64 class sc_event_and_list;
65 class sc_event_or_list;
66 class sc_reset;
67 void sc_thread_cor_fn( void* );
68 void sc_set_stack_size( sc_thread_handle, std::size_t );
69 class sc_event;
70 class sc_join;
71 class sc_module;
72 class sc_process_handle;
73 class sc_process_table;
74 class sc_simcontext;
75 class sc_runnable;
76 
77 sc_cor* get_cor_pointer( sc_process_b* process_p );
78 void sc_set_stack_size( sc_thread_handle thread_h, std::size_t size );
79 void wait( sc_simcontext* );
80 void wait( const sc_event&, sc_simcontext* );
81 void wait( const sc_event_or_list&, sc_simcontext* );
82 void wait( const sc_event_and_list&, sc_simcontext* );
83 void wait( const sc_time&, sc_simcontext* );
84 void wait( const sc_time&, const sc_event&, sc_simcontext* );
85 void wait( const sc_time&, const sc_event_or_list&, sc_simcontext* );
86 void wait( const sc_time&, const sc_event_and_list&, sc_simcontext* );
87 
88 //==============================================================================
89 // sc_thread_process -
90 //
91 //==============================================================================
93  friend void sc_thread_cor_fn( void* );
94  friend void sc_set_stack_size( sc_thread_handle, std::size_t );
95  friend class sc_event;
96  friend class sc_join;
97  friend class sc_module;
98  friend class sc_process_b;
99  friend class sc_process_handle;
100  friend class sc_process_table;
101  friend class sc_simcontext;
102  friend class sc_runnable;
103  friend sc_cor* get_cor_pointer( sc_process_b* process_p );
104 
105  friend void wait( sc_simcontext* );
106  friend void wait( const sc_event&, sc_simcontext* );
107  friend void wait( const sc_event_or_list&, sc_simcontext* );
108  friend void wait( const sc_event_and_list&, sc_simcontext* );
109  friend void wait( const sc_time&, sc_simcontext* );
110  friend void wait( const sc_time&, const sc_event&, sc_simcontext* );
111  friend void wait( const sc_time&, const sc_event_or_list&, sc_simcontext* );
112  friend void wait( const sc_time&, const sc_event_and_list&, sc_simcontext*);
113  public:
114  sc_thread_process( const char* name_p, bool free_host,
115  SC_ENTRY_FUNC method_p, sc_process_host* host_p,
116  const sc_spawn_options* opt_p );
117 
118  virtual const char* kind() const
119  { return "sc_thread_process"; }
120 
121  protected:
122  // may not be deleted manually (called from sc_process_b)
123  virtual ~sc_thread_process();
124 
125  virtual void disable_process(
127  virtual void enable_process(
129  virtual void kill_process(
133  virtual void prepare_for_simulation();
134  virtual void resume_process(
136  void set_next_exist( sc_thread_handle next_p );
137  void set_next_runnable( sc_thread_handle next_p );
138 
139  void set_stack_size( std::size_t size );
140  inline void suspend_me();
141  virtual void suspend_process(
143  virtual void throw_reset( bool async );
144  virtual void throw_user( const sc_throw_it_helper& helper,
146 
147  bool trigger_dynamic( sc_event* );
148  inline void trigger_static();
149 
150  void wait( const sc_event& );
151  void wait( const sc_event_or_list& );
152  void wait( const sc_event_and_list& );
153  void wait( const sc_time& );
154  void wait( const sc_time&, const sc_event& );
155  void wait( const sc_time&, const sc_event_or_list& );
156  void wait( const sc_time&, const sc_event_and_list& );
157  void wait_cycles( int n=1 );
158 
159  protected:
160  void add_monitor( sc_process_monitor* monitor_p );
161  void remove_monitor( sc_process_monitor* monitor_p);
162  void signal_monitors( int type = 0 );
163 
164  protected:
165  sc_cor* m_cor_p; // Thread's coroutine.
166  std::vector<sc_process_monitor*> m_monitor_q; // Thread monitors.
167  std::size_t m_stack_size; // Thread stack size.
168  int m_wait_cycle_n; // # of waits to be done.
169 
170  private: // disabled
172  const sc_thread_process& operator = ( const sc_thread_process& );
173 
174 };
175 
176 //------------------------------------------------------------------------------
177 //"sc_thread_process::set_stack_size"
178 //
179 //------------------------------------------------------------------------------
180 inline void sc_thread_process::set_stack_size( std::size_t size )
181 {
182  assert( size );
183  m_stack_size = size;
184 }
185 
186 //------------------------------------------------------------------------------
187 //"sc_thread_process::suspend_me"
188 //
189 // This method suspends this object instance in favor of the next runnable
190 // process. Upon awakening we check to see if an exception should be thrown.
191 // There are two types of exceptions that can be thrown, synchronous reset
192 // and asynchronous reset. At a future time there may be more asynchronous
193 // exceptions. If an asynchronous reset is seen and there is not static reset
194 // specified, or the static reset is not active then clear the throw
195 // type for the next time this method is called.
196 //
197 // Notes:
198 // (1) For an explanation of how the reset mechanism works see the top of
199 // the file sc_reset.cpp.
200 // (2) The m_sticky_reset field is used to handle synchronous resets that
201 // are enabled via the sc_process_handle::sync_reset_on() method. These
202 // resets are not generated by a signal, but rather are modal by
203 // method call: sync_reset_on() - sync_reset_off().
204 //------------------------------------------------------------------------------
206 {
207  // remember, if we're currently unwinding
208 
209  bool unwinding_preempted = m_unwinding;
210 
211  sc_simcontext* simc_p = simcontext();
212  sc_cor* cor_p = simc_p->next_cor();
213 
214  // do not switch, if we're about to execute next (e.g. suicide)
215 
216  if( m_cor_p != cor_p )
217  {
218  DEBUG_MSG( DEBUG_NAME , this, "suspending thread");
219  simc_p->cor_pkg()->yield( cor_p );
220  DEBUG_MSG( DEBUG_NAME , this, "resuming thread");
221  }
222 
223  // IF THERE IS A THROW TO BE DONE FOR THIS PROCESS DO IT NOW:
224  //
225  // (1) Optimize THROW_NONE for speed as it is the normal case.
226  // (2) If this thread is already unwinding then suspend_me() was
227  // called from the catch clause to throw an exception on another
228  // process, so just go back to the catch clause.
229 
230  if ( m_throw_status == THROW_NONE ) return;
231 
232  if ( m_unwinding ) return;
233 
234  switch( m_throw_status )
235  {
236  case THROW_ASYNC_RESET:
237  case THROW_SYNC_RESET:
238  DEBUG_MSG( DEBUG_NAME , this, "throwing reset for");
240  throw sc_unwind_exception( this, true );
241 
242  case THROW_USER:
243  DEBUG_MSG( DEBUG_NAME, this, "invoking throw_it for");
246  THROW_NONE);
248  break;
249 
250  case THROW_KILL:
251  DEBUG_MSG( DEBUG_NAME, this, "throwing kill for");
252  throw sc_unwind_exception( this, false );
253 
254  default: // THROWING_NOW
255  sc_assert( unwinding_preempted );
256  DEBUG_MSG( DEBUG_NAME, this, "restarting thread");
257  break;
258  }
259 }
260 
261 
262 //------------------------------------------------------------------------------
263 //"sc_thread_process::wait"
264 //
265 //------------------------------------------------------------------------------
266 inline
267 void
269 {
270  if( m_unwinding )
271  SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
272 
273  m_event_p = &e; // for cleanup.
274  e.add_dynamic( this );
276  suspend_me();
277 }
278 
279 inline
280 void
282 {
283  if( m_unwinding )
284  SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
285 
286  el.add_dynamic( this );
287  m_event_list_p = &el;
289  suspend_me();
290 }
291 
292 inline
293 void
295 {
296  if( m_unwinding )
297  SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
298 
299  el.add_dynamic( this );
300  m_event_list_p = &el;
301  m_event_count = el.size();
303  suspend_me();
304 }
305 
306 inline
307 void
309 {
310  if( m_unwinding )
311  SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
312 
313  m_timeout_event_p->notify_internal( t );
314  m_timeout_event_p->add_dynamic( this );
316  suspend_me();
317 }
318 
319 inline
320 void
322 {
323  if( m_unwinding )
324  SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
325 
326  m_timeout_event_p->notify_internal( t );
327  m_timeout_event_p->add_dynamic( this );
328  e.add_dynamic( this );
329  m_event_p = &e;
331  suspend_me();
332 }
333 
334 inline
335 void
337 {
338  if( m_unwinding )
339  SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
340 
341  m_timeout_event_p->notify_internal( t );
342  m_timeout_event_p->add_dynamic( this );
343  el.add_dynamic( this );
344  m_event_list_p = &el;
346  suspend_me();
347 }
348 
349 inline
350 void
352 {
353  if( m_unwinding )
354  SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
355 
356  m_timeout_event_p->notify_internal( t );
357  m_timeout_event_p->add_dynamic( this );
358  el.add_dynamic( this );
359  m_event_list_p = &el;
360  m_event_count = el.size();
362  suspend_me();
363 }
364 
365 //------------------------------------------------------------------------------
366 //"sc_thread_process::wait_cycles"
367 //
368 // This method suspends this object instance for the specified number of cycles.
369 // A cycle is defined as the event the thread is set up to staticly wait on.
370 // The field m_wait_cycle_n is set to one less than the number of cycles to
371 // be waited for, since the value is tested before being decremented in
372 // the simulation kernel.
373 //------------------------------------------------------------------------------
374 inline
375 void
377 {
378  if( m_unwinding )
379  SC_REPORT_ERROR( SC_ID_WAIT_DURING_UNWINDING_, name() );
380 
381  m_wait_cycle_n = n-1;
382  suspend_me();
383 }
384 
385 //------------------------------------------------------------------------------
386 //"sc_thread_process::miscellaneous support"
387 //
388 //------------------------------------------------------------------------------
389 inline
391 {
392  m_monitor_q.push_back(monitor_p);
393 }
394 
395 
396 inline
398 {
399  int mon_n = m_monitor_q.size();
400 
401  for ( int mon_i = 0; mon_i < mon_n; mon_i++ )
402  {
403  if ( m_monitor_q[mon_i] == monitor_p )
404  {
405  m_monitor_q[mon_i] = m_monitor_q[mon_n-1];
406  m_monitor_q.resize(mon_n-1);
407  }
408  }
409 }
410 
411 inline
413 {
414  m_exist_p = next_p;
415 }
416 
417 inline
419 {
420  return (sc_thread_handle)m_exist_p;
421 }
422 
423 inline
425 {
426  m_runnable_p = next_p;
427 }
428 
429 inline
431 {
433 }
434 
435 inline sc_cor* get_cor_pointer( sc_process_b* process_p )
436 {
437  sc_thread_handle thread_p = DCAST<sc_thread_handle>(process_p);
438  return thread_p->m_cor_p;
439 }
440 
441 //------------------------------------------------------------------------------
442 //"sc_thread_process::trigger_static"
443 //
444 // This inline method adds the current thread to the queue of runnable
445 // processes, if required. This is the case if the following criteria
446 // are met:
447 // (1) The process is in a runnable state.
448 // (2) The process is not already on the run queue.
449 // (3) The process is expecting a static trigger,
450 // dynamic event waits take priority.
451 // (4) The process' static wait count is zero.
452 //
453 // If the triggering process is the same process, the trigger is
454 // ignored as well, unless SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
455 // is defined.
456 //------------------------------------------------------------------------------
457 inline
458 void
460 {
461  // No need to try queueing this thread if one of the following is true:
462  // (a) its disabled
463  // (b) its already queued for execution
464  // (c) its waiting on a dynamic event
465  // (d) its wait count is not satisfied
466 
467  if ( (m_state & ps_bit_disabled) || is_runnable() ||
469  return;
470 
471 #if ! defined( SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS )
472  if( SC_UNLIKELY_( sc_get_current_process_b() == this ) )
473  {
475  return;
476  }
477 #endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
478 
479  if ( m_wait_cycle_n > 0 )
480  {
481  --m_wait_cycle_n;
482  return;
483  }
484 
485  // If we get here then the thread is has satisfied its wait criteria, if
486  // its suspended mark its state as ready to run. If its not suspended then
487  // push it onto the runnable queue.
488 
489  if ( m_state & ps_bit_suspended )
490  {
492  }
493  else
494  {
495  simcontext()->push_runnable_thread(this);
496  }
497 }
498 
499 #undef DEBUG_MSG
500 #undef DEBUG_NAME
501 
502 } // namespace sc_core
503 
504 // $Log: sc_thread_process.h,v $
505 // Revision 1.30 2011/08/26 20:46:11 acg
506 // Andy Goodrich: moved the modification log to the end of the file to
507 // eliminate source line number skew when check-ins are done.
508 //
509 // Revision 1.29 2011/08/24 23:36:12 acg
510 // Andy Goodrich: removed break statements that can never be reached and
511 // which causes warnings in the Greenhills C++ compiler.
512 //
513 // Revision 1.28 2011/04/14 22:34:27 acg
514 // Andy Goodrich: removed dead code.
515 //
516 // Revision 1.27 2011/04/13 05:02:18 acg
517 // Andy Goodrich: added missing check to the wake up code in suspend_me()
518 // so that we just return if the call to suspend_me() was issued from a
519 // stack unwinding.
520 //
521 // Revision 1.26 2011/04/13 02:44:26 acg
522 // Andy Goodrich: added m_unwinding flag in place of THROW_NOW because the
523 // throw status will be set back to THROW_*_RESET if reset is active and
524 // the check for an unwind being complete was expecting THROW_NONE as the
525 // clearing of THROW_NOW.
526 //
527 // Revision 1.25 2011/04/11 22:05:14 acg
528 // Andy Goodrich: use the DEBUG_NAME macro in DEBUG_MSG invocations.
529 //
530 // Revision 1.24 2011/04/10 22:12:32 acg
531 // Andy Goodrich: adding debugging macros.
532 //
533 // Revision 1.23 2011/04/08 22:41:28 acg
534 // Andy Goodrich: added comment pointing to the description of the reset
535 // mechanism in sc_reset.cpp.
536 //
537 // Revision 1.22 2011/04/08 18:27:33 acg
538 // Andy Goodrich: added check to make sure we don't schedule a running process
539 // because of it issues a notify() it is sensitive to.
540 //
541 // Revision 1.21 2011/04/05 06:22:38 acg
542 // Andy Goodrich: expanded comment for trigger_static() initial vetting.
543 //
544 // Revision 1.20 2011/04/01 21:24:57 acg
545 // Andy Goodrich: removed unused code.
546 //
547 // Revision 1.19 2011/02/19 08:30:53 acg
548 // Andy Goodrich: Moved process queueing into trigger_static from
549 // sc_event::notify.
550 //
551 // Revision 1.18 2011/02/18 20:27:14 acg
552 // Andy Goodrich: Updated Copyrights.
553 //
554 // Revision 1.17 2011/02/17 19:55:58 acg
555 // Andy Goodrich:
556 // (1) Changed signature of trigger_dynamic() back to a bool.
557 // (2) Simplified process control usage.
558 // (3) Changed trigger_static() to recognize process controls and to
559 // do the down-count on wait(N), allowing the elimination of
560 // ready_to_run().
561 //
562 // Revision 1.16 2011/02/16 22:37:31 acg
563 // Andy Goodrich: clean up to remove need for ps_disable_pending.
564 //
565 // Revision 1.15 2011/02/13 21:47:38 acg
566 // Andy Goodrich: update copyright notice.
567 //
568 // Revision 1.14 2011/02/13 21:35:54 acg
569 // Andy Goodrich: added error for performing a wait() during unwinding.
570 //
571 // Revision 1.13 2011/02/11 13:25:24 acg
572 // Andy Goodrich: Philipp A. Hartmann's changes:
573 // (1) Removal of SC_CTHREAD method overloads.
574 // (2) New exception processing code.
575 //
576 // Revision 1.12 2011/02/01 23:01:53 acg
577 // Andy Goodrich: removed dead code.
578 //
579 // Revision 1.11 2011/02/01 21:18:01 acg
580 // Andy Goodrich:
581 // (1) Changes in throw processing for new process control rules.
582 // (2) Support of new process_state enum values.
583 //
584 // Revision 1.10 2011/01/25 20:50:37 acg
585 // Andy Goodrich: changes for IEEE 1666 2011.
586 //
587 // Revision 1.9 2011/01/19 23:21:50 acg
588 // Andy Goodrich: changes for IEEE 1666 2011
589 //
590 // Revision 1.8 2011/01/18 20:10:45 acg
591 // Andy Goodrich: changes for IEEE1666_2011 semantics.
592 //
593 // Revision 1.7 2011/01/06 17:59:58 acg
594 // Andy Goodrich: removed debugging output.
595 //
596 // Revision 1.6 2010/07/22 20:02:33 acg
597 // Andy Goodrich: bug fixes.
598 //
599 // Revision 1.5 2009/07/28 01:10:53 acg
600 // Andy Goodrich: updates for 2.3 release candidate.
601 //
602 // Revision 1.4 2009/05/22 16:06:29 acg
603 // Andy Goodrich: process control updates.
604 //
605 // Revision 1.3 2009/03/12 22:59:58 acg
606 // Andy Goodrich: updates for 2.4 stuff.
607 //
608 // Revision 1.2 2008/05/22 17:06:06 acg
609 // Andy Goodrich: formatting and comments.
610 //
611 // Revision 1.1.1.1 2006/12/15 20:20:05 acg
612 // SystemC 2.3
613 //
614 // Revision 1.7 2006/05/08 17:57:13 acg
615 // Andy Goodrich: Added David Long's forward declarations for friend functions
616 // to keep the Microsoft C++ compiler happy.
617 //
618 // Revision 1.6 2006/04/20 17:08:17 acg
619 // Andy Goodrich: 3.0 style process changes.
620 //
621 // Revision 1.5 2006/04/11 23:13:21 acg
622 // Andy Goodrich: Changes for reduced reset support that only includes
623 // sc_cthread, but has preliminary hooks for expanding to method and thread
624 // processes also.
625 //
626 // Revision 1.4 2006/01/24 20:49:05 acg
627 // Andy Goodrich: changes to remove the use of deprecated features within the
628 // simulator, and to issue warning messages when deprecated features are used.
629 //
630 // Revision 1.3 2006/01/13 18:44:30 acg
631 // Added $Log to record CVS changes into the source.
632 
633 #endif // !defined(sc_thread_process_h_INCLUDED)
virtual void enable_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
virtual void throw_user(const sc_throw_it_helper &helper, sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
const char * name() const
Definition: sc_object.h:67
friend sc_cor * get_cor_pointer(sc_process_b *process_p)
friend class sc_unwind_exception
Definition: sc_process.h:284
void wait(int, sc_simcontext *)
const sc_event * m_event_p
Definition: sc_process.h:414
virtual void throw_it()=0
void add_monitor(sc_process_monitor *monitor_p)
#define sc_assert(expr)
Definition: sc_report.h:235
sc_thread_handle next_runnable()
virtual void throw_reset(bool async)
sc_cor_pkg * cor_pkg()
friend void wait(sc_simcontext *)
sc_thread_handle next_exist()
virtual void suspend_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
void(sc_process_host::* SC_ENTRY_FUNC)()
Definition: sc_process.h:142
friend void sc_thread_cor_fn(void *)
virtual void kill_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
sc_process_b sc_process_b
Definition: sc_process.h:447
virtual void resume_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
sc_process_b * sc_get_current_process_b()
sc_process_b * m_runnable_p
Definition: sc_process.h:429
class sc_thread_process * sc_thread_handle
Definition: sc_process.h:58
const sc_event_list * m_event_list_p
Definition: sc_process.h:416
sc_event * m_timeout_event_p
Definition: sc_process.h:439
void report_immediate_self_notification() const
virtual void prepare_for_simulation()
void sc_set_stack_size(sc_method_handle, std::size_t)
friend void sc_set_stack_size(sc_thread_handle, std::size_t)
#define SC_UNLIKELY_(x)
Definition: sc_cmnhdr.h:85
virtual const char * kind() const
#define DEBUG_MSG(NAME, P, MSG)
sc_throw_it_helper * m_throw_helper_p
Definition: sc_process.h:436
void add_dynamic(sc_method_handle) const
void signal_monitors(int type=0)
sc_descendant_inclusion_info
Definition: sc_process.h:73
void sc_thread_cor_fn(void *arg)
void set_stack_size(std::size_t size)
int size() const
Definition: sc_event.h:546
#define SC_REPORT_ERROR(msg_type, msg)
Definition: sc_report.h:213
bool is_runnable() const
Definition: sc_process.h:515
bool trigger_dynamic(sc_event *)
virtual void yield(sc_cor *next_cor)=0
sc_simcontext * simcontext() const
Definition: sc_object.h:81
sc_thread_process(const char *name_p, bool free_host, SC_ENTRY_FUNC method_p, sc_process_host *host_p, const sc_spawn_options *opt_p)
void remove_monitor(sc_process_monitor *monitor_p)
void set_next_runnable(sc_thread_handle next_p)
process_throw_type m_throw_status
Definition: sc_process.h:437
sc_event * m_reset_event_p
Definition: sc_process.h:427
trigger_t m_trigger_type
Definition: sc_process.h:440
virtual void disable_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
void set_next_exist(sc_thread_handle next_p)
std::vector< sc_process_monitor * > m_monitor_q
sc_cor * get_cor_pointer(sc_process_b *process_p)
sc_process_b * m_exist_p
Definition: sc_process.h:417