SystemC  2.3.1
Accellera SystemC proof-of-concept library
sc_process_handle.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_process_handle.h -- Process access support.
21 
22  Original Author: Andy Goodrich, Forte Design Systems, 17 June 2003
23 
24 
25  CHANGE LOG AT THE END OF THE FILE
26  *****************************************************************************/
27 
28 // $Log: sc_process_handle.h,v $
29 // Revision 1.21 2011/08/26 21:54:04 acg
30 // Torsten Maehne: Simplify use of dynamic_cast<> for initializing m_target.
31 //
32 // Revision 1.20 2011/08/26 20:46:10 acg
33 // Andy Goodrich: moved the modification log to the end of the file to
34 // eliminate source line number skew when check-ins are done.
35 //
36 
37 #if !defined(sc_process_handle_h_INCLUDED)
38 #define sc_process_handle_h_INCLUDED
39 
40 #include "sysc/kernel/sc_module.h"
41 
42 namespace sc_core {
43 
44 // forward operator declarations:
45 
46 class sc_process_handle;
47 bool
48 operator == ( const sc_process_handle& left, const sc_process_handle& right );
49 bool
50 operator != ( const sc_process_handle& left, const sc_process_handle& right );
51 bool
52 operator < ( const sc_process_handle& left, const sc_process_handle& right );
53 
54 
55 
56 //=============================================================================
57 // CLASS sc_process_handle
58 //
59 // This class provides access to an sc_process_b object instance in a
60 // manner which allows some persistence after the deletion of the actual
61 // process.
62 //=============================================================================
63 class sc_simcontext;
66 
67  friend bool operator == ( const this_type& left, const this_type& right );
68  friend bool operator != ( const this_type& left, const this_type& right );
69  friend bool operator < ( const this_type& left, const this_type& right );
70  friend class sc_object;
71  friend class sc_join;
72  friend class sc_module;
73  friend class sc_reset;
74  friend class sc_sensitive;
75  friend class sc_sensitive_pos;
76  friend class sc_sensitive_neg;
77  friend class sc_thread_process;
78 
79  public:
80  inline sc_process_handle();
81  inline explicit sc_process_handle( sc_object* object_p );
82  inline explicit sc_process_handle( sc_process_b* process_p );
83  inline sc_process_handle( const sc_process_handle& orig );
84  inline ~sc_process_handle();
86  inline void swap( sc_process_handle& other );
87 
88  public:
89  inline void disable(
91  inline bool dynamic() const;
92  inline void enable(
94  inline const std::vector<sc_event*>& get_child_events() const;
95  inline const std::vector<sc_object*>& get_child_objects() const;
96  inline sc_object* get_parent_object() const;
97  inline sc_object* get_process_object() const;
98  inline bool is_unwinding() const;
99  inline void kill(
101  inline const char* name() const;
102  inline sc_curr_proc_kind proc_kind() const;
103  inline void reset(
105  inline sc_event& reset_event() const;
106  inline void resume(
108  inline void suspend(
110  inline void sync_reset_off(
112  inline void sync_reset_on(
114  inline sc_event& terminated_event();
115  inline bool terminated() const;
116  template<typename EXCEPT>
117  inline void throw_it( const EXCEPT& exception,
119  inline bool valid() const;
120 
121  public: // implementation specific methods:
122  inline std::string dump_state() const;
123 
124  protected:
125  inline bool dont_initialize() const
126  { return m_target_p ? m_target_p->dont_initialize() : false; }
127  inline void dont_initialize( bool dont );
128 
129  public:
130  operator sc_process_b* ()
131  { return m_target_p; }
132  operator sc_cthread_handle ();
133  operator sc_method_handle ();
134  operator sc_thread_handle ();
135 
136  protected:
137  sc_process_b* m_target_p; // Target for this object instance.
138 
139  protected:
140  static std::vector<sc_event*> empty_event_vector; // If m_target_p == 0.
141  static std::vector<sc_object*> empty_object_vector; // If m_target_p == 0.
142  static sc_event non_event; // If m_target_p == 0.
143 };
144 
145 inline bool operator == (
146  const sc_process_handle& left, const sc_process_handle& right )
147 {
148  return (left.m_target_p != 0) && (right.m_target_p != 0) &&
149  (left.m_target_p == right.m_target_p);
150 }
151 
152 inline bool operator != (
153  const sc_process_handle& left, const sc_process_handle& right )
154 {
155  return (left.m_target_p == 0) || (right.m_target_p == 0) ||
156  (left.m_target_p != right.m_target_p);
157 }
158 
159 inline bool operator < (
160  const sc_process_handle& left, const sc_process_handle& right )
161 {
162  return left.m_target_p < right.m_target_p;
163 }
164 
165 //------------------------------------------------------------------------------
166 //"sc_process_handle::sc_process_handle - non-pointer constructor"
167 //
168 // This version of the object instance constructor for this class creates
169 // an object instance whose target needs to be supplied via an assignment.
170 //------------------------------------------------------------------------------
171 inline sc_process_handle::sc_process_handle() : m_target_p(0)
172 {
173 }
174 
175 //------------------------------------------------------------------------------
176 //"sc_process_handle::sc_process_handle - pointer constructor"
177 //
178 // This version of the object instance constructor for this class creates
179 // an object instance whose target is the supplied sc_object instance.
180 // The supplied sc_object must in fact be an sc_process_b instance.
181 // object_p -> sc_object instance this is handle for.
182 //------------------------------------------------------------------------------
184  m_target_p(DCAST<sc_process_b*>(object_p))
185 {
186  if ( m_target_p ) m_target_p->reference_increment();
187 }
188 
189 //------------------------------------------------------------------------------
190 //"sc_process_handle::sc_process_handle - pointer constructor"
191 //
192 // This version of the object instance constructor for this class creates
193 // an object instance whose target is the supplied sc_process_b instance.
194 // This saves a dynamic cast compared to the sc_object* case.
195 // process_p -> process instance this is handle for.
196 //------------------------------------------------------------------------------
198  m_target_p(process_p)
199 {
200  if ( m_target_p ) m_target_p->reference_increment();
201 }
202 
203 //------------------------------------------------------------------------------
204 //"sc_process_handle::sc_process_handle - copy constructor"
205 //
206 // This version of the object instance constructor for this class provides
207 // the copy constructor for the class. It clones the supplied original
208 // handle and increments the references to its target.
209 // orig = sc_process_handle object instance to be copied from.
210 //------------------------------------------------------------------------------
212  m_target_p(orig.m_target_p)
213 {
214  if ( m_target_p ) m_target_p->reference_increment();
215 }
216 
217 
218 //------------------------------------------------------------------------------
219 //"sc_process_handle::operator ="
220 //
221 // This assignment operator signature is call by value rather than reference.
222 // This means that an sc_process_handle instance will be created and the
223 // target for that instance will be incremented before the assignment is done.
224 // The assignment is done using the swap() method, which simply swaps the
225 // targets of 'orig' and this object instance. We don't need to increment
226 // the reference count for our new target since that was done when 'orig'
227 // was created. Our old target's reference count will be decremented when
228 // 'orig' is deleted.
229 // orig = sc_process_handle object instance to be copied from.
230 // Result is a reference for this object instance.
231 //------------------------------------------------------------------------------
232 inline sc_process_handle&
234 {
235  swap( orig );
236  return *this;
237 }
238 
239 
240 //------------------------------------------------------------------------------
241 //"sc_process_handle::~sc_process_handle"
242 //
243 // This is the object instance destructor for this class. It decrements
244 // the reference count for its target.
245 //------------------------------------------------------------------------------
247 {
248  if ( m_target_p ) m_target_p->reference_decrement();
249 }
250 
251 //------------------------------------------------------------------------------
252 //"sc_process_handle::inline methods"
253 //
254 // These are short inline methods.
255 //------------------------------------------------------------------------------
256 
257 // disable this object instance's target.
258 
260 {
261  if ( m_target_p )
262  m_target_p->disable_process(descendants);
263  else
264  SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "disable()");
265 }
266 
267 // call dont_initialize() on this object instance's target.
268 
269 inline void sc_process_handle::dont_initialize( bool dont )
270 {
271  if ( m_target_p )
272  m_target_p->dont_initialize( dont );
273  else
274  SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "dont_initialize()");
275 }
276 
277 // dump the status of this object instance's target:
278 
279 inline std::string sc_process_handle::dump_state() const
280 {
281  return m_target_p ? m_target_p->dump_state() : std::string("NO TARGET");
282 }
283 
284 // return whether this object instance's target is dynamic or not.
285 
286 inline bool sc_process_handle::dynamic() const
287 {
288  return m_target_p ? m_target_p->dynamic() : false;
289 }
290 
291 // enable this object instance's target.
292 
294 {
295  if ( m_target_p )
296  m_target_p->enable_process(descendants);
297  else
298  SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "enable()");
299 }
300 
301 // return the child objects for this object instance's target.
302 
303 inline
304 const std::vector<sc_event*>& sc_process_handle::get_child_events() const
305 {
307 }
308 
309 // return the child objects for this object instance's target.
310 
311 inline
312 const std::vector<sc_object*>& sc_process_handle::get_child_objects() const
313 {
315 }
316 
317 // return the parent object for this object instance's target.
318 
320 {
321  return m_target_p ? m_target_p->get_parent_object() : NULL;
322 }
323 
324 // return this object instance's target.
325 
327 {
328  return m_target_p;
329 }
330 
331 // return whether this object instance is unwinding or not.
332 
334 {
335  if ( m_target_p )
336  return m_target_p->is_unwinding();
337  else {
338  SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "is_unwinding()");
339  return false;
340  }
341 }
342 
343 // kill this object instance's target.
344 
346 {
347  if ( m_target_p )
348  m_target_p->kill_process( descendants );
349  else
350  SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "kill()");
351 }
352 
353 // return the name of this object instance's target.
354 
355 inline const char* sc_process_handle::name() const
356 {
357  return m_target_p ? m_target_p->name() : "";
358 }
359 
360 // return the process kind for this object instance's target.
361 
363 {
365 }
366 
367 // reset this object instance's target.
368 
370 {
371  if ( m_target_p )
373  descendants );
374  else
375  SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "reset()");
376 }
377 
378 // return the reset event for this object instance's target.
379 
381 {
382  if ( m_target_p )
383  return m_target_p->reset_event();
384  else
385  {
386  SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "reset()");
388  }
389 }
390 
391 // resume this object instance's target.
392 
394 {
395  if ( m_target_p )
396  m_target_p->resume_process(descendants);
397  else
398  SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "resume()");
399 }
400 
401 // suspend this object instance's target.
402 
404 {
405  if ( m_target_p )
406  m_target_p->suspend_process(descendants);
407  else
408  SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "suspend()");
409 }
410 
411 // swap targets of this process handle with the supplied one.
412 
414 {
415  sc_process_b* tmp = m_target_p;
416  m_target_p = other.m_target_p;
417  other.m_target_p = tmp;
418 }
419 
420 // turn sync_reset off for this object instance's target.
421 
423  sc_descendant_inclusion_info descendants)
424 {
425  if ( m_target_p )
427  descendants);
428  else
429  SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "sync_reset_off()");
430 }
431 
432 // turn sync_reset on for this object instance's target.
433 
435  sc_descendant_inclusion_info descendants)
436 {
437  if ( m_target_p )
438  {
440  descendants);
441  }
442  else
443  {
444  SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "sync_reset_on()");
445  }
446 }
447 
448 // terminate this object instance's target.
449 
450 inline bool sc_process_handle::terminated() const
451 {
452  return m_target_p ? m_target_p->terminated() : false;
453 }
454 
455 // return the termination event for this object instance's target.
456 
458 {
459  if ( m_target_p )
460  return m_target_p->terminated_event();
461  else
462  {
463  SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "terminated_event()");
465  }
466 }
467 
468 // return true if this object instance has a target, false it not.
469 
470 inline bool sc_process_handle::valid() const
471 {
472  return m_target_p ? true : false;
473 }
474 
475 //------------------------------------------------------------------------------
476 //"sc_process_handle::sc_throw_it"
477 //
478 // This method throws the supplied exception to the process whose handle this
479 // object instance is, and optionally to the process' descendants. Once the
480 // exception is thrown the currently executed process will suspend to allow
481 // the exception to be propagated. Once the propagation has occurred the
482 // current process will be resumed.
483 //
484 // Notes:
485 // (1) We allocate the helper function on the stack, see the description of
486 // sc_throw_it<EXCEPT>, in sc_process.h, for why.
487 //
488 // Arguments:
489 // exception = exception to be thrown
490 // descendants = indication of whether descendant processes should also
491 // receive the throw.
492 //------------------------------------------------------------------------------
493 template<typename EXCEPT>
494 inline void sc_process_handle::throw_it( const EXCEPT& exception,
495  sc_descendant_inclusion_info descendants)
496 {
497  sc_throw_it<EXCEPT> helper(exception); // helper to throw the exception.
498 
499  if ( !m_target_p )
500  {
501  SC_REPORT_WARNING( SC_ID_EMPTY_PROCESS_HANDLE_, "throw_it()");
502  return;
503  }
504  m_target_p->throw_user(helper, descendants);
505 }
506 
507 
508 //------------------------------------------------------------------------------
509 //"sc_process_b::last_created_process_handle"
510 //
511 // This method returns the kind of this process.
512 //------------------------------------------------------------------------------
514 {
516 }
517 
519 {
521 }
522 
523 } // namespace sc_core
524 
525 // Revision 1.19 2011/08/24 22:05:51 acg
526 // Torsten Maehne: initialization changes to remove warnings.
527 //
528 // Revision 1.18 2011/04/01 22:08:26 acg
529 // Andy Goodrich: remove unused variable.
530 //
531 // Revision 1.17 2011/03/12 21:07:51 acg
532 // Andy Goodrich: changes to kernel generated event support.
533 //
534 // Revision 1.16 2011/02/18 20:27:14 acg
535 // Andy Goodrich: Updated Copyrights.
536 //
537 // Revision 1.15 2011/02/17 19:53:03 acg
538 // Andy Goodrich: changed dump_status() to dump_state() with new signature.
539 //
540 // Revision 1.14 2011/02/13 21:47:37 acg
541 // Andy Goodrich: update copyright notice.
542 //
543 // Revision 1.13 2011/02/13 21:33:30 acg
544 // Andy Goodrich: added dump_status() to allow the dumping of the status
545 // of a process handle's target.
546 //
547 // Revision 1.12 2011/02/01 23:01:53 acg
548 // Andy Goodrich: removed dead code.
549 //
550 // Revision 1.11 2011/02/01 21:07:36 acg
551 // Andy Goodrich: defering of run queue manipulations to the
552 // sc_thread_process::throw_it() method.
553 //
554 // Revision 1.10 2011/01/25 20:50:37 acg
555 // Andy Goodrich: changes for IEEE 1666 2011.
556 //
557 // Revision 1.9 2011/01/20 16:52:20 acg
558 // Andy Goodrich: changes for IEEE 1666 2011.
559 //
560 // Revision 1.8 2011/01/19 23:21:50 acg
561 // Andy Goodrich: changes for IEEE 1666 2011
562 //
563 // Revision 1.7 2011/01/18 20:10:45 acg
564 // Andy Goodrich: changes for IEEE1666_2011 semantics.
565 //
566 // Revision 1.6 2010/07/30 05:21:22 acg
567 // Andy Goodrich: release 2.3 fixes.
568 //
569 // Revision 1.5 2010/07/22 20:02:33 acg
570 // Andy Goodrich: bug fixes.
571 //
572 // Revision 1.4 2009/05/22 16:06:29 acg
573 // Andy Goodrich: process control updates.
574 //
575 // Revision 1.3 2008/05/22 17:06:26 acg
576 // Andy Goodrich: updated copyright notice to include 2008.
577 //
578 // Revision 1.2 2007/09/20 20:32:35 acg
579 // Andy Goodrich: changes to the semantics of throw_it() to match the
580 // specification. A call to throw_it() will immediately suspend the calling
581 // thread until all the throwees have executed. At that point the calling
582 // thread will be restarted before the execution of any other threads.
583 //
584 // Revision 1.1.1.1 2006/12/15 20:20:05 acg
585 // SystemC 2.3
586 //
587 // Revision 1.7 2006/05/08 17:58:24 acg
588 // Andy Goodrich: added David Long's forward declarations for friend
589 // functions, methods, and operators to keep the Microsoft compiler happy.
590 //
591 // Revision 1.6 2006/04/20 17:08:17 acg
592 // Andy Goodrich: 3.0 style process changes.
593 //
594 // Revision 1.5 2006/04/11 23:13:21 acg
595 // Andy Goodrich: Changes for reduced reset support that only includes
596 // sc_cthread, but has preliminary hooks for expanding to method and thread
597 // processes also.
598 //
599 // Revision 1.4 2006/01/24 20:49:05 acg
600 // Andy Goodrich: changes to remove the use of deprecated features within the
601 // simulator, and to issue warning messages when deprecated features are used.
602 //
603 // Revision 1.3 2006/01/13 18:44:30 acg
604 // Added $Log to record CVS changes into the source.
605 
606 #endif // !defined(sc_spawn_h_INCLUDED)
const char * name() const
Definition: sc_object.h:67
bool operator<(const sc_process_handle &left, const sc_process_handle &right)
bool operator!=(const sc_process_handle &left, const sc_process_handle &right)
sc_object * get_parent_object() const
Definition: sc_object.h:111
sc_event & terminated_event()
static std::vector< sc_object * > empty_object_vector
void sync_reset_on(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
static sc_process_b * m_last_created_process_p
Definition: sc_process.h:444
void disable(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
const ::std::vector< sc_object * > & get_child_objects() const
Definition: sc_process.h:476
friend class sc_process_handle
Definition: sc_process.h:271
void resume(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
virtual void enable_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)=0
void kill(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
#define SC_REPORT_WARNING(msg_type, msg)
Definition: sc_report.h:209
virtual void throw_user(const sc_throw_it_helper &helper, sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)=0
friend bool operator<(const this_type &left, const this_type &right)
void throw_it(const EXCEPT &exception, sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
void reset(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
class sc_thread_process * sc_thread_handle
Definition: sc_process.h:58
static sc_process_handle last_created_process_handle()
sc_object * get_parent_object() const
std::string dump_state() const
friend bool operator!=(const this_type &left, const this_type &right)
const std::vector< sc_event * > & get_child_events() const
const std::vector< sc_object * > & get_child_objects() const
void sync_reset_off(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
virtual void resume_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)=0
sc_event & reset_event()
const char * name() const
virtual bool terminated() const
Definition: sc_process.h:678
void reset_process(reset_type rt, sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
sc_curr_proc_kind proc_kind() const
sc_process_handle & operator=(sc_process_handle src)
friend bool operator==(const this_type &left, const this_type &right)
sc_curr_proc_kind
Definition: sc_process.h:63
static std::vector< sc_event * > empty_event_vector
void enable(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)
bool dynamic() const
Definition: sc_process.h:351
sc_descendant_inclusion_info
Definition: sc_process.h:73
sc_process_handle sc_get_last_created_process_handle()
bool operator==(const sc_process_handle &left, const sc_process_handle &right)
class sc_cthread_process * sc_cthread_handle
Definition: sc_process.h:56
sc_event & reset_event() const
virtual void kill_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)=0
void swap(sc_process_handle &other)
class sc_method_process * sc_method_handle
Definition: sc_process.h:57
sc_object * get_process_object() const
sc_curr_proc_kind proc_kind() const
Definition: sc_process.h:588
#define DCAST
Definition: sc_iostream.h:61
virtual const std::vector< sc_event * > & get_child_events() const
Definition: sc_object.h:104
bool dont_initialize() const
Definition: sc_process.h:337
virtual void suspend_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)=0
virtual void disable_process(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)=0
bool is_unwinding() const
Definition: sc_process.h:525
std::string dump_state() const
void suspend(sc_descendant_inclusion_info descendants=SC_NO_DESCENDANTS)