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 #include "systemc/kernel/sc_event.h"
00038 #include "systemc/kernel/sc_kernel_ids.h"
00039 #include "systemc/kernel/sc_process_int.h"
00040 #include "systemc/kernel/sc_simcontext_int.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049 void
00050 sc_event::cancel()
00051 {
00052
00053 switch( m_notify_type ) {
00054 case DELTA: {
00055
00056 m_simc->remove_delta_event( this );
00057 m_notify_type = NONE;
00058 break;
00059 }
00060 case TIMED: {
00061
00062 assert( m_timed != 0 );
00063 m_timed->m_event = 0;
00064 m_timed = 0;
00065 m_notify_type = NONE;
00066 break;
00067 }
00068 default:
00069 ;
00070 }
00071 }
00072
00073
00074 void
00075 sc_event::notify()
00076 {
00077
00078 if( m_simc->update_phase() ) {
00079 SC_REPORT_ERROR( SC_ID_IMMEDIATE_NOTIFICATION_, "" );
00080 }
00081 cancel();
00082 trigger();
00083 }
00084
00085 void
00086 sc_event::notify( const sc_time& t )
00087 {
00088 if( m_notify_type == DELTA ) {
00089 return;
00090 }
00091 if( t == SC_ZERO_TIME ) {
00092 if( m_notify_type == TIMED ) {
00093
00094 assert( m_timed != 0 );
00095 m_timed->m_event = 0;
00096 m_timed = 0;
00097 }
00098
00099 m_delta = m_simc->add_delta_event( this );
00100 m_notify_type = DELTA;
00101 return;
00102 }
00103 if( m_notify_type == TIMED ) {
00104 assert( m_timed != 0 );
00105 if( m_timed->m_notify_time <= m_simc->time_stamp() + t ) {
00106 return;
00107 }
00108
00109 m_timed->m_event = 0;
00110 m_timed = 0;
00111 }
00112
00113 sc_event_timed* et = new sc_event_timed( this, m_simc->time_stamp() + t );
00114 m_simc->add_timed_event( et );
00115 m_timed = et;
00116 m_notify_type = TIMED;
00117 }
00118
00119
00120 void
00121 sc_event::reset()
00122 {
00123 m_notify_type = NONE;
00124 m_delta = -1;
00125 m_timed = 0;
00126
00127 m_methods_dynamic.erase_all();
00128
00129 m_threads_dynamic.erase_all();
00130 }
00131
00132
00133 void
00134 sc_event::trigger()
00135 {
00136 int size;
00137
00138
00139
00140
00141 if( ( size = m_methods_static.size() ) != 0 ) {
00142 sc_method_handle* l_methods_static = m_methods_static.raw_data();
00143 int i = size - 1;
00144 do {
00145 sc_method_handle method_h = l_methods_static[i];
00146 if( method_h->trigger_static() ) {
00147 m_simc->push_runnable_method( method_h );
00148 }
00149 } while( -- i >= 0 );
00150 }
00151
00152
00153
00154 if( ( size = m_methods_dynamic.size() ) != 0 ) {
00155 sc_method_handle* l_methods_dynamic = m_methods_dynamic.raw_data();
00156 int i = size - 1;
00157 do {
00158 sc_method_handle method_h = l_methods_dynamic[i];
00159 if( method_h->trigger_dynamic( this ) ) {
00160 m_simc->push_runnable_method( method_h );
00161 }
00162 } while( -- i >= 0 );
00163 m_methods_dynamic.erase_all();
00164 }
00165
00166
00167
00168 if( ( size = m_threads_static.size() ) != 0 ) {
00169 sc_thread_handle* l_threads_static = m_threads_static.raw_data();
00170 int i = size - 1;
00171 do {
00172 sc_thread_handle thread_h = l_threads_static[i];
00173 if( thread_h->trigger_static() ) {
00174 m_simc->push_runnable_thread( thread_h );
00175 }
00176 } while( -- i >= 0 );
00177 }
00178
00179
00180
00181 if( ( size = m_threads_dynamic.size() ) != 0 ) {
00182 sc_thread_handle* l_threads_dynamic = m_threads_dynamic.raw_data();
00183 int i = size - 1;
00184 do {
00185 sc_thread_handle thread_h = l_threads_dynamic[i];
00186 if( thread_h->trigger_dynamic( this ) ) {
00187 m_simc->push_runnable_thread( thread_h );
00188 }
00189 } while( -- i >= 0 );
00190 m_threads_dynamic.erase_all();
00191 }
00192
00193 m_notify_type = NONE;
00194 m_delta = -1;
00195 m_timed = 0;
00196 }
00197
00198
00199 bool
00200 sc_event::remove_static( sc_method_handle method_h_ ) const
00201 {
00202 int size = m_methods_static.size();
00203 sc_method_handle* l_methods_static = m_methods_static.raw_data();
00204 for( int i = size - 1; i >= 0; -- i ) {
00205 if( l_methods_static[i] == method_h_ ) {
00206 l_methods_static[i] = l_methods_static[size - 1];
00207 m_methods_static.decr_count();
00208 return true;
00209 }
00210 }
00211 return false;
00212 }
00213
00214 bool
00215 sc_event::remove_static( sc_thread_handle thread_h_ ) const
00216 {
00217 int size = m_threads_static.size();
00218 sc_thread_handle* l_threads_static = m_threads_static.raw_data();
00219 for( int i = size - 1; i >= 0; -- i ) {
00220 if( l_threads_static[i] == thread_h_ ) {
00221 l_threads_static[i] = l_threads_static[size - 1];
00222 m_threads_static.decr_count();
00223 return true;
00224 }
00225 }
00226 return false;
00227 }
00228
00229 bool
00230 sc_event::remove_dynamic( sc_method_handle method_h_ ) const
00231 {
00232 int size = m_methods_dynamic.size();
00233 sc_method_handle* l_methods_dynamic = m_methods_dynamic.raw_data();
00234 for( int i = size - 1; i >= 0; -- i ) {
00235 if( l_methods_dynamic[i] == method_h_ ) {
00236 l_methods_dynamic[i] = l_methods_dynamic[size - 1];
00237 m_methods_dynamic.decr_count();
00238 return true;
00239 }
00240 }
00241 return false;
00242 }
00243
00244 bool
00245 sc_event::remove_dynamic( sc_thread_handle thread_h_ ) const
00246 {
00247 int size = m_threads_dynamic.size();
00248 sc_thread_handle* l_threads_dynamic = m_threads_dynamic.raw_data();
00249 for( int i = size - 1; i >= 0; -- i ) {
00250 if( l_threads_dynamic[i] == thread_h_ ) {
00251 l_threads_dynamic[i] = l_threads_dynamic[size - 1];
00252 m_threads_dynamic.decr_count();
00253 return true;
00254 }
00255 }
00256 return false;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 union sc_event_timed_u
00269 {
00270 sc_event_timed_u* next;
00271 char dummy[sizeof( sc_event_timed )];
00272 };
00273
00274 static
00275 sc_event_timed_u* free_list = 0;
00276
00277 void*
00278 sc_event_timed::allocate()
00279 {
00280 const int ALLOC_SIZE = 64;
00281
00282 if( free_list == 0 ) {
00283 free_list = (sc_event_timed_u*) malloc( ALLOC_SIZE *
00284 sizeof( sc_event_timed ) );
00285 int i = 0;
00286 for( ; i < ALLOC_SIZE - 1; ++ i ) {
00287 free_list[i].next = &free_list[i + 1];
00288 }
00289 free_list[i].next = 0;
00290 }
00291
00292 sc_event_timed_u* q = free_list;
00293 free_list = free_list->next;
00294 return q;
00295 }
00296
00297 void
00298 sc_event_timed::deallocate( void* p )
00299 {
00300 if( p != 0 ) {
00301 sc_event_timed_u* q = RCAST<sc_event_timed_u*>( p );
00302 q->next = free_list;
00303 free_list = q;
00304 }
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314 void
00315 sc_event_list::push_back( const sc_event& e )
00316 {
00317
00318 const sc_event** l_events = m_events.raw_data();
00319 for( int i = m_events.size() - 1; i >= 0; -- i ) {
00320 if( &e == l_events[i] ) {
00321
00322 return;
00323 }
00324 }
00325 m_events.push_back( &e );
00326 }
00327
00328
00329 void
00330 sc_event_list::add_dynamic( sc_method_handle method_h )
00331 {
00332 const sc_event** l_events = m_events.raw_data();
00333 for( int i = m_events.size() - 1; i >= 0; -- i ) {
00334 l_events[i]->add_dynamic( method_h );
00335 }
00336 }
00337
00338 void
00339 sc_event_list::add_dynamic( sc_thread_handle thread_h )
00340 {
00341 const sc_event** l_events = m_events.raw_data();
00342 for( int i = m_events.size() - 1; i >= 0; -- i ) {
00343 l_events[i]->add_dynamic( thread_h );
00344 }
00345 }
00346
00347 void
00348 sc_event_list::remove_dynamic( sc_method_handle method_h,
00349 const sc_event* e_not )
00350 {
00351 const sc_event** l_events = m_events.raw_data();
00352 for( int i = m_events.size() - 1; i >= 0; -- i ) {
00353 const sc_event* e = l_events[i];
00354 if( e != e_not ) {
00355 e->remove_dynamic( method_h );
00356 }
00357 }
00358 }
00359
00360 void
00361 sc_event_list::remove_dynamic( sc_thread_handle thread_h,
00362 const sc_event* e_not )
00363 {
00364 const sc_event** l_events = m_events.raw_data();
00365 for( int i = m_events.size() - 1; i >= 0; -- i ) {
00366 const sc_event* e = l_events[i];
00367 if( e != e_not ) {
00368 e->remove_dynamic( thread_h );
00369 }
00370 }
00371 }
00372
00373
00374