SystemC  2.3.1
Accellera SystemC proof-of-concept library
sc_method_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_method_process.h -- Method 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 // $Log: sc_method_process.h,v $
29 // Revision 1.23 2011/09/05 21:20:22 acg
30 // Andy Goodrich: result of automake invocation.
31 //
32 // Revision 1.22 2011/08/29 18:04:32 acg
33 // Philipp A. Hartmann: miscellaneous clean ups.
34 //
35 // Revision 1.21 2011/08/26 20:46:10 acg
36 // Andy Goodrich: moved the modification log to the end of the file to
37 // eliminate source line number skew when check-ins are done.
38 //
39 
40 #if !defined(sc_method_process_h_INCLUDED)
41 #define sc_method_process_h_INCLUDED
42 
43 #include "sysc/kernel/sc_process.h"
45 #include "sysc/kernel/sc_cor.h"
46 #include "sysc/kernel/sc_event.h"
47 #include "sysc/kernel/sc_except.h"
48 
49 
50 // DEBUGGING MACROS:
51 //
52 // DEBUG_MSG(NAME,P,MSG)
53 // MSG = message to print
54 // NAME = name that must match the process for the message to print, or
55 // null if the message should be printed unconditionally.
56 // P = pointer to process message is for, or NULL in which case the
57 // message will not print.
58 #if 0
59 # define DEBUG_NAME ""
60 # define DEBUG_MSG(NAME,P,MSG) \
61  { \
62  if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
63  std::cout << "**** " << sc_time_stamp() << " (" \
64  << sc_get_current_process_name() << "): " << MSG \
65  << " - " << P->name() << std::endl; \
66  }
67 #else
68 # define DEBUG_MSG(NAME,P,MSG)
69 #endif
70 
71 
72 namespace sc_core {
73 
74 // forward function and class declarations:
75 
76 void sc_method_cor_fn( void* );
77 void sc_cmethod_cor_fn( void* );
78 void sc_set_stack_size( sc_method_handle, std::size_t );
79 class sc_event;
80 class sc_module;
81 class sc_process_table;
82 class sc_process_handle;
83 class sc_simcontext;
84 class sc_runnable;
85 
86 void next_trigger( sc_simcontext* );
87 void next_trigger( const sc_event&, sc_simcontext* );
88 void next_trigger( const sc_event_or_list&, sc_simcontext* );
89 void next_trigger( const sc_event_and_list&, sc_simcontext* );
90 void next_trigger( const sc_time&, sc_simcontext* );
91 void next_trigger( const sc_time&, const sc_event&, sc_simcontext* );
92 void next_trigger( const sc_time&, const sc_event_or_list&, sc_simcontext* );
93 void next_trigger( const sc_time&, const sc_event_and_list&, sc_simcontext* );
94 
95 struct sc_invoke_method;
96 //==============================================================================
97 // sc_method_process -
98 //
99 //==============================================================================
101  friend struct sc_invoke_method;
102  friend void sc_method_cor_fn( void* );
103  friend void sc_cmethod_cor_fn( void* );
104  friend void sc_set_stack_size( sc_method_handle, std::size_t );
105  friend class sc_event;
106  friend class sc_module;
107  friend class sc_process_table;
108  friend class sc_process_handle;
109  friend class sc_simcontext;
110  friend class sc_runnable;
111 
112  friend void next_trigger( sc_simcontext* );
113  friend void next_trigger( const sc_event&,
114  sc_simcontext* );
115  friend void next_trigger( const sc_event_or_list&,
116  sc_simcontext* );
117  friend void next_trigger( const sc_event_and_list&,
118  sc_simcontext* );
119  friend void next_trigger( const sc_time&,
120  sc_simcontext* );
121  friend void next_trigger( const sc_time&, const sc_event&,
122  sc_simcontext* );
123  friend void next_trigger( const sc_time&, const sc_event_or_list&,
124  sc_simcontext* );
125  friend void next_trigger( const sc_time&, const sc_event_and_list&,
126  sc_simcontext* );
127 
128  public:
129  sc_method_process( const char* name_p, bool free_host,
130  SC_ENTRY_FUNC method_p, sc_process_host* host_p,
131  const sc_spawn_options* opt_p );
132 
133  virtual const char* kind() const
134  { return "sc_method_process"; }
135 
136  protected:
137  void check_for_throws();
138  virtual void disable_process(
140  virtual void enable_process(
142  inline bool run_process();
143  virtual void kill_process(
147  void clear_trigger();
148  void next_trigger( const sc_event& );
149  void next_trigger( const sc_event_or_list& );
150  void next_trigger( const sc_event_and_list& );
151  void next_trigger( const sc_time& );
152  void next_trigger( const sc_time&, const sc_event& );
153  void next_trigger( const sc_time&, const sc_event_or_list& );
154  void next_trigger( const sc_time&, const sc_event_and_list& );
155  virtual void resume_process(
157  void set_next_exist( sc_method_handle next_p );
158  void set_next_runnable( sc_method_handle next_p );
159  void set_stack_size( std::size_t size );
160  virtual void suspend_process(
162  virtual void throw_reset( bool async );
163  virtual void throw_user( const sc_throw_it_helper& helper,
165  bool trigger_dynamic( sc_event* );
166  inline void trigger_static();
167 
168  protected:
169  sc_cor* m_cor; // Thread's coroutine.
170  std::size_t m_stack_size; // Thread stack size.
171  std::vector<sc_process_monitor*> m_monitor_q; // Thread monitors.
172 
173  private:
174  // may not be deleted manually (called from sc_process_b)
175  virtual ~sc_method_process();
176 
177  private: // disabled
179  const sc_method_process& operator = ( const sc_method_process& );
180 
181 };
182 
183 inline
184 void
186 {
187  clear_trigger();
188  e.add_dynamic( this );
189  m_event_p = &e;
191 }
192 
193 inline
194 void
196 {
197  clear_trigger();
198  el.add_dynamic( this );
199  m_event_list_p = &el;
201 }
202 
203 inline
204 void
206 {
207  clear_trigger();
208  el.add_dynamic( this );
209  m_event_list_p = &el;
210  m_event_count = el.size();
212 }
213 
214 inline
215 void
217 {
218  clear_trigger();
219  m_timeout_event_p->notify_internal( t );
220  m_timeout_event_p->add_dynamic( this );
222 }
223 
224 inline
225 void
227 {
228  clear_trigger();
229  m_timeout_event_p->notify_internal( t );
230  m_timeout_event_p->add_dynamic( this );
231  e.add_dynamic( this );
232  m_event_p = &e;
234 }
235 
236 inline
237 void
239 {
240  clear_trigger();
241  m_timeout_event_p->notify_internal( t );
242  m_timeout_event_p->add_dynamic( this );
243  el.add_dynamic( this );
244  m_event_list_p = &el;
246 }
247 
248 inline
249 void
251 {
252  clear_trigger();
253  m_timeout_event_p->notify_internal( t );
254  m_timeout_event_p->add_dynamic( this );
255  el.add_dynamic( this );
256  m_event_list_p = &el;
257  m_event_count = el.size();
259 }
260 
261 inline
263 {
264  m_exist_p = next_p;
265 }
266 
267 inline
269 {
270  return (sc_method_handle)m_exist_p;
271 }
272 
273 
274 inline
276 {
277  m_runnable_p = next_p;
278 }
279 
280 inline
282 {
284 }
285 
286 // +----------------------------------------------------------------------------
287 // |"sc_method_process::run_process"
288 // |
289 // | This method executes this object instance, including fielding exceptions.
290 // |
291 // | Result is false if an unfielded exception occurred, true if not.
292 // +----------------------------------------------------------------------------
294 {
295  // Execute this object instance's semantics and catch any exceptions that
296  // are generated:
297 
298  bool restart = false;
299  do {
300  try {
301  DEBUG_MSG(DEBUG_NAME,this,"executing method semantics");
302  semantics();
303  restart = false;
304  }
305  catch( sc_unwind_exception& ex ) {
306  DEBUG_MSG(DEBUG_NAME,this,"caught unwind exception");
307  ex.clear();
308  restart = ex.is_reset();
309  }
310  catch( ... ) {
311  sc_report* err_p = sc_handle_exception();
312  simcontext()->set_error( err_p );
313  return false;
314  }
315  } while( restart );
316 
317  return true;
318 }
319 
320 //------------------------------------------------------------------------------
321 //"sc_method_process::trigger_static"
322 //
323 // This inline method adds the current method to the queue of runnable
324 // processes, if required. This is the case if the following criteria
325 // are met:
326 // (1) The process is in a runnable state.
327 // (2) The process is not already on the run queue.
328 // (3) The process is expecting a static trigger,
329 // dynamic event waits take priority.
330 //
331 //
332 // If the triggering process is the same process, the trigger is
333 // ignored as well, unless SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
334 // is defined.
335 //------------------------------------------------------------------------------
336 inline
337 void
339 {
340  if ( (m_state & ps_bit_disabled) || is_runnable() ||
342  return;
343 
344 #if ! defined( SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS )
345  if( SC_UNLIKELY_( sc_get_current_process_b() == this ) )
346  {
348  return;
349  }
350 #endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
351 
352  // If we get here then the method is has satisfied its wait, if its
353  // suspended mark its state as ready to run. If its not suspended then
354  // push it onto the runnable queue.
355 
356  if ( m_state & ps_bit_suspended )
357  {
359  }
360  else
361  {
362  simcontext()->push_runnable_method(this);
363  }
364 }
365 
366 #undef DEBUG_MSG
367 
368 } // namespace sc_core
369 
370 // Revision 1.20 2011/08/24 22:05:50 acg
371 // Torsten Maehne: initialization changes to remove warnings.
372 //
373 // Revision 1.19 2011/07/29 22:43:15 acg
374 // Andy Goodrich: addition of check_for_throws() method.
375 //
376 // Revision 1.18 2011/07/24 11:18:09 acg
377 // Philipp A. Hartmann: add code to restart a method process after a
378 // self-reset.
379 //
380 // Revision 1.17 2011/05/09 04:07:48 acg
381 // Philipp A. Hartmann:
382 // (1) Restore hierarchy in all phase callbacks.
383 // (2) Ensure calls to before_end_of_elaboration.
384 //
385 // Revision 1.16 2011/04/13 02:41:34 acg
386 // Andy Goodrich: eliminate warning messages generated when the DEBUG_MSG
387 // macro is used.
388 //
389 // Revision 1.15 2011/04/10 22:12:32 acg
390 // Andy Goodrich: adding debugging macros.
391 //
392 // Revision 1.14 2011/04/08 22:31:21 acg
393 // Andy Goodrich: added new inline method run_process() to hide the process
394 // implementation for sc_simcontext.
395 //
396 // Revision 1.13 2011/04/05 20:50:56 acg
397 // Andy Goodrich:
398 // (1) changes to make sure that event(), posedge() and negedge() only
399 // return true if the clock has not moved.
400 // (2) fixes for method self-resumes.
401 // (3) added SC_PRERELEASE_VERSION
402 // (4) removed kernel events from the object hierarchy, added
403 // sc_hierarchy_name_exists().
404 //
405 // Revision 1.12 2011/04/01 21:24:57 acg
406 // Andy Goodrich: removed unused code.
407 //
408 // Revision 1.11 2011/02/19 08:30:53 acg
409 // Andy Goodrich: Moved process queueing into trigger_static from
410 // sc_event::notify.
411 //
412 // Revision 1.10 2011/02/18 20:27:14 acg
413 // Andy Goodrich: Updated Copyrights.
414 //
415 // Revision 1.9 2011/02/17 19:51:34 acg
416 // Andy Goodrich:
417 // (1) Changed the signature of trigger_dynamic back to a bool.
418 // (2) Removed ready_to_run().
419 // (3) Simplified process control usage.
420 //
421 // Revision 1.8 2011/02/16 22:37:30 acg
422 // Andy Goodrich: clean up to remove need for ps_disable_pending.
423 //
424 // Revision 1.7 2011/02/13 21:47:37 acg
425 // Andy Goodrich: update copyright notice.
426 //
427 // Revision 1.6 2011/02/01 21:05:05 acg
428 // Andy Goodrich: Changes in trigger_dynamic methods to handle new
429 // process control rules about event sensitivity.
430 //
431 // Revision 1.5 2011/01/18 20:10:44 acg
432 // Andy Goodrich: changes for IEEE1666_2011 semantics.
433 //
434 // Revision 1.4 2009/07/28 01:10:53 acg
435 // Andy Goodrich: updates for 2.3 release candidate.
436 //
437 // Revision 1.3 2009/05/22 16:06:29 acg
438 // Andy Goodrich: process control updates.
439 //
440 // Revision 1.2 2008/05/22 17:06:25 acg
441 // Andy Goodrich: updated copyright notice to include 2008.
442 //
443 // Revision 1.1.1.1 2006/12/15 20:20:05 acg
444 // SystemC 2.3
445 //
446 // Revision 1.7 2006/05/08 17:57:13 acg
447 // Andy Goodrich: Added David Long's forward declarations for friend functions
448 // to keep the Microsoft C++ compiler happy.
449 //
450 // Revision 1.6 2006/04/20 17:08:17 acg
451 // Andy Goodrich: 3.0 style process changes.
452 //
453 // Revision 1.5 2006/04/11 23:13:21 acg
454 // Andy Goodrich: Changes for reduced reset support that only includes
455 // sc_cthread, but has preliminary hooks for expanding to method and thread
456 // processes also.
457 //
458 // Revision 1.4 2006/01/24 20:49:05 acg
459 // Andy Goodrich: changes to remove the use of deprecated features within the
460 // simulator, and to issue warning messages when deprecated features are used.
461 //
462 // Revision 1.3 2006/01/13 18:44:29 acg
463 // Added $Log to record CVS changes into the source.
464 
465 #endif // !defined(sc_method_process_h_INCLUDED)
const sc_event * m_event_p
Definition: sc_process.h:414
virtual void suspend_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
virtual void kill_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
virtual bool is_reset() const
Definition: sc_except.h:77
void set_stack_size(std::size_t size)
void set_next_runnable(sc_method_handle next_p)
void set_next_exist(sc_method_handle next_p)
friend void sc_cmethod_cor_fn(void *)
void(sc_process_host::* SC_ENTRY_FUNC)()
Definition: sc_process.h:142
sc_method_handle next_runnable()
#define DEBUG_MSG(NAME, P, MSG)
void set_error(sc_report *)
sc_process_b * sc_get_current_process_b()
friend void next_trigger(sc_simcontext *)
sc_process_b * m_runnable_p
Definition: sc_process.h:429
friend void sc_set_stack_size(sc_method_handle, std::size_t)
const sc_event_list * m_event_list_p
Definition: sc_process.h:416
sc_event * m_timeout_event_p
Definition: sc_process.h:439
friend void sc_method_cor_fn(void *)
virtual void throw_reset(bool async)
void report_immediate_self_notification() const
virtual void enable_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
void sc_set_stack_size(sc_method_handle, std::size_t)
std::vector< sc_process_monitor * > m_monitor_q
#define SC_UNLIKELY_(x)
Definition: sc_cmnhdr.h:85
bool trigger_dynamic(sc_event *)
void add_dynamic(sc_method_handle) const
virtual void resume_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
void sc_method_cor_fn(void *)
sc_descendant_inclusion_info
Definition: sc_process.h:73
void sc_cmethod_cor_fn(void *)
int size() const
Definition: sc_event.h:546
void next_trigger(sc_simcontext *)
bool is_runnable() const
Definition: sc_process.h:515
class sc_method_process * sc_method_handle
Definition: sc_process.h:57
sc_simcontext * simcontext() const
Definition: sc_object.h:81
virtual void throw_user(const sc_throw_it_helper &helper, sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
virtual const char * kind() const
virtual void disable_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
trigger_t m_trigger_type
Definition: sc_process.h:440
sc_method_process(const char *name_p, bool free_host, SC_ENTRY_FUNC method_p, sc_process_host *host_p, const sc_spawn_options *opt_p)
sc_method_handle next_exist()
sc_report * sc_handle_exception()
sc_process_b * m_exist_p
Definition: sc_process.h:417