00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef SC_EVENT_H
00029 #define SC_EVENT_H
00030
00031 #include "sysc/kernel/sc_cmnhdr.h"
00032 #include "sysc/kernel/sc_kernel_ids.h"
00033 #include "sysc/kernel/sc_simcontext.h"
00034 #include "sysc/communication/sc_writer_policy.h"
00035
00036 namespace sc_core {
00037
00038
00039 class sc_event;
00040 class sc_event_timed;
00041 class sc_event_list;
00042 class sc_event_or_list;
00043 class sc_event_and_list;
00044 class sc_object;
00045
00046
00047 int sc_notify_time_compare( const void*, const void* );
00048
00049
00055 template< typename T >
00056 class sc_event_expr
00057 {
00058 friend class sc_event;
00059 friend class sc_event_and_list;
00060 friend class sc_event_or_list;
00061
00062 typedef T type;
00063
00064 inline sc_event_expr()
00065 : m_expr( new T(true) )
00066 {}
00067
00068 public:
00069
00070 inline sc_event_expr( sc_event_expr const & e)
00071 : m_expr(e.m_expr)
00072 {
00073 e.m_expr = 0;
00074 }
00075
00076 T const & release() const
00077 {
00078 sc_assert( m_expr );
00079 T* expr = m_expr;
00080 m_expr=0;
00081 return *expr;
00082 }
00083
00084 void push_back( sc_event const & e) const
00085 {
00086 sc_assert( m_expr );
00087 m_expr->push_back(e);
00088 }
00089
00090 void push_back( type const & el) const
00091 {
00092 sc_assert( m_expr );
00093 m_expr->push_back(el);
00094 }
00095 operator T const &() const
00096 {
00097 return release();
00098 }
00099
00100 ~sc_event_expr()
00101 {
00102 delete m_expr;
00103 }
00104
00105 private:
00106 mutable type * m_expr;
00107
00108
00109 void operator=( sc_event_expr const & );
00110 };
00111
00112
00118 class sc_event_list
00119 {
00120 friend class sc_process_b;
00121 friend class sc_method_process;
00122 friend class sc_thread_process;
00123 friend void sc_thread_cor_fn( void* arg );
00124
00125 public:
00126 sc_event_list( const sc_event_list& );
00127 sc_event_list& operator = ( const sc_event_list& );
00128
00129 int size() const;
00130
00131 protected:
00132
00133 void push_back( const sc_event& );
00134 void push_back( const sc_event_list& );
00135
00136 explicit
00137 sc_event_list( bool and_list_, bool auto_delete_ = false );
00138
00139 sc_event_list( const sc_event&,
00140 bool and_list_,
00141 bool auto_delete_ = false );
00142
00143 ~sc_event_list();
00144
00145 void swap( sc_event_list& );
00146 void move_from( const sc_event_list& );
00147
00148 bool and_list() const;
00149
00150 void add_dynamic( sc_method_handle ) const;
00151 void add_dynamic( sc_thread_handle ) const;
00152 void remove_dynamic( sc_method_handle, const sc_event* ) const;
00153 void remove_dynamic( sc_thread_handle, const sc_event* ) const;
00154
00155 bool busy() const;
00156 bool temporary() const;
00157 void auto_delete() const;
00158
00159 void report_premature_destruction() const;
00160 void report_invalid_modification() const;
00161
00162 private:
00163
00164 std::vector<const sc_event*> m_events;
00165 bool m_and_list;
00166 bool m_auto_delete;
00167 mutable unsigned m_busy;
00168 };
00169
00170
00171
00177 class sc_event_and_list
00178 : public sc_event_list
00179 {
00180 friend class sc_event;
00181 friend class sc_event_expr<sc_event_and_list>;
00182 friend class sc_process_b;
00183 friend class sc_method_process;
00184 friend class sc_thread_process;
00185
00186 protected:
00187
00188 explicit
00189 sc_event_and_list( bool auto_delete_ );
00190
00191 public:
00192
00193 sc_event_and_list();
00194 sc_event_and_list( const sc_event& );
00195
00196 void swap( sc_event_and_list& );
00197 sc_event_and_list& operator &= ( const sc_event& );
00198 sc_event_and_list& operator &= ( const sc_event_and_list & );
00199
00200 sc_event_expr<sc_event_and_list> operator & ( const sc_event& );
00201 sc_event_expr<sc_event_and_list> operator & ( const sc_event_and_list& );
00202 };
00203
00204 typedef sc_event_expr<sc_event_and_list> sc_event_and_expr;
00205
00206
00212 class sc_event_or_list
00213 : public sc_event_list
00214 {
00215 friend class sc_event;
00216 friend class sc_event_expr<sc_event_or_list>;
00217 friend class sc_process_b;
00218 friend class sc_method_process;
00219 friend class sc_thread_process;
00220
00221 protected:
00222
00223 explicit
00224 sc_event_or_list( bool auto_delete_ );
00225
00226 public:
00227 sc_event_or_list();
00228 sc_event_or_list( const sc_event& );
00229 void swap( sc_event_or_list& );
00230 sc_event_or_list& operator |= ( const sc_event& );
00231 sc_event_or_list& operator |= ( const sc_event_or_list & );
00232 sc_event_expr<sc_event_or_list> operator | ( const sc_event& ) const;
00233 sc_event_expr<sc_event_or_list> operator | ( const sc_event_or_list& ) const;
00234 };
00235
00236 typedef sc_event_expr<sc_event_or_list> sc_event_or_expr;
00237
00238
00244 class sc_event
00245 {
00246 friend class sc_clock;
00247 friend class sc_event_list;
00248 friend class sc_event_timed;
00249 friend class sc_simcontext;
00250 friend class sc_object;
00251 friend class sc_process_b;
00252 friend class sc_method_process;
00253 friend class sc_thread_process;
00254 template<typename IF, sc_writer_policy POL> friend class sc_signal;
00255 friend void sc_thread_cor_fn( void* arg );
00256
00257 public:
00258
00259 sc_event();
00260 sc_event( const char* name );
00261 ~sc_event();
00262
00263 void cancel();
00264
00265 const char* name() const { return m_name.c_str(); }
00266 const char* basename() const;
00267 sc_object* get_parent_object() const { return m_parent_p; }
00268 bool in_hierarchy() const { return m_name.length() != 0; }
00269
00274
00275 void notify();
00276
00277 void notify( const sc_time& );
00278 void notify( double, sc_time_unit );
00279
00280 void notify_delayed();
00281 void notify_delayed( const sc_time& );
00282 void notify_delayed( double, sc_time_unit );
00283
00284 sc_event_or_expr operator | ( const sc_event& ) const;
00285 sc_event_or_expr operator | ( const sc_event_or_list& ) const;
00286 sc_event_and_expr operator & ( const sc_event& ) const;
00287 sc_event_and_expr operator & ( const sc_event_and_list& ) const;
00288
00289
00290 private:
00291
00292 void add_static( sc_method_handle ) const;
00293 void add_static( sc_thread_handle ) const;
00294 void add_dynamic( sc_method_handle ) const;
00295 void add_dynamic( sc_thread_handle ) const;
00296
00297 void notify_internal( const sc_time& );
00298 void notify_next_delta();
00299
00300 bool remove_static( sc_method_handle ) const;
00301 bool remove_static( sc_thread_handle ) const;
00302 bool remove_dynamic( sc_method_handle ) const;
00303 bool remove_dynamic( sc_thread_handle ) const;
00304
00305 void register_event( const char* name );
00306 void reset();
00307
00308 void trigger();
00309
00313
00314 const sc_timestamp& get_notify_timestamp() const;
00315
00319
00320 void set_notify_timestamp( const sc_timestamp& ts );
00321
00322 private:
00323
00324 enum notify_t { NONE, DELTA, TIMED };
00325
00326 std::string m_name;
00327 sc_object* m_parent_p;
00328 sc_simcontext* m_simc;
00329 notify_t m_notify_type;
00330 int m_delta_event_index;
00331 sc_event_timed* m_timed;
00332
00333 mutable std::vector<sc_method_handle> m_methods_static;
00334 mutable std::vector<sc_method_handle> m_methods_dynamic;
00335 mutable std::vector<sc_thread_handle> m_threads_static;
00336 mutable std::vector<sc_thread_handle> m_threads_dynamic;
00337
00341
00342 sc_timestamp m_notify_timestamp;
00343
00344 private:
00345
00346
00347 sc_event( const sc_event& );
00348 sc_event& operator = ( const sc_event& );
00349 };
00350
00351 #define SC_KERNEL_EVENT_PREFIX "$$$$kernel_event$$$$_"
00352
00353 extern sc_event sc_non_event;
00354
00355
00361 class sc_event_timed
00362 {
00363 friend class sc_event;
00364 friend class sc_simcontext;
00365
00366 friend int sc_notify_time_compare( const void*, const void* );
00367
00368 private:
00369
00370 sc_event_timed( sc_event* e, const sc_time& t )
00371 : m_event( e ), m_notify_time( t )
00372 {}
00373
00374 ~sc_event_timed()
00375 { if( m_event != 0 ) { m_event->m_timed = 0; } }
00376
00377 sc_event* event() const
00378 { return m_event; }
00379
00380 const sc_time& notify_time() const
00381 { return m_notify_time; }
00382
00383 static void* operator new( std::size_t )
00384 { return allocate(); }
00385
00386 static void operator delete( void* p, std::size_t )
00387 { deallocate( p ); }
00388
00389 private:
00390
00391
00392 static void* allocate();
00393 static void deallocate( void* );
00394
00395 private:
00396
00397 sc_event* m_event;
00398 sc_time m_notify_time;
00399
00400 private:
00401
00402
00403 sc_event_timed();
00404 sc_event_timed( const sc_event_timed& );
00405 sc_event_timed& operator = ( const sc_event_timed& );
00406 };
00407
00408
00409
00410
00411 inline
00412 void
00413 sc_event::notify( double v, sc_time_unit tu )
00414 {
00415 notify( sc_time( v, tu, m_simc ) );
00416 }
00417
00418
00419 inline
00420 void
00421 sc_event::notify_internal( const sc_time& t )
00422 {
00423
00424 sc_process_b* m_proc = m_simc->get_curr_proc();
00425
00426 if( t == SC_ZERO_TIME ) {
00427
00428
00429 set_notify_timestamp( m_proc->get_timestamp() );
00430
00431
00432 m_delta_event_index = m_simc->add_delta_event( this );
00433 m_notify_type = DELTA;
00434 } else {
00435
00436
00437
00438
00439 sc_event_timed* et = new sc_event_timed( this,
00440 m_proc->get_timestamp().get_time_count() + t );
00441 m_simc->add_timed_event( et );
00442 m_timed = et;
00443 m_notify_type = TIMED;
00444
00445
00446 set_notify_timestamp( sc_timestamp( m_proc->get_timestamp().
00447 get_time_count() + t, 0 ) );
00448 }
00449 }
00450
00451 inline
00452 void
00453 sc_event::notify_next_delta()
00454 {
00455
00456 sc_process_b* m_proc = m_simc->get_curr_proc();
00457
00458 if( m_notify_type != NONE ) {
00459 SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
00460 }
00461
00462
00463 set_notify_timestamp( m_proc->get_timestamp() );
00464
00465
00466 m_delta_event_index = m_simc->add_delta_event( this );
00467 m_notify_type = DELTA;
00468 }
00469
00470 inline
00471 void
00472 sc_event::notify_delayed( double v, sc_time_unit tu )
00473 {
00474 notify_delayed( sc_time( v, tu, m_simc ) );
00475 }
00476
00477
00478 inline
00479 void
00480 sc_event::add_static( sc_method_handle method_h ) const
00481 {
00482 m_methods_static.push_back( method_h );
00483 }
00484
00485 inline
00486 void
00487 sc_event::add_static( sc_thread_handle thread_h ) const
00488 {
00489 m_threads_static.push_back( thread_h );
00490 }
00491
00492 inline
00493 void
00494 sc_event::add_dynamic( sc_method_handle method_h ) const
00495 {
00496 m_methods_dynamic.push_back( method_h );
00497 }
00498
00499 inline
00500 void
00501 sc_event::add_dynamic( sc_thread_handle thread_h ) const
00502 {
00503 m_threads_dynamic.push_back( thread_h );
00504 }
00505
00506
00507
00508
00509
00510
00511 extern void notify( sc_event& e );
00512 extern void notify( const sc_time& t, sc_event& e );
00513 extern void notify( double v, sc_time_unit tu, sc_event& e );
00514
00515
00516
00517
00518 inline
00519 sc_event_list::sc_event_list( bool and_list_, bool auto_delete_ )
00520 : m_events()
00521 , m_and_list( and_list_ )
00522 , m_auto_delete( auto_delete_ )
00523 , m_busy( 0 )
00524 {
00525 }
00526
00527 inline
00528 sc_event_list::sc_event_list( const sc_event& e,
00529 bool and_list_,
00530 bool auto_delete_ )
00531 : m_events()
00532 , m_and_list( and_list_ )
00533 , m_auto_delete( auto_delete_ )
00534 , m_busy(0)
00535 {
00536 m_events.push_back( &e );
00537 }
00538
00539 inline
00540 sc_event_list::sc_event_list( sc_event_list const & that )
00541 : m_events()
00542 , m_and_list( that.m_and_list )
00543 , m_auto_delete( false )
00544 , m_busy( 0 )
00545 {
00546 move_from( that );
00547 that.auto_delete();
00548 }
00549
00550 inline
00551 sc_event_list&
00552 sc_event_list::operator=( sc_event_list const & that )
00553 {
00554 if( m_busy )
00555 report_invalid_modification();
00556
00557 move_from( that );
00558 that.auto_delete();
00559
00560 return *this;
00561 }
00562
00563 inline
00564 sc_event_list::~sc_event_list()
00565 {
00566 if( m_busy )
00567 report_premature_destruction();
00568 }
00569
00570 inline
00571 void
00572 sc_event_list::swap( sc_event_list& that )
00573 {
00574 if( busy() || that.busy() )
00575 report_invalid_modification();
00576 m_events.swap( that.m_events );
00577 }
00578
00579 inline
00580 void
00581 sc_event_list::move_from( sc_event_list const& that )
00582 {
00583 if( that.temporary() ) {
00584 swap( const_cast<sc_event_list&>(that) );
00585 } else {
00586 m_events = that.m_events;
00587 }
00588 }
00589
00590 inline
00591 int
00592 sc_event_list::size() const
00593 {
00594 return m_events.size();
00595 }
00596
00597 inline
00598 bool
00599 sc_event_list::and_list() const
00600 {
00601 return m_and_list;
00602 }
00603
00604
00605 inline
00606 bool
00607 sc_event_list::busy() const
00608 {
00609 return m_busy != 0;
00610 }
00611
00612
00613 inline
00614 bool
00615 sc_event_list::temporary() const
00616 {
00617 return m_auto_delete && ! m_busy;
00618 }
00619
00620 inline
00621 void
00622 sc_event_list::auto_delete() const
00623 {
00624 if( m_busy ) {
00625 --m_busy;
00626 }
00627 if( ! m_busy && m_auto_delete ) {
00628 delete this;
00629 }
00630 }
00631
00632
00633
00634
00635
00636 inline
00637 sc_event_or_list::sc_event_or_list()
00638 : sc_event_list( false )
00639 {}
00640
00641 inline
00642 sc_event_or_list::sc_event_or_list( const sc_event& e )
00643 : sc_event_list( false )
00644 {
00645 push_back( e );
00646 }
00647
00648 inline
00649 sc_event_or_list::sc_event_or_list( bool auto_delete_ )
00650 : sc_event_list( false, auto_delete_ )
00651 {}
00652
00653 inline
00654 sc_event_or_list&
00655 sc_event_or_list::operator |= ( const sc_event& e )
00656 {
00657 if( busy() )
00658 report_invalid_modification();
00659
00660 push_back( e );
00661 return *this;
00662 }
00663
00664 inline
00665 sc_event_or_list&
00666 sc_event_or_list::operator |= ( const sc_event_or_list& el )
00667 {
00668 if( busy() )
00669 report_invalid_modification();
00670
00671 push_back( el );
00672 return *this;
00673 }
00674
00675 inline
00676 sc_event_or_expr
00677 sc_event_or_list::operator | ( const sc_event& e2 ) const
00678 {
00679 sc_event_or_expr expr;
00680 expr.push_back( *this );
00681 expr.push_back( e2 );
00682 return expr;
00683 }
00684
00685 inline
00686 sc_event_or_expr
00687 sc_event_or_list::operator | ( const sc_event_or_list& e2 ) const
00688 {
00689 sc_event_or_expr expr;
00690 expr.push_back( *this );
00691 expr.push_back( e2 );
00692 return expr;
00693 }
00694
00695
00696
00697
00698 inline
00699 sc_event_or_expr
00700 sc_event::operator | ( const sc_event& e2 ) const
00701 {
00702 sc_event_or_expr expr;
00703 expr.push_back( *this );
00704 expr.push_back( e2 );
00705 return expr;
00706 }
00707
00708 inline
00709 sc_event_or_expr
00710 sc_event::operator | ( const sc_event_or_list& e2 ) const
00711 {
00712 sc_event_or_expr expr;
00713 expr.push_back( *this );
00714 expr.push_back( e2 );
00715 return expr;
00716 }
00717
00718
00719
00720 inline
00721 sc_event_or_expr
00722 operator | ( sc_event_or_expr expr, sc_event const & e )
00723 {
00724 expr.push_back( e );
00725 return expr;
00726 }
00727
00728 inline
00729 sc_event_or_expr
00730 operator | ( sc_event_or_expr expr, sc_event_or_list const & el )
00731 {
00732 expr.push_back( el );
00733 return expr;
00734 }
00735
00736 inline
00737 void
00738 sc_event_or_list::swap( sc_event_or_list & that )
00739 {
00740 sc_event_list::swap( that );
00741 }
00742
00743
00744
00745
00746
00747 inline
00748 sc_event_and_list::sc_event_and_list()
00749 : sc_event_list( true )
00750 {}
00751
00752 inline
00753 sc_event_and_list::sc_event_and_list( const sc_event& e )
00754 : sc_event_list( true )
00755 {
00756 push_back( e );
00757 }
00758
00759 inline
00760 sc_event_and_list::sc_event_and_list( bool auto_delete_ )
00761 : sc_event_list( true, auto_delete_ )
00762 {}
00763
00764 inline
00765 void
00766 sc_event_and_list::swap( sc_event_and_list & that )
00767 {
00768 sc_event_list::swap( that );
00769 }
00770
00771
00772 inline
00773 sc_event_and_list&
00774 sc_event_and_list::operator &= ( const sc_event& e )
00775 {
00776 if( busy() )
00777 report_invalid_modification();
00778
00779 push_back( e );
00780 return *this;
00781 }
00782
00783 inline
00784 sc_event_and_list&
00785 sc_event_and_list::operator &= ( const sc_event_and_list& el )
00786 {
00787 if( busy() )
00788 report_invalid_modification();
00789
00790 push_back( el );
00791 return *this;
00792 }
00793
00794 inline
00795 sc_event_and_expr
00796 sc_event_and_list::operator & ( const sc_event& e )
00797 {
00798 sc_event_and_expr expr;
00799 expr.push_back( *this );
00800 expr.push_back( e );
00801 return expr;
00802 }
00803
00804 inline
00805 sc_event_and_expr
00806 sc_event_and_list::operator & ( const sc_event_and_list& el )
00807 {
00808 sc_event_and_expr expr;
00809 expr.push_back( *this );
00810 expr.push_back( el );
00811 return expr;
00812 }
00813
00814
00815
00816 inline
00817 sc_event_and_expr
00818 sc_event::operator & ( const sc_event& e2 ) const
00819 {
00820 sc_event_and_expr expr;
00821 expr.push_back( *this );
00822 expr.push_back( e2 );
00823 return expr;
00824 }
00825
00826 inline
00827 sc_event_and_expr
00828 sc_event::operator & ( const sc_event_and_list& e2 ) const
00829 {
00830 sc_event_and_expr expr;
00831 expr.push_back( *this );
00832 expr.push_back( e2 );
00833 return expr;
00834 }
00835
00836
00837
00838 inline
00839 sc_event_and_expr
00840 operator & ( sc_event_and_expr expr, sc_event const & e )
00841 {
00842 expr.push_back( e );
00843 return expr;
00844 }
00845
00846 inline
00847 sc_event_and_expr
00848 operator & ( sc_event_and_expr expr, sc_event_and_list const & el )
00849 {
00850 expr.push_back( el );
00851 return expr;
00852 }
00853
00854 }
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926 #endif
00927
00928