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