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
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef SC_EVENT_H
00037 #define SC_EVENT_H
00038
00039
00040 #include "systemc/kernel/sc_kernel_ids.h"
00041 #include "systemc/kernel/sc_simcontext.h"
00042 #include "systemc/utils/sc_vector.h"
00043
00044
00045
00046 class sc_event_timed;
00047 class sc_event_list;
00048 class sc_event_or_list;
00049 class sc_event_and_list;
00050
00051
00052
00053
00054
00055
00056
00057
00058 class sc_event
00059 {
00060 friend class sc_clock;
00061 friend class sc_event_list;
00062 friend class sc_event_timed;
00063 friend class sc_simcontext;
00064 friend class sc_process_b;
00065 friend class sc_method_process;
00066 friend class sc_thread_process;
00067
00068 public:
00069
00070 sc_event();
00071 ~sc_event();
00072
00073 void cancel();
00074
00075 void notify();
00076 void notify( const sc_time& );
00077 void notify( double, sc_time_unit );
00078
00079 void notify_delayed();
00080 void notify_delayed( const sc_time& );
00081 void notify_delayed( double, sc_time_unit );
00082
00083 sc_event_or_list& operator | ( const sc_event& ) const;
00084 sc_event_and_list& operator & ( const sc_event& ) const;
00085
00086 private:
00087
00088 void reset();
00089
00090 void trigger();
00091
00092 void add_static( sc_method_handle ) const;
00093 void add_static( sc_thread_handle ) const;
00094 void add_dynamic( sc_method_handle ) const;
00095 void add_dynamic( sc_thread_handle ) const;
00096
00097 bool remove_static( sc_method_handle ) const;
00098 bool remove_static( sc_thread_handle ) const;
00099 bool remove_dynamic( sc_method_handle ) const;
00100 bool remove_dynamic( sc_thread_handle ) const;
00101
00102 private:
00103
00104 enum notify_t { NONE, DELTA, TIMED };
00105
00106 sc_simcontext* m_simc;
00107 notify_t m_notify_type;
00108 int m_delta;
00109 sc_event_timed* m_timed;
00110
00111 mutable sc_pvector<sc_method_handle> m_methods_static;
00112 mutable sc_pvector<sc_method_handle> m_methods_dynamic;
00113 mutable sc_pvector<sc_thread_handle> m_threads_static;
00114 mutable sc_pvector<sc_thread_handle> m_threads_dynamic;
00115
00116 private:
00117
00118
00119 sc_event( const sc_event& );
00120 sc_event& operator = ( const sc_event& );
00121 };
00122
00123
00124
00125
00126
00127
00128
00129
00130 class sc_event_timed
00131 {
00132 friend class sc_event;
00133 friend class sc_simcontext;
00134
00135 friend int sc_notify_time_compare( const void*, const void* );
00136
00137 private:
00138
00139 sc_event_timed( sc_event* e, const sc_time& t )
00140 : m_event( e ), m_notify_time( t )
00141 {}
00142
00143 ~sc_event_timed()
00144 { if( m_event != 0 ) { m_event->m_timed = 0; } }
00145
00146 sc_event* event() const
00147 { return m_event; }
00148
00149 const sc_time& notify_time() const
00150 { return m_notify_time; }
00151
00152 static void* operator new( size_t )
00153 { return allocate(); }
00154
00155 static void operator delete( void* p, size_t )
00156 { deallocate( p ); }
00157
00158 private:
00159
00160
00161 static void* allocate();
00162 static void deallocate( void* );
00163
00164 private:
00165
00166 sc_event* m_event;
00167 sc_time m_notify_time;
00168
00169 private:
00170
00171
00172 sc_event_timed();
00173 sc_event_timed( const sc_event_timed& );
00174 sc_event_timed& operator = ( const sc_event_timed& );
00175 };
00176
00177
00178
00179
00180 inline
00181 sc_event::sc_event()
00182 : m_simc( sc_get_curr_simcontext() ),
00183 m_notify_type( NONE ),
00184 m_delta( -1 ),
00185 m_timed( 0 )
00186 {}
00187
00188 inline
00189 sc_event::~sc_event()
00190 {
00191 cancel();
00192 }
00193
00194
00195 inline
00196 void
00197 sc_event::notify( double v, sc_time_unit tu )
00198 {
00199 notify( sc_time( v, tu, m_simc ) );
00200 }
00201
00202
00203 inline
00204 void
00205 sc_event::notify_delayed()
00206 {
00207 if( m_notify_type != NONE ) {
00208 SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
00209 }
00210
00211 m_delta = m_simc->add_delta_event( this );
00212 m_notify_type = DELTA;
00213 }
00214
00215 inline
00216 void
00217 sc_event::notify_delayed( const sc_time& t )
00218 {
00219 if( m_notify_type != NONE ) {
00220 SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
00221 }
00222 if( t == SC_ZERO_TIME ) {
00223
00224 m_delta = m_simc->add_delta_event( this );
00225 m_notify_type = DELTA;
00226 } else {
00227
00228 sc_event_timed* et = new sc_event_timed( this,
00229 m_simc->time_stamp() + t );
00230 m_simc->add_timed_event( et );
00231 m_timed = et;
00232 m_notify_type = TIMED;
00233 }
00234 }
00235
00236 inline
00237 void
00238 sc_event::notify_delayed( double v, sc_time_unit tu )
00239 {
00240 notify_delayed( sc_time( v, tu, m_simc ) );
00241 }
00242
00243
00244 inline
00245 void
00246 sc_event::add_static( sc_method_handle method_h ) const
00247 {
00248 m_methods_static.push_back( method_h );
00249 }
00250
00251 inline
00252 void
00253 sc_event::add_static( sc_thread_handle thread_h ) const
00254 {
00255 m_threads_static.push_back( thread_h );
00256 }
00257
00258 inline
00259 void
00260 sc_event::add_dynamic( sc_method_handle method_h ) const
00261 {
00262 m_methods_dynamic.push_back( method_h );
00263 }
00264
00265 inline
00266 void
00267 sc_event::add_dynamic( sc_thread_handle thread_h ) const
00268 {
00269 m_threads_dynamic.push_back( thread_h );
00270 }
00271
00272
00273
00274
00275
00276
00277 inline
00278 void
00279 notify( sc_event& e )
00280 {
00281 e.notify();
00282 }
00283
00284 inline
00285 void
00286 notify( const sc_time& t, sc_event& e )
00287 {
00288 e.notify( t );
00289 }
00290
00291 inline
00292 void
00293 notify( double v, sc_time_unit tu, sc_event& e )
00294 {
00295 e.notify( v, tu );
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305 class sc_event_list
00306 {
00307 friend class sc_method_process;
00308 friend class sc_thread_process;
00309
00310 protected:
00311
00312 void push_back( const sc_event& );
00313
00314 sc_event_list( const sc_event&,
00315 bool and_list_,
00316 bool auto_delete_ = false );
00317
00318 int size() const;
00319 bool and_list() const;
00320
00321 void add_dynamic( sc_method_handle );
00322 void add_dynamic( sc_thread_handle );
00323 void remove_dynamic( sc_method_handle, const sc_event* );
00324 void remove_dynamic( sc_thread_handle, const sc_event* );
00325
00326 void auto_delete();
00327
00328 private:
00329
00330 sc_pvector<const sc_event*> m_events;
00331 bool m_and_list;
00332 bool m_auto_delete;
00333
00334 private:
00335
00336
00337 sc_event_list();
00338 sc_event_list( const sc_event_list& );
00339 sc_event_list& operator = ( const sc_event_list& );
00340 };
00341
00342
00343
00344
00345 inline
00346 sc_event_list::sc_event_list( const sc_event& e,
00347 bool and_list_,
00348 bool auto_delete_ )
00349 : m_and_list( and_list_ ),
00350 m_auto_delete( auto_delete_ )
00351 {
00352 m_events.push_back( &e );
00353 }
00354
00355
00356 inline
00357 int
00358 sc_event_list::size() const
00359 {
00360 return m_events.size();
00361 }
00362
00363 inline
00364 bool
00365 sc_event_list::and_list() const
00366 {
00367 return m_and_list;
00368 }
00369
00370
00371 inline
00372 void
00373 sc_event_list::auto_delete()
00374 {
00375 if( m_auto_delete ) {
00376 delete this;
00377 }
00378 }
00379
00380
00381
00382
00383
00384
00385
00386
00387 class sc_event_or_list
00388 : public sc_event_list
00389 {
00390 friend class sc_event;
00391 friend class sc_method_process;
00392 friend class sc_thread_process;
00393
00394 protected:
00395
00396 sc_event_or_list( const sc_event&, bool auto_delete_ = false );
00397
00398 public:
00399
00400 sc_event_or_list& operator | ( const sc_event& );
00401
00402 private:
00403
00404
00405 sc_event_or_list();
00406 sc_event_or_list( const sc_event_or_list& );
00407 sc_event_or_list& operator = ( const sc_event_or_list& );
00408 };
00409
00410
00411
00412
00413 inline
00414 sc_event_or_list::sc_event_or_list( const sc_event& e,
00415 bool auto_delete_ )
00416 : sc_event_list( e, false, auto_delete_ )
00417 {}
00418
00419
00420 inline
00421 sc_event_or_list&
00422 sc_event_or_list::operator | ( const sc_event& e )
00423 {
00424 push_back( e );
00425 return *this;
00426 }
00427
00428
00429
00430
00431 inline
00432 sc_event_or_list&
00433 sc_event::operator | ( const sc_event& e2 ) const
00434 {
00435 sc_event_or_list* el = new sc_event_or_list( *this, true );
00436 el->push_back( e2 );
00437 return *el;
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447 class sc_event_and_list
00448 : public sc_event_list
00449 {
00450 friend class sc_event;
00451 friend class sc_method_process;
00452 friend class sc_thread_process;
00453
00454 protected:
00455
00456 sc_event_and_list( const sc_event&, bool auto_delete_ = false );
00457
00458 public:
00459
00460 sc_event_and_list& operator & ( const sc_event& );
00461
00462 private:
00463
00464
00465 sc_event_and_list();
00466 sc_event_and_list( const sc_event_and_list& );
00467 sc_event_and_list& operator = ( const sc_event_and_list& );
00468 };
00469
00470
00471
00472
00473 inline
00474 sc_event_and_list::sc_event_and_list( const sc_event& e,
00475 bool auto_delete_ )
00476 : sc_event_list( e, true, auto_delete_ )
00477 {}
00478
00479
00480 inline
00481 sc_event_and_list&
00482 sc_event_and_list::operator & ( const sc_event& e )
00483 {
00484 push_back( e );
00485 return *this;
00486 }
00487
00488
00489
00490
00491 inline
00492 sc_event_and_list&
00493 sc_event::operator & ( const sc_event& e2 ) const
00494 {
00495 sc_event_and_list* el = new sc_event_and_list( *this, true );
00496 el->push_back( e2 );
00497 return *el;
00498 }
00499
00500
00501 #endif
00502
00503