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