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