Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

sc_event.cpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2004 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 2.3 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 /*****************************************************************************
00019 
00020   sc_event.cpp --
00021 
00022   Original Author: Martin Janssen, Synopsys, Inc., 2001-05-21
00023 
00024  *****************************************************************************/
00025 
00026 /*****************************************************************************
00027 
00028   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00029   changes you are making here.
00030 
00031       Name, Affiliation, Date:
00032   Description of Modification:
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 //  CLASS : sc_event
00045 //
00046 //  The event class.
00047 // ----------------------------------------------------------------------------
00048 
00049 void
00050 sc_event::cancel()
00051 {
00052     // cancel a delta or timed notification
00053     switch( m_notify_type ) {
00054     case DELTA: {
00055         // remove this event from the delta events set
00056         m_simc->remove_delta_event( this );
00057         m_notify_type = NONE;
00058         break;
00059     }
00060     case TIMED: {
00061         // remove this event from the timed events set
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     // immediate notification
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             // remove this event from the timed events set
00094             assert( m_timed != 0 );
00095             m_timed->m_event = 0;
00096             m_timed = 0;
00097         }
00098         // add this event to the delta events set
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         // remove this event from the timed events set
00109         m_timed->m_event = 0;
00110         m_timed = 0;
00111     }
00112     // add this event to the timed events set
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     // clear the dynamic sensitive methods
00127     m_methods_dynamic.erase_all();
00128     // clear the dynamic sensitive threads
00129     m_threads_dynamic.erase_all();
00130 }
00131 
00132 
00133 void
00134 sc_event::trigger()
00135 {
00136     int size;
00137 
00138 
00139     // trigger the static sensitive methods
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     // trigger the dynamic sensitive methods
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     // trigger the static sensitive threads
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     // trigger the dynamic sensitive threads
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 //  CLASS : sc_event_timed
00262 //
00263 //  Class for storing the time to notify a timed event.
00264 // ----------------------------------------------------------------------------
00265 
00266 // dedicated memory management; not MT-Safe
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 //  CLASS : sc_event_list
00310 //
00311 //  Base class for lists of events.
00312 // ----------------------------------------------------------------------------
00313 
00314 void
00315 sc_event_list::push_back( const sc_event& e )
00316 {
00317     // make sure e is not already in the list
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             // event already in the list; ignore
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 // Taf!

Generated on Fri Jan 14 08:29:01 2005 for SystemC2.1beta11(excludingMSLib)(IncludingSCV)\nProvidedby:www.openverificationfoundation.org by doxygen1.2.18