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     bool busy()        const;
00159     bool temporary()   const;
00160     void auto_delete() const;
00161 
00162     void report_premature_destruction() const;
00163     void report_invalid_modification()  const;
00164 
00165 private:
00166 
00167     std::vector<const sc_event*> m_events;
00168     bool                         m_and_list;
00169     bool                         m_auto_delete;
00170     mutable unsigned             m_busy;
00171 };
00172 
00173 
00174 
00180 class sc_event_and_list
00181 : public sc_event_list
00182 {
00183     friend class sc_event;
00184     friend class sc_event_expr<sc_event_and_list>;
00185     friend class sc_process_b;
00186     friend class sc_method_process;
00187     friend class sc_thread_process;
00188 
00189 protected:
00190 
00191     explicit
00192     sc_event_and_list( bool auto_delete_ );
00193 
00194 public:
00195 
00196     sc_event_and_list();
00197     sc_event_and_list( const sc_event& );
00198 
00199     void swap( sc_event_and_list& );
00200     sc_event_and_list& operator &= ( const sc_event& );
00201     sc_event_and_list& operator &= ( const sc_event_and_list & );
00202 
00203     sc_event_expr<sc_event_and_list>  operator & ( const sc_event& );
00204     sc_event_expr<sc_event_and_list>  operator & ( const sc_event_and_list& );
00205 };
00206 
00207 typedef sc_event_expr<sc_event_and_list> sc_event_and_expr;
00208 
00209 
00215 class sc_event_or_list
00216 : public sc_event_list
00217 {
00218     friend class sc_event;
00219     friend class sc_event_expr<sc_event_or_list>;
00220     friend class sc_process_b;
00221     friend class sc_method_process;
00222     friend class sc_thread_process;
00223 
00224 protected:
00225 
00226     explicit
00227     sc_event_or_list( bool auto_delete_ );
00228 
00229 public:
00230     sc_event_or_list();
00231     sc_event_or_list( const sc_event& );
00232     void swap( sc_event_or_list& );
00233     sc_event_or_list& operator |= ( const sc_event& );
00234     sc_event_or_list& operator |= ( const sc_event_or_list & );
00235     sc_event_expr<sc_event_or_list>  operator | ( const sc_event& ) const;
00236     sc_event_expr<sc_event_or_list>  operator | ( const sc_event_or_list& ) const;
00237 };
00238 
00239 typedef sc_event_expr<sc_event_or_list> sc_event_or_expr;
00240 
00241 
00247 class sc_event
00248 {
00249     friend class sc_clock;
00250     friend class sc_event_list;
00251     friend class sc_event_timed;
00252     friend class sc_simcontext;
00253     friend class sc_object;
00254     friend class sc_process_b;
00255     friend class sc_method_process;
00256     friend class sc_thread_process;
00257     template<typename IF, sc_writer_policy POL> friend class sc_signal;
00258     friend void sc_thread_cor_fn( void* arg );
00259 
00260 public:
00261         
00262         std::vector<sc_timestamp>    m_notify_timestamp_list;
00263     sc_event();
00264     sc_event( const char* name );
00265     ~sc_event();
00266 
00267     void cancel();
00268 
00269     const char* name() const             { return m_name.c_str(); }
00270     const char* basename() const;
00271     sc_object* get_parent_object() const { return m_parent_p; }
00272     bool in_hierarchy() const            { return m_name.length() != 0; }
00273 
00278     
00279     void notify();
00280 
00281     void notify( const sc_time& );
00282     void notify( double, sc_time_unit );
00283 
00284     void notify_delayed();
00285     void notify_delayed( const sc_time& );
00286     void notify_delayed( double, sc_time_unit );
00287 
00288     sc_event_or_expr  operator | ( const sc_event& ) const; 
00289     sc_event_or_expr  operator | ( const sc_event_or_list& ) const;
00290     sc_event_and_expr operator & ( const sc_event& ) const;
00291     sc_event_and_expr operator & ( const sc_event_and_list& ) const;
00292 
00296     
00297     const sc_timestamp& get_notify_timestamp() const;
00298         void push_notify_timestamp_list( const sc_timestamp& ts );
00299         const sc_timestamp& get_notify_timestamp_last() const;
00300         mutable std::vector<sc_method_handle> m_methods_static;
00301     mutable std::vector<sc_method_handle> m_methods_dynamic;
00302     mutable std::vector<sc_thread_handle> m_threads_static;
00303         mutable std::vector<sc_thread_handle> m_threads_dynamic;
00304 private:
00305 
00306     void add_static( sc_method_handle ) const;
00307     void add_static( sc_thread_handle ) const;
00308     void add_dynamic( sc_method_handle ) const;
00309     void add_dynamic( sc_thread_handle ) const;
00310 
00311     void notify_internal( const sc_time& );
00312     void notify_next_delta();
00313 
00314     bool remove_static( sc_method_handle ) const;
00315     bool remove_static( sc_thread_handle ) const;
00316     bool remove_dynamic( sc_method_handle ) const;
00317     bool remove_dynamic( sc_thread_handle ) const;
00318 
00319     void register_event( const char* name );
00320     void reset();
00321 
00322     void trigger();
00323 
00324     
00328     
00329     void set_notify_timestamp( const sc_timestamp& ts );
00330 
00331 private:
00332 
00333     enum notify_t { NONE, DELTA, TIMED };
00334 
00335     std::string     m_name;     
00336     sc_object*      m_parent_p; 
00337     sc_simcontext*  m_simc;
00338     
00339     
00340     sc_event_timed* m_timed;
00341 
00342     
00343    
00344 
00348     
00349     sc_timestamp    m_notify_timestamp;
00350 
00351 private:
00352 
00353     
00354     sc_event( const sc_event& );
00355     sc_event& operator = ( const sc_event& );
00356         notify_t        m_notify_type;
00357         
00358 public:
00359         int             m_delta_event_index;
00360 };
00361 
00362 #define SC_KERNEL_EVENT_PREFIX "$$$$kernel_event$$$$_"
00363 
00364 extern sc_event sc_non_event; 
00365 
00366 
00372 class sc_event_timed
00373 {
00374     friend class sc_event;
00375     friend class sc_simcontext;
00376 
00377     friend int sc_notify_time_compare( const void*, const void* );
00378 
00379 private:
00380 
00381     sc_event_timed( sc_event* e, const sc_time& t )
00382         : m_event( e ), m_notify_time( t )
00383         {}
00384 
00385     ~sc_event_timed()
00386         { if( m_event != 0 ) { m_event->m_timed = 0; } }
00387 
00388     sc_event* event() const
00389         { return m_event; }
00390 
00391     const sc_time& notify_time() const
00392         { return m_notify_time; }
00393 
00394     static void* operator new( std::size_t )
00395         { return allocate(); }
00396 
00397     static void operator delete( void* p, std::size_t )
00398         { deallocate( p ); }
00399 
00400 private:
00401 
00402     
00403     static void* allocate();
00404     static void  deallocate( void* );
00405 
00406 private:
00407 
00408     sc_event* m_event;
00409     sc_time   m_notify_time;
00410 
00411 private:
00412 
00413     
00414     sc_event_timed();
00415     sc_event_timed( const sc_event_timed& );
00416     sc_event_timed& operator = ( const sc_event_timed& );
00417 };
00418 
00419 
00420 
00421 
00422 inline
00423 void
00424 sc_event::notify( double v, sc_time_unit tu )
00425 {
00426     notify( sc_time( v, tu, m_simc ) );
00427 }
00428 
00429 
00430 inline
00431 void
00432 sc_event::notify_internal( const sc_time& t )
00433 {
00434     
00435     sc_process_b* m_proc = m_simc->get_curr_proc();
00436 
00437     if( t == SC_ZERO_TIME ) {
00438         
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448                 sc_event_timed* et = new sc_event_timed( this,
00449                                  m_proc->get_timestamp().get_time_count() + t );
00450         m_simc->add_timed_event( et );
00451         m_timed = et;
00452         m_notify_type = TIMED;
00453         
00454         
00455         set_notify_timestamp( sc_timestamp( m_proc->get_timestamp().
00456                                             get_time_count() , m_proc->get_timestamp().
00457                                             get_delta_count() +1 ) );
00458     } else {
00459         
00460         
00461         
00462         
00463         sc_event_timed* et = new sc_event_timed( this,
00464                                  m_proc->get_timestamp().get_time_count() + t );
00465         m_simc->add_timed_event( et );
00466         m_timed = et;
00467         m_notify_type = TIMED;
00468         
00469         
00470         set_notify_timestamp( sc_timestamp( m_proc->get_timestamp().
00471                                             get_time_count() + t, 0 ) );
00472     }
00473 }
00474 
00475 inline
00476 void
00477 sc_event::notify_next_delta()
00478 {
00479     
00480     sc_process_b* m_proc = m_simc->get_curr_proc();
00481 
00482     if( m_notify_type != NONE ) {
00483         SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
00484     }
00485 
00486     
00487     set_notify_timestamp( m_proc->get_timestamp() );
00488 
00489     
00490     m_delta_event_index = m_simc->add_delta_event( this );
00491     m_notify_type = DELTA;
00492 }
00493 
00494 inline
00495 void
00496 sc_event::notify_delayed( double v, sc_time_unit tu )
00497 {
00498     notify_delayed( sc_time( v, tu, m_simc ) );
00499 }
00500 
00501 
00502 inline
00503 void
00504 sc_event::add_static( sc_method_handle method_h ) const
00505 {
00506     m_methods_static.push_back( method_h );
00507 }
00508 
00509 inline
00510 void
00511 sc_event::add_static( sc_thread_handle thread_h ) const
00512 {
00513     m_threads_static.push_back( thread_h );
00514 }
00515 
00516 inline
00517 void
00518 sc_event::add_dynamic( sc_method_handle method_h ) const
00519 {
00520     m_methods_dynamic.push_back( method_h );
00521 }
00522 
00523 inline
00524 void
00525 sc_event::add_dynamic( sc_thread_handle thread_h ) const
00526 {
00527     
00528     m_threads_dynamic.push_back( thread_h );
00529 }
00530 
00531 
00532 
00533 
00534 
00535 
00536 extern void notify( sc_event& e );
00537 extern void notify( const sc_time& t, sc_event& e );
00538 extern void notify( double v, sc_time_unit tu, sc_event& e );
00539 
00540 
00541 
00542 
00543 inline
00544 sc_event_list::sc_event_list( bool and_list_, bool auto_delete_ ) 
00545   : m_events() 
00546   , m_and_list( and_list_ ) 
00547   , m_auto_delete( auto_delete_ ) 
00548   , m_busy( 0 )
00549 {
00550 }
00551 
00552 inline
00553 sc_event_list::sc_event_list( const sc_event& e,
00554                               bool and_list_,
00555                               bool auto_delete_ )
00556   : m_events()
00557   , m_and_list( and_list_ )
00558   , m_auto_delete( auto_delete_ )
00559   , m_busy(0)
00560 {
00561     m_events.push_back( &e );
00562 }
00563 
00564 inline
00565 sc_event_list::sc_event_list( sc_event_list const & that )
00566   : m_events()
00567   , m_and_list( that.m_and_list )
00568   , m_auto_delete( false )
00569   , m_busy( 0 )
00570 {
00571     move_from( that );
00572     that.auto_delete(); 
00573 }
00574 
00575 inline
00576 sc_event_list&
00577 sc_event_list::operator=( sc_event_list const & that )
00578 {
00579     if( m_busy )
00580         report_invalid_modification();
00581 
00582     move_from( that );
00583     that.auto_delete(); 
00584 
00585     return *this;
00586 }
00587 
00588 inline
00589 sc_event_list::~sc_event_list()
00590 {
00591     if( m_busy )
00592         report_premature_destruction();
00593 }
00594 
00595 inline
00596 void
00597 sc_event_list::swap( sc_event_list& that )
00598 {
00599     if( busy() || that.busy() )
00600         report_invalid_modification();
00601     m_events.swap( that.m_events );
00602 }
00603 
00604 inline
00605 void
00606 sc_event_list::move_from( sc_event_list const&  that )
00607 {
00608     if( that.temporary() ) {
00609         swap( const_cast<sc_event_list&>(that) ); 
00610     } else {
00611         m_events = that.m_events;                 
00612     }
00613 }
00614 
00615 inline
00616 int
00617 sc_event_list::size() const
00618 {
00619     return m_events.size();
00620 }
00621 
00622 inline
00623 bool
00624 sc_event_list::and_list() const
00625 {
00626     return m_and_list;
00627 }
00628 
00629 
00630 inline
00631 bool
00632 sc_event_list::busy() const
00633 {
00634     return m_busy != 0;
00635 }
00636 
00637 
00638 inline
00639 bool
00640 sc_event_list::temporary() const
00641 {
00642     return m_auto_delete && ! m_busy;
00643 }
00644 
00645 inline
00646 void
00647 sc_event_list::auto_delete() const
00648 {
00649     if( m_busy ) {
00650         --m_busy;
00651     }
00652     if( ! m_busy && m_auto_delete ) {
00653         delete this;
00654     }
00655 }
00656 
00657 
00658 
00659 
00660 
00661 inline
00662 sc_event_or_list::sc_event_or_list()
00663   : sc_event_list( false )
00664 {}
00665 
00666 inline
00667 sc_event_or_list::sc_event_or_list( const sc_event& e )
00668 : sc_event_list( false )
00669 {
00670   push_back( e );
00671 }
00672 
00673 inline
00674 sc_event_or_list::sc_event_or_list( bool auto_delete_ )
00675 : sc_event_list( false, auto_delete_ )
00676 {}
00677 
00678 inline
00679 sc_event_or_list&
00680 sc_event_or_list::operator |= ( const sc_event& e )
00681 {
00682     if( busy() )
00683         report_invalid_modification();
00684 
00685     push_back( e );
00686     return *this;
00687 }
00688 
00689 inline
00690 sc_event_or_list&
00691 sc_event_or_list::operator |= ( const sc_event_or_list& el )
00692 {
00693     if( busy() )
00694         report_invalid_modification();
00695 
00696     push_back( el );
00697     return *this;
00698 }
00699 
00700 inline
00701 sc_event_or_expr
00702 sc_event_or_list::operator | ( const sc_event& e2 ) const
00703 {
00704     sc_event_or_expr expr;
00705     expr.push_back( *this );
00706     expr.push_back( e2 );
00707     return expr;
00708 }
00709 
00710 inline
00711 sc_event_or_expr
00712 sc_event_or_list::operator | ( const sc_event_or_list& 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 
00721 
00722 
00723 inline
00724 sc_event_or_expr
00725 sc_event::operator | ( const sc_event& e2 ) const
00726 {
00727     sc_event_or_expr expr;
00728     expr.push_back( *this );
00729     expr.push_back( e2 );
00730     return expr;
00731 }
00732 
00733 inline
00734 sc_event_or_expr
00735 sc_event::operator | ( const sc_event_or_list& 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 
00744 
00745 inline
00746 sc_event_or_expr
00747 operator | ( sc_event_or_expr expr, sc_event const & e )
00748 {
00749     expr.push_back( e );
00750     return expr;
00751 }
00752 
00753 inline
00754 sc_event_or_expr
00755 operator | ( sc_event_or_expr expr, sc_event_or_list const & el )
00756 {
00757     expr.push_back( el );
00758     return expr;
00759 }
00760 
00761 inline
00762 void
00763 sc_event_or_list::swap( sc_event_or_list & that )
00764 {
00765   sc_event_list::swap( that );
00766 }
00767 
00768 
00769 
00770 
00771 
00772 inline
00773 sc_event_and_list::sc_event_and_list()
00774   : sc_event_list( true )
00775 {}
00776 
00777 inline
00778 sc_event_and_list::sc_event_and_list( const sc_event& e )
00779 : sc_event_list( true )
00780 {
00781   push_back( e );
00782 }
00783 
00784 inline
00785 sc_event_and_list::sc_event_and_list( bool auto_delete_ )
00786 : sc_event_list( true, auto_delete_ )
00787 {}
00788 
00789 inline
00790 void
00791 sc_event_and_list::swap( sc_event_and_list & that )
00792 {
00793   sc_event_list::swap( that );
00794 }
00795 
00796 
00797 inline
00798 sc_event_and_list&
00799 sc_event_and_list::operator &= ( const sc_event& e )
00800 {
00801     if( busy() )
00802         report_invalid_modification();
00803 
00804     push_back( e );
00805     return *this;
00806 }
00807 
00808 inline
00809 sc_event_and_list&
00810 sc_event_and_list::operator &= ( const sc_event_and_list& el )
00811 {
00812     if( busy() )
00813         report_invalid_modification();
00814 
00815     push_back( el );
00816     return *this;
00817 }
00818 
00819 inline
00820 sc_event_and_expr
00821 sc_event_and_list::operator & ( const sc_event& e )
00822 {
00823     sc_event_and_expr expr;
00824     expr.push_back( *this );
00825     expr.push_back( e );
00826     return expr;
00827 }
00828 
00829 inline
00830 sc_event_and_expr
00831 sc_event_and_list::operator & ( const sc_event_and_list& el )
00832 {
00833     sc_event_and_expr expr;
00834     expr.push_back( *this );
00835     expr.push_back( el );
00836     return expr;
00837 }
00838 
00839 
00840 
00841 inline
00842 sc_event_and_expr
00843 sc_event::operator & ( const sc_event& e2 ) const
00844 {
00845     sc_event_and_expr expr;
00846     expr.push_back( *this );
00847     expr.push_back( e2 );
00848     return expr;
00849 }
00850 
00851 inline
00852 sc_event_and_expr
00853 sc_event::operator & ( const sc_event_and_list& 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 
00862 
00863 inline
00864 sc_event_and_expr
00865 operator & ( sc_event_and_expr expr, sc_event const & e )
00866 {
00867     expr.push_back( e );
00868     return expr;
00869 }
00870 
00871 inline
00872 sc_event_and_expr
00873 operator & ( sc_event_and_expr expr, sc_event_and_list const & el )
00874 {
00875     expr.push_back( el );
00876     return expr;
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 
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 #endif
00952 
00953