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