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