sc_process.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-2006 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.4 (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_process.cpp -- Base process implementation.
00021 
00022   Original Authors: Andy Goodrich, Forte Design Systems, 17 June 2003
00023                     Stuart Swan, Cadence
00024                     Bishnupriya Bhattacharya, Cadence Design Systems,
00025                     25 August, 2003
00026 
00027  *****************************************************************************/
00028 
00029 /*****************************************************************************
00030 
00031   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00032   changes you are making here.
00033 
00034       Name, Affiliation, Date: Andy Goodrich, Forte Design Systems, 12 Aug 05
00035   Description of Modification: This is the rewrite of process support. It 
00036                                contains some code from the now-defunct 
00037                                sc_process_b.cpp, as well as the former 
00038                                version of sc_process_b.cpp.
00039 
00040       Name, Affiliation, Date:
00041   Description of Modification:
00042 
00043  *****************************************************************************/
00044 
00045 // $Log: sc_process.cpp,v $
00046 // Revision 1.1.1.1  2006/12/15 20:31:37  acg
00047 // SystemC 2.2
00048 //
00049 // Revision 1.5  2006/04/11 23:13:21  acg
00050 //   Andy Goodrich: Changes for reduced reset support that only includes
00051 //   sc_cthread, but has preliminary hooks for expanding to method and thread
00052 //   processes also.
00053 //
00054 // Revision 1.4  2006/01/24 20:49:05  acg
00055 // Andy Goodrich: changes to remove the use of deprecated features within the
00056 // simulator, and to issue warning messages when deprecated features are used.
00057 //
00058 // Revision 1.3  2006/01/13 18:44:30  acg
00059 // Added $Log to record CVS changes into the source.
00060 //
00061 
00062 #include "sysc/kernel/sc_name_gen.h"
00063 #include "sysc/kernel/sc_cthread_process.h"
00064 #include "sysc/kernel/sc_method_process.h"
00065 #include "sysc/kernel/sc_thread_process.h"
00066 #include "sysc/kernel/sc_sensitive.h"
00067 #include "sysc/kernel/sc_process_handle.h"
00068 
00069 namespace sc_core {
00070 
00071 // sc_process_handle entities that are returned for null pointer instances:
00072 
00073 std::vector<sc_object*> sc_process_handle::empty_vector;
00074 sc_event                sc_process_handle::non_event;
00075 
00076 // Process to delete next:
00077 sc_process_b* sc_process_b::m_delete_next_p = 0;
00078 
00079 // Last process that was created:
00080 sc_process_b* sc_process_b::m_last_created_process_p = 0;
00081 
00082 //------------------------------------------------------------------------------
00083 //"sc_process_b::add_static_event"
00084 //
00085 // This method adds an event to the list of static events, and sets the
00086 // event up to call back this process when it fires.
00087 //------------------------------------------------------------------------------
00088 void sc_process_b::add_static_event( const sc_event& e )
00089 {
00090     sc_method_handle method_h; // This process as a method.
00091     sc_thread_handle thread_h; // This process as a thread.
00092     
00093 
00094     // CHECK TO SEE IF WE ARE ALREADY REGISTERED WITH THE EVENT:
00095 
00096     for( int i = m_static_events.size() - 1; i >= 0; -- i ) {
00097         if( &e == m_static_events[i] ) {
00098             return;
00099         }
00100     }
00101 
00102     // REMEMBER THE EVENT AND THEN REGISTER OUR OBJECT INSTANCE WITH IT:
00103 
00104     m_static_events.push_back( &e );
00105 
00106     switch ( m_process_kind )
00107     {
00108       case SC_THREAD_PROC_:
00109       case SC_CTHREAD_PROC_:
00110         thread_h = DCAST<sc_thread_handle>( this );
00111         assert( thread_h != 0 );
00112         e.add_static( thread_h );
00113         break;
00114       case SC_METHOD_PROC_:
00115         method_h = DCAST<sc_method_handle>( this );
00116         assert( method_h != 0 );
00117         e.add_static( method_h );
00118         break;
00119       default:
00120         assert( false );
00121         break;
00122     }
00123 }
00124 
00125 
00126 //------------------------------------------------------------------------------
00127 //"sc_process_b::dont_initialize"
00128 //
00129 // This virtual method sets the initialization switch for this object instance.
00130 //------------------------------------------------------------------------------
00131 void sc_process_b::dont_initialize( bool dont )
00132 {
00133     m_dont_init = dont;
00134 }
00135 
00136 
00137 //------------------------------------------------------------------------------
00138 //"sc_process_b::gen_unique_name"
00139 //
00140 // This method generates a unique name within this object instance's namespace.
00141 //------------------------------------------------------------------------------
00142 const char* sc_process_b::gen_unique_name( const char* basename_,
00143     bool preserve_first )
00144 {
00145     if ( ! m_name_gen_p ) m_name_gen_p = new sc_name_gen;
00146     return m_name_gen_p->gen_unique_name( basename_, preserve_first );
00147 }
00148 
00149 
00150 //------------------------------------------------------------------------------
00151 //"sc_process_b::kill_process"
00152 //
00153 // This method removes this object instance from use. It will be called by
00154 // the kill_process() methods of classes derived from it. This object 
00155 // will be removed from any data structures it resides, other than existence.
00156 //------------------------------------------------------------------------------
00157 void sc_process_b::kill_process()
00158 { 
00159     sc_method_handle method_h; // This process as a method.
00160     sc_thread_handle thread_h; // This process as a thread.
00161 
00162     if ( m_zombie ) return;    // Nothing to be done.
00163 
00164 
00165     // REMOVE ANY DYNAMIC WAITS
00166 
00167     switch ( m_process_kind )
00168     {
00169       case SC_THREAD_PROC_:
00170       case SC_CTHREAD_PROC_:
00171         thread_h = DCAST<sc_thread_handle>(this);
00172         assert( thread_h );
00173         if ( m_event_p ) m_event_p->remove_dynamic( thread_h );
00174         if ( m_event_list_p )
00175         {
00176             m_event_list_p->remove_dynamic( thread_h, 0 );
00177             m_event_list_p->auto_delete();
00178         }
00179         break;
00180       case SC_METHOD_PROC_:
00181         method_h = DCAST<sc_method_handle>(this);
00182         assert( method_h );
00183         if ( m_event_p ) m_event_p->remove_dynamic( method_h );
00184         if ( m_event_list_p )
00185         {
00186             m_event_list_p->remove_dynamic( method_h, 0 );
00187             m_event_list_p->auto_delete();
00188         }
00189         break;
00190       default: // Some other type, it needs to clean up itself.
00191         // std::cout << "Check " << __FILE__ << ":" << __LINE__ << std::endl;
00192         break;
00193     }
00194 
00195 
00196     // REMOVE STATIC WAITS, AND REMOVE THE PROCESS FROM ITS SC_RESET:
00197 
00198     remove_static_events();
00199     if ( m_reset_p ) m_reset_p->remove_process( this );
00200 
00201 
00202     // FIRE THE TERMINATION EVENT, MARK AS TERMINATED, AND DECREMENT THE COUNT:
00203     //
00204     // (1) We wait to set the process kind until after doing the removals
00205     //     above.
00206     // (2) Decrementing the reference count will result in actual object 
00207     //     deletion if we hit zero.
00208 
00209     m_zombie = true;
00210     if ( m_term_event_p ) m_term_event_p->notify();
00211     reference_decrement();
00212 }
00213 
00214 //------------------------------------------------------------------------------
00215 //"sc_process_b::remove_static_events"
00216 //
00217 // This method removes this object instance from the events in its static
00218 // event list.
00219 //------------------------------------------------------------------------------
00220 void
00221 sc_process_b::remove_static_events()
00222 {
00223     sc_method_handle method_h; // This process as a method.
00224     sc_thread_handle thread_h; // This process as a thread.
00225 
00226     switch ( m_process_kind )
00227     {
00228       case SC_THREAD_PROC_:
00229       case SC_CTHREAD_PROC_:
00230         thread_h = DCAST<sc_thread_handle>( this );
00231         assert( thread_h != 0 );
00232         for( int i = m_static_events.size() - 1; i >= 0; -- i ) {
00233             m_static_events[i]->remove_static( thread_h );
00234         }
00235         m_static_events.resize(0);
00236         break;
00237       case SC_METHOD_PROC_:
00238         method_h = DCAST<sc_method_handle>( this );
00239         assert( method_h != 0 );
00240         for( int i = m_static_events.size() - 1; i >= 0; -- i ) {
00241             m_static_events[i]->remove_static( method_h );
00242         }
00243         m_static_events.resize(0);
00244         break;
00245       default: // Some other type, it needs to clean up itself.
00246         // std::cout << "Check " << __FILE__ << ":" << __LINE__ << std::endl;
00247         break;
00248     }
00249 }
00250 
00251 
00252 //------------------------------------------------------------------------------
00253 //"sc_process_b::sc_process_b"
00254 //
00255 // This is the object instance constructor for this class.
00256 //------------------------------------------------------------------------------
00257 sc_process_b::sc_process_b( const char* name_p, bool free_host,
00258      SC_ENTRY_FUNC method_p, sc_process_host* host_p, 
00259      const sc_spawn_options* opt_p 
00260 ) :
00261     sc_object( name_p ),
00262     proc_id( simcontext()->next_proc_id()),
00263     m_dont_init( false ),
00264     m_dynamic_proc( simcontext()->elaboration_done() ),
00265     m_event_p(0),
00266     m_event_list_p(0),
00267     m_exist_p(0),
00268     m_free_host( free_host ),
00269     m_last_report_p(0),
00270     m_name_gen_p(0),
00271     m_process_kind(SC_NO_PROC_),
00272     m_references_n(1), 
00273     m_reset_p(0),
00274     m_runnable_p(0),
00275     m_semantics_host_p( host_p ),
00276     m_semantics_method_p ( method_p ),
00277     m_term_event_p(0),
00278     m_throw_type( THROW_NONE ),
00279     m_timed_out(false),
00280     m_timeout_event_p(new sc_event),
00281     m_trigger_type(STATIC),
00282     m_zombie(false)
00283 {
00284 
00285     // THIS OBJECT INSTANCE IS NOW THE LAST CREATED PROCESS:
00286 
00287     m_last_created_process_p = this;
00288 
00289 }
00290 
00291 //------------------------------------------------------------------------------
00292 //"sc_process_b::~sc_process_b"
00293 //
00294 // This is the object instance destructor for this class.
00295 //------------------------------------------------------------------------------
00296 sc_process_b::~sc_process_b()
00297 {
00298    
00299     // REDIRECT ANY CHILDREN AS CHILDREN OF THE SIMULATION CONTEXT:
00300 
00301     int size = m_child_objects.size();
00302     for(int i = 0; i < size; i++) 
00303     {
00304         sc_object* obj_p =  m_child_objects[i];
00305         obj_p->m_parent = NULL;
00306         simcontext()->add_child_object(obj_p);
00307     }
00308 
00309 
00310     // DELETE SEMANTICS OBJECTS IF NEED BE:
00311 
00312     if ( m_free_host ) delete m_semantics_host_p;
00313 #   if !defined(SC_USE_MEMBER_FUNC_PTR) // Remove invocation object.
00314         delete m_semantics_method_p;
00315 #   endif
00316 
00317 
00318     // REMOVE ANY STRUCTURES THAT MAY HAVE BEEN BUILT:
00319 
00320     if ( m_name_gen_p ) delete m_name_gen_p;
00321     if ( m_last_report_p ) delete m_last_report_p;
00322     if ( m_term_event_p ) delete m_term_event_p;
00323     if ( m_timeout_event_p ) delete m_timeout_event_p;
00324 
00325 }
00326 
00327 
00328 //------------------------------------------------------------------------------
00329 //"sc_process_b::terminated_event"
00330 //
00331 // This inline method returns a reference to the terminated event for this
00332 // object instance. If no event exists one is allocated.
00333 //------------------------------------------------------------------------------
00334 sc_event& sc_process_b::terminated_event()
00335 {
00336     if ( m_process_kind == SC_METHOD_PROC_ )
00337     SC_REPORT_WARNING(SC_ID_METHOD_TERMINATION_EVENT_,"");
00338     if ( !m_term_event_p ) m_term_event_p = new sc_event;
00339     return *m_term_event_p;
00340 }
00341 
00342 //------------------------------------------------------------------------------
00343 //"sc_process_handle::operator sc_cthread_handle"
00344 //
00345 //------------------------------------------------------------------------------
00346 sc_process_handle::operator sc_cthread_handle()  
00347 {
00348     return DCAST<sc_cthread_handle>(m_target_p); 
00349 }
00350 
00351 //------------------------------------------------------------------------------
00352 //"sc_process_handle::sc_method_handle"
00353 //
00354 //------------------------------------------------------------------------------
00355 sc_process_handle::operator sc_method_handle()  
00356 {
00357     return DCAST<sc_method_handle>(m_target_p); 
00358 }
00359 
00360 //------------------------------------------------------------------------------
00361 //"sc_process_handle::sc_thread_handle"
00362 //
00363 //------------------------------------------------------------------------------
00364 sc_process_handle::operator sc_thread_handle()  
00365 {
00366     return DCAST<sc_thread_handle>(m_target_p); 
00367 }
00368 
00369 } // namespace sc_core 

Generated on Wed Jan 21 15:32:09 2009 for SystemC by  doxygen 1.5.5