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_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
00072
00073 std::vector<sc_object*> sc_process_handle::empty_vector;
00074 sc_event sc_process_handle::non_event;
00075
00076
00077 sc_process_b* sc_process_b::m_delete_next_p = 0;
00078
00079
00080 sc_process_b* sc_process_b::m_last_created_process_p = 0;
00081
00082
00083
00084
00085
00086
00087
00088 void sc_process_b::add_static_event( const sc_event& e )
00089 {
00090 sc_method_handle method_h;
00091 sc_thread_handle thread_h;
00092
00093
00094
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
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
00128
00129
00130
00131 void sc_process_b::dont_initialize( bool dont )
00132 {
00133 m_dont_init = dont;
00134 }
00135
00136
00137
00138
00139
00140
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
00152
00153
00154
00155
00156
00157 void sc_process_b::kill_process()
00158 {
00159 sc_method_handle method_h;
00160 sc_thread_handle thread_h;
00161
00162 if ( m_zombie ) return;
00163
00164
00165
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:
00191
00192 break;
00193 }
00194
00195
00196
00197
00198 remove_static_events();
00199 if ( m_reset_p ) m_reset_p->remove_process( this );
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 m_zombie = true;
00210 if ( m_term_event_p ) m_term_event_p->notify();
00211 reference_decrement();
00212 }
00213
00214
00215
00216
00217
00218
00219
00220 void
00221 sc_process_b::remove_static_events()
00222 {
00223 sc_method_handle method_h;
00224 sc_thread_handle thread_h;
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:
00246
00247 break;
00248 }
00249 }
00250
00251
00252
00253
00254
00255
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
00286
00287 m_last_created_process_p = this;
00288
00289 }
00290
00291
00292
00293
00294
00295
00296 sc_process_b::~sc_process_b()
00297 {
00298
00299
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
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
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
00330
00331
00332
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
00344
00345
00346 sc_process_handle::operator sc_cthread_handle()
00347 {
00348 return DCAST<sc_cthread_handle>(m_target_p);
00349 }
00350
00351
00352
00353
00354
00355 sc_process_handle::operator sc_method_handle()
00356 {
00357 return DCAST<sc_method_handle>(m_target_p);
00358 }
00359
00360
00361
00362
00363
00364 sc_process_handle::operator sc_thread_handle()
00365 {
00366 return DCAST<sc_thread_handle>(m_target_p);
00367 }
00368
00369 }