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