SystemC  2.3.1
Accellera SystemC proof-of-concept library
sc_event.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_event.h --
21 
22  Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
23 
24  CHANGE LOG AT THE END OF THE FILE
25  *****************************************************************************/
26 
27 
28 #ifndef SC_EVENT_H
29 #define SC_EVENT_H
30 
31 #include "sysc/kernel/sc_cmnhdr.h"
35 
36 namespace sc_core {
37 
38 // forward declarations
39 class sc_event;
40 class sc_event_timed;
41 class sc_event_list;
42 class sc_event_or_list;
43 class sc_event_and_list;
44 class sc_object;
45 
46 // friend function declarations
47  int sc_notify_time_compare( const void*, const void* );
48 
49 // ----------------------------------------------------------------------------
50 // CLASS : sc_event_expr
51 //
52 // The event expression class.
53 // ----------------------------------------------------------------------------
54 
55 template< typename T >
57 {
58  friend class sc_event;
59  friend class sc_event_and_list;
60  friend class sc_event_or_list;
61 
62  typedef T type;
63 
64  inline sc_event_expr()
65  : m_expr( new T(true) )
66  {}
67 
68 public:
69 
70  inline sc_event_expr( sc_event_expr const & e) // move semantics
71  : m_expr(e.m_expr)
72  {
73  e.m_expr = 0;
74  }
75 
76  T const & release() const
77  {
78  sc_assert( m_expr );
79  T* expr = m_expr;
80  m_expr=0;
81  return *expr;
82  }
83 
84  void push_back( sc_event const & e) const
85  {
86  sc_assert( m_expr );
87  m_expr->push_back(e);
88  }
89 
90  void push_back( type const & el) const
91  {
92  sc_assert( m_expr );
93  m_expr->push_back(el);
94  }
95  operator T const &() const
96  {
97  return release();
98  }
99 
101  {
102  delete m_expr;
103  }
104 
105 private:
106  mutable type * m_expr;
107 
108  // disabled
109  void operator=( sc_event_expr const & );
110 };
111 
112 // ----------------------------------------------------------------------------
113 // CLASS : sc_event_list
114 //
115 // Base class for lists of events.
116 // ----------------------------------------------------------------------------
117 
119 {
120  friend class sc_process_b;
121  friend class sc_method_process;
122  friend class sc_thread_process;
123  friend void sc_thread_cor_fn( void* arg );
124 
125 public:
126  sc_event_list( const sc_event_list& );
128 
129  int size() const;
130 
131 protected:
132 
133  void push_back( const sc_event& );
134  void push_back( const sc_event_list& );
135 
136  explicit
137  sc_event_list( bool and_list_, bool auto_delete_ = false );
138 
139  sc_event_list( const sc_event&,
140  bool and_list_,
141  bool auto_delete_ = false );
142 
143  ~sc_event_list();
144 
145  void swap( sc_event_list& );
146  void move_from( const sc_event_list& );
147 
148  bool and_list() const;
149 
150  void add_dynamic( sc_method_handle ) const;
151  void add_dynamic( sc_thread_handle ) const;
152  void remove_dynamic( sc_method_handle, const sc_event* ) const;
153  void remove_dynamic( sc_thread_handle, const sc_event* ) const;
154 
155  bool busy() const;
156  bool temporary() const;
157  void auto_delete() const;
158 
159  void report_premature_destruction() const;
160  void report_invalid_modification() const;
161 
162 private:
163 
164  std::vector<const sc_event*> m_events;
165  bool m_and_list;
166  bool m_auto_delete;
167  mutable unsigned m_busy;
168 };
169 
170 
171 // ----------------------------------------------------------------------------
172 // CLASS : sc_event_and_list
173 //
174 // AND list of events.
175 // ----------------------------------------------------------------------------
176 
178 : public sc_event_list
179 {
180  friend class sc_event;
182  friend class sc_process_b;
183  friend class sc_method_process;
184  friend class sc_thread_process;
185 
186 protected:
187 
188  explicit
189  sc_event_and_list( bool auto_delete_ );
190 
191 public:
192 
194  sc_event_and_list( const sc_event& );
195 
196  void swap( sc_event_and_list& );
199 
202 };
203 
205 
206 // ----------------------------------------------------------------------------
207 // CLASS : sc_event_or_list
208 //
209 // OR list of events.
210 // ----------------------------------------------------------------------------
211 
213 : public sc_event_list
214 {
215  friend class sc_event;
217  friend class sc_process_b;
218  friend class sc_method_process;
219  friend class sc_thread_process;
220 
221 protected:
222 
223  explicit
224  sc_event_or_list( bool auto_delete_ );
225 
226 public:
228  sc_event_or_list( const sc_event& );
229  void swap( sc_event_or_list& );
234 };
235 
237 
238 // ----------------------------------------------------------------------------
239 // CLASS : sc_event
240 //
241 // The event class.
242 // ----------------------------------------------------------------------------
243 
244 class sc_event
245 {
246  friend class sc_clock;
247  friend class sc_event_list;
248  friend class sc_event_timed;
249  friend class sc_simcontext;
250  friend class sc_object;
251  friend class sc_process_b;
252  friend class sc_method_process;
253  friend class sc_thread_process;
254  template<typename IF, sc_writer_policy POL> friend class sc_signal;
255  friend void sc_thread_cor_fn( void* arg );
256 
257 public:
258 
259  sc_event();
260  sc_event( const char* name );
261  ~sc_event();
262 
263  void cancel();
264 
265  const char* name() const { return m_name.c_str(); }
266  const char* basename() const;
267  sc_object* get_parent_object() const { return m_parent_p; }
268  bool in_hierarchy() const { return m_name.length() != 0; }
269 
270  void notify();
271  void notify( const sc_time& );
272  void notify( double, sc_time_unit );
273 
274  void notify_delayed();
275  void notify_delayed( const sc_time& );
276  void notify_delayed( double, sc_time_unit );
277 
278  sc_event_or_expr operator | ( const sc_event& ) const;
280  sc_event_and_expr operator & ( const sc_event& ) const;
282 
283 
284 private:
285 
286  void add_static( sc_method_handle ) const;
287  void add_static( sc_thread_handle ) const;
288  void add_dynamic( sc_method_handle ) const;
289  void add_dynamic( sc_thread_handle ) const;
290 
291  void notify_internal( const sc_time& );
292  void notify_next_delta();
293 
294  bool remove_static( sc_method_handle ) const;
295  bool remove_static( sc_thread_handle ) const;
296  bool remove_dynamic( sc_method_handle ) const;
297  bool remove_dynamic( sc_thread_handle ) const;
298 
299  void register_event( const char* name );
300  void reset();
301 
302  void trigger();
303 
304 private:
305 
306  enum notify_t { NONE, DELTA, TIMED };
307 
308  std::string m_name; // name of object.
309  sc_object* m_parent_p; // parent sc_object for this event.
310  sc_simcontext* m_simc;
311  notify_t m_notify_type;
312  int m_delta_event_index;
313  sc_event_timed* m_timed;
314 
315  mutable std::vector<sc_method_handle> m_methods_static;
316  mutable std::vector<sc_method_handle> m_methods_dynamic;
317  mutable std::vector<sc_thread_handle> m_threads_static;
318  mutable std::vector<sc_thread_handle> m_threads_dynamic;
319 
320 private:
321 
322  // disabled
323  sc_event( const sc_event& );
324  sc_event& operator = ( const sc_event& );
325 };
326 
327 #define SC_KERNEL_EVENT_PREFIX "$$$$kernel_event$$$$_"
328 
329 extern sc_event sc_non_event; // Event that never happens.
330 
331 // ----------------------------------------------------------------------------
332 // CLASS : sc_event_timed
333 //
334 // Class for storing the time to notify a timed event.
335 // ----------------------------------------------------------------------------
336 
338 {
339  friend class sc_event;
340  friend class sc_simcontext;
341 
342  friend int sc_notify_time_compare( const void*, const void* );
343 
344 private:
345 
346  sc_event_timed( sc_event* e, const sc_time& t )
347  : m_event( e ), m_notify_time( t )
348  {}
349 
350  ~sc_event_timed()
351  { if( m_event != 0 ) { m_event->m_timed = 0; } }
352 
353  sc_event* event() const
354  { return m_event; }
355 
356  const sc_time& notify_time() const
357  { return m_notify_time; }
358 
359  static void* operator new( std::size_t )
360  { return allocate(); }
361 
362  static void operator delete( void* p, std::size_t )
363  { deallocate( p ); }
364 
365 private:
366 
367  // dedicated memory management
368  static void* allocate();
369  static void deallocate( void* );
370 
371 private:
372 
373  sc_event* m_event;
374  sc_time m_notify_time;
375 
376 private:
377 
378  // disabled
379  sc_event_timed();
380  sc_event_timed( const sc_event_timed& );
381  sc_event_timed& operator = ( const sc_event_timed& );
382 };
383 
384 
385 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
386 
387 inline
388 void
390 {
391  notify( sc_time( v, tu, m_simc ) );
392 }
393 
394 
395 inline
396 void
397 sc_event::notify_internal( const sc_time& t )
398 {
399  if( t == SC_ZERO_TIME ) {
400  // add this event to the delta events set
401  m_delta_event_index = m_simc->add_delta_event( this );
402  m_notify_type = DELTA;
403  } else {
404  sc_event_timed* et =
405  new sc_event_timed( this, m_simc->time_stamp() + t );
406  m_simc->add_timed_event( et );
407  m_timed = et;
408  m_notify_type = TIMED;
409  }
410 }
411 
412 inline
413 void
414 sc_event::notify_next_delta()
415 {
416  if( m_notify_type != NONE ) {
417  SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
418  }
419  // add this event to the delta events set
420  m_delta_event_index = m_simc->add_delta_event( this );
421  m_notify_type = DELTA;
422 }
423 
424 inline
425 void
427 {
428  notify_delayed( sc_time( v, tu, m_simc ) );
429 }
430 
431 
432 inline
433 void
434 sc_event::add_static( sc_method_handle method_h ) const
435 {
436  m_methods_static.push_back( method_h );
437 }
438 
439 inline
440 void
441 sc_event::add_static( sc_thread_handle thread_h ) const
442 {
443  m_threads_static.push_back( thread_h );
444 }
445 
446 inline
447 void
448 sc_event::add_dynamic( sc_method_handle method_h ) const
449 {
450  m_methods_dynamic.push_back( method_h );
451 }
452 
453 inline
454 void
455 sc_event::add_dynamic( sc_thread_handle thread_h ) const
456 {
457  m_threads_dynamic.push_back( thread_h );
458 }
459 
460 
461 // ----------------------------------------------------------------------------
462 // Deprecated functional notation for notifying events.
463 // ----------------------------------------------------------------------------
464 
465 extern void notify( sc_event& e );
466 extern void notify( const sc_time& t, sc_event& e );
467 extern void notify( double v, sc_time_unit tu, sc_event& e );
468 
469 
470 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
471 
472 inline
473 sc_event_list::sc_event_list( bool and_list_, bool auto_delete_ )
474  : m_events()
475  , m_and_list( and_list_ )
476  , m_auto_delete( auto_delete_ )
477  , m_busy( 0 )
478 {
479 }
480 
481 inline
483  bool and_list_,
484  bool auto_delete_ )
485  : m_events()
486  , m_and_list( and_list_ )
487  , m_auto_delete( auto_delete_ )
488  , m_busy(0)
489 {
490  m_events.push_back( &e );
491 }
492 
493 inline
495  : m_events()
496  , m_and_list( that.m_and_list )
497  , m_auto_delete( false )
498  , m_busy( 0 )
499 {
500  move_from( that );
501  that.auto_delete(); // free automatic lists
502 }
503 
504 inline
507 {
508  if( m_busy )
510 
511  move_from( that );
512  that.auto_delete(); // free automatic lists
513 
514  return *this;
515 }
516 
517 inline
519 {
520  if( m_busy )
522 }
523 
524 inline
525 void
527 {
528  if( busy() || that.busy() )
530  m_events.swap( that.m_events );
531 }
532 
533 inline
534 void
536 {
537  if( that.temporary() ) {
538  swap( const_cast<sc_event_list&>(that) ); // move from source
539  } else {
540  m_events = that.m_events; // copy from source
541  }
542 }
543 
544 inline
545 int
547 {
548  return m_events.size();
549 }
550 
551 inline
552 bool
554 {
555  return m_and_list;
556 }
557 
558 
559 inline
560 bool
562 {
563  return m_busy != 0;
564 }
565 
566 
567 inline
568 bool
570 {
571  return m_auto_delete && ! m_busy;
572 }
573 
574 inline
575 void
577 {
578  if( m_busy ) {
579  --m_busy;
580  }
581  if( ! m_busy && m_auto_delete ) {
582  delete this;
583  }
584 }
585 
586 
587 
588 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
589 
590 inline
592  : sc_event_list( false )
593 {}
594 
595 inline
597 : sc_event_list( false )
598 {
599  push_back( e );
600 }
601 
602 inline
604 : sc_event_list( false, auto_delete_ )
605 {}
606 
607 inline
610 {
611  if( busy() )
613 
614  push_back( e );
615  return *this;
616 }
617 
618 inline
621 {
622  if( busy() )
624 
625  push_back( el );
626  return *this;
627 }
628 
629 inline
632 {
633  sc_event_or_expr expr;
634  expr.push_back( *this );
635  expr.push_back( e2 );
636  return expr;
637 }
638 
639 inline
642 {
643  sc_event_or_expr expr;
644  expr.push_back( *this );
645  expr.push_back( e2 );
646  return expr;
647 }
648 
649 
650 // sc_event
651 
652 inline
654 sc_event::operator | ( const sc_event& e2 ) const
655 {
656  sc_event_or_expr expr;
657  expr.push_back( *this );
658  expr.push_back( e2 );
659  return expr;
660 }
661 
662 inline
665 {
666  sc_event_or_expr expr;
667  expr.push_back( *this );
668  expr.push_back( e2 );
669  return expr;
670 }
671 
672 // sc_event_expr
673 
674 inline
677 {
678  expr.push_back( e );
679  return expr;
680 }
681 
682 inline
685 {
686  expr.push_back( el );
687  return expr;
688 }
689 
690 inline
691 void
693 {
694  sc_event_list::swap( that );
695 }
696 
697 
698 
699 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
700 
701 inline
703  : sc_event_list( true )
704 {}
705 
706 inline
708 : sc_event_list( true )
709 {
710  push_back( e );
711 }
712 
713 inline
715 : sc_event_list( true, auto_delete_ )
716 {}
717 
718 inline
719 void
721 {
722  sc_event_list::swap( that );
723 }
724 
725 
726 inline
729 {
730  if( busy() )
732 
733  push_back( e );
734  return *this;
735 }
736 
737 inline
740 {
741  if( busy() )
743 
744  push_back( el );
745  return *this;
746 }
747 
748 inline
751 {
752  sc_event_and_expr expr;
753  expr.push_back( *this );
754  expr.push_back( e );
755  return expr;
756 }
757 
758 inline
761 {
762  sc_event_and_expr expr;
763  expr.push_back( *this );
764  expr.push_back( el );
765  return expr;
766 }
767 
768 // sc_event
769 
770 inline
772 sc_event::operator & ( const sc_event& e2 ) const
773 {
774  sc_event_and_expr expr;
775  expr.push_back( *this );
776  expr.push_back( e2 );
777  return expr;
778 }
779 
780 inline
783 {
784  sc_event_and_expr expr;
785  expr.push_back( *this );
786  expr.push_back( e2 );
787  return expr;
788 }
789 
790 // sc_event_expr
791 
792 inline
795 {
796  expr.push_back( e );
797  return expr;
798 }
799 
800 inline
803 {
804  expr.push_back( el );
805  return expr;
806 }
807 
808 } // namespace sc_core
809 
810 // $Log: sc_event.h,v $
811 // Revision 1.14 2011/08/29 18:04:32 acg
812 // Philipp A. Hartmann: miscellaneous clean ups.
813 //
814 // Revision 1.13 2011/08/26 20:46:09 acg
815 // Andy Goodrich: moved the modification log to the end of the file to
816 // eliminate source line number skew when check-ins are done.
817 //
818 // Revision 1.12 2011/08/24 22:05:50 acg
819 // Torsten Maehne: initialization changes to remove warnings.
820 //
821 // Revision 1.11 2011/03/12 21:07:51 acg
822 // Andy Goodrich: changes to kernel generated event support.
823 //
824 // Revision 1.10 2011/03/06 15:55:11 acg
825 // Andy Goodrich: Changes for named events.
826 //
827 // Revision 1.9 2011/03/05 01:39:21 acg
828 // Andy Goodrich: changes for named events.
829 //
830 // Revision 1.8 2011/02/18 20:27:14 acg
831 // Andy Goodrich: Updated Copyrights.
832 //
833 // Revision 1.7 2011/02/13 21:47:37 acg
834 // Andy Goodrich: update copyright notice.
835 //
836 // Revision 1.6 2011/02/01 21:03:23 acg
837 // Andy Goodrich: new return codes for trigger_dynamic calls.
838 //
839 // Revision 1.5 2011/01/18 20:10:44 acg
840 // Andy Goodrich: changes for IEEE1666_2011 semantics.
841 //
842 // Revision 1.4 2010/12/07 20:09:11 acg
843 // Andy Goodrich: writer policy fix.
844 //
845 // Revision 1.3 2009/05/22 16:06:29 acg
846 // Andy Goodrich: process control updates.
847 //
848 // Revision 1.2 2008/05/22 17:06:25 acg
849 // Andy Goodrich: updated copyright notice to include 2008.
850 //
851 // Revision 1.1.1.1 2006/12/15 20:20:05 acg
852 // SystemC 2.3
853 //
854 // Revision 1.8 2006/05/26 20:33:16 acg
855 // Andy Goodrich: changes required by additional platform compilers (i.e.,
856 // Microsoft VC++, Sun Forte, HP aCC).
857 //
858 // Revision 1.7 2006/05/08 17:57:51 acg
859 // Andy Goodrich: added David Long's forward declarations for friend
860 // functions, methods, and operators to keep the Microsoft compiler happy.
861 //
862 // Revision 1.6 2006/04/11 23:13:20 acg
863 // Andy Goodrich: Changes for reduced reset support that only includes
864 // sc_cthread, but has preliminary hooks for expanding to method and thread
865 // processes also.
866 //
867 // Revision 1.5 2006/01/24 20:56:00 acg
868 // Andy Goodrich: fixed up CVS comment.
869 //
870 // Revision 1.4 2006/01/24 20:48:14 acg
871 // Andy Goodrich: added deprecation warnings for notify_delayed(). Added two
872 // new implementation-dependent methods, notify_next_delta() & notify_internal()
873 // to replace calls to notify_delayed() from within the simulator. These two
874 // new methods are simpler than notify_delayed() and should speed up simulations
875 //
876 // Revision 1.3 2006/01/13 18:44:29 acg
877 // Added $Log to record CVS changes into the source.
878 //
879 
880 #endif
881 
882 // Taf!
const char * basename() const
void notify(sc_event &e)
T const & release() const
Definition: sc_event.h:76
void swap(sc_event_or_list &)
Definition: sc_event.h:692
sc_event sc_non_event
sc_event_or_list & operator|=(const sc_event &)
Definition: sc_event.h:609
void swap(sc_event_list &)
Definition: sc_event.h:526
sc_time_unit
Definition: sc_time.h:56
sc_event_expr< sc_event_and_list > sc_event_and_expr
Definition: sc_event.h:204
#define sc_assert(expr)
Definition: sc_report.h:235
sc_event_list & operator=(const sc_event_list &)
Definition: sc_event.h:506
void swap(sc_event_and_list &)
Definition: sc_event.h:720
void push_back(type const &el) const
Definition: sc_event.h:90
void push_back(const sc_event &)
void report_premature_destruction() const
sc_event_list(const sc_event_list &)
Definition: sc_event.h:494
sc_event_and_expr operator&(const sc_event &) const
Definition: sc_event.h:772
void report_invalid_modification() const
friend void sc_thread_cor_fn(void *arg)
friend class sc_object
Definition: sc_event.h:250
bool temporary() const
Definition: sc_event.h:569
sc_event_or_expr operator|(sc_event_or_expr expr, sc_event const &e)
Definition: sc_event.h:676
class sc_thread_process * sc_thread_handle
Definition: sc_process.h:58
bool busy() const
Definition: sc_event.h:561
bool in_hierarchy() const
Definition: sc_event.h:268
sc_event_or_expr operator|(const sc_event &) const
Definition: sc_event.h:654
const sc_time & time_stamp() const
void push_back(sc_event const &e) const
Definition: sc_event.h:84
sc_event_and_list & operator&=(const sc_event &)
Definition: sc_event.h:728
int sc_notify_time_compare(const void *, const void *)
sc_event_expr< sc_event_and_list > operator&(const sc_event &)
Definition: sc_event.h:750
friend class sc_event_timed
Definition: sc_event.h:248
void add_dynamic(sc_method_handle) const
sc_object * get_parent_object() const
Definition: sc_event.h:267
void remove_dynamic(sc_method_handle, const sc_event *) const
const sc_time SC_ZERO_TIME
void auto_delete() const
Definition: sc_event.h:576
friend class sc_simcontext
Definition: sc_event.h:249
sc_event_expr< sc_event_or_list > operator|(const sc_event &) const
Definition: sc_event.h:631
sc_event_and_expr operator&(sc_event_and_expr expr, sc_event const &e)
Definition: sc_event.h:794
int size() const
Definition: sc_event.h:546
#define SC_REPORT_ERROR(msg_type, msg)
Definition: sc_report.h:213
class sc_method_process * sc_method_handle
Definition: sc_process.h:57
const char * name() const
Definition: sc_event.h:265
friend void sc_thread_cor_fn(void *arg)
sc_event_expr< sc_event_or_list > sc_event_or_expr
Definition: sc_event.h:236
void move_from(const sc_event_list &)
Definition: sc_event.h:535
bool and_list() const
Definition: sc_event.h:553
friend int sc_notify_time_compare(const void *, const void *)
friend class sc_event
Definition: sc_event.h:339
sc_event_expr(sc_event_expr const &e)
Definition: sc_event.h:70