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