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 #include "sysc/kernel/sc_thread_process.h"
00062 #include "sysc/kernel/sc_process_handle.h"
00063 #include "sysc/kernel/sc_simcontext_int.h"
00064 #include "sysc/kernel/sc_module.h"
00065
00066 namespace sc_core {
00067
00068
00069
00070
00071
00072
00073 void sc_thread_cor_fn( void* arg )
00074 {
00075 sc_thread_handle thread_h = RCAST<sc_thread_handle>( arg );
00076
00077
00078
00079 while( true ) {
00080
00081 try {
00082 thread_h->semantics();
00083 }
00084 catch( sc_user ) {
00085 continue;
00086 }
00087 catch( sc_halt ) {
00088 ::std::cout << "Terminating process "
00089 << thread_h->name() << ::std::endl;
00090 }
00091 catch( const sc_report& ex ) {
00092 std::cout << "\n" << ex.what() << std::endl;
00093 thread_h->simcontext()->set_error();
00094 }
00095 break;
00096 }
00097
00098
00099
00100
00101
00102
00103 thread_h->kill_process();
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 void sc_thread_process::kill_process()
00115 {
00116
00117
00118 int mon_n = m_monitor_q.size();
00119 if ( mon_n )
00120 {
00121 for ( int mon_i = 0; mon_i < mon_n; mon_i++ )
00122 m_monitor_q[mon_i]->signal( this, sc_process_monitor::spm_exit);
00123 }
00124
00125
00126
00127 sc_process_b::kill_process();
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 sc_process_b* active_p = sc_get_current_process_b();
00139 sc_simcontext* simc_p = simcontext();
00140 if ( active_p == (sc_process_b*)this )
00141 {
00142 simc_p->cor_pkg()->abort( simc_p->next_cor() );
00143 }
00144
00145
00146
00147 else
00148 {
00149 simc_p->remove_runnable_thread( this );
00150 }
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160 void sc_thread_process::prepare_for_simulation()
00161 {
00162 m_cor_p = simcontext()->cor_pkg()->create( m_stack_size,
00163 sc_thread_cor_fn, this );
00164 m_cor_p->stack_protect( true );
00165 }
00166
00167
00168
00169
00170
00171
00172
00173 sc_thread_process::sc_thread_process( const char* name_p, bool free_host,
00174 SC_ENTRY_FUNC method_p, sc_process_host* host_p,
00175 const sc_spawn_options* opt_p
00176 ):
00177 sc_process_b(
00178 name_p && name_p[0] ? name_p : sc_gen_unique_name("thread_p"),
00179 free_host, method_p, host_p, opt_p),
00180 m_cor_p(0), m_stack_size(SC_DEFAULT_STACK_SIZE),
00181 m_wait_cycle_n(0)
00182 {
00183
00184
00185
00186 if ( DCAST<sc_module*>(host_p) != 0 && sc_is_running() )
00187 {
00188 SC_REPORT_ERROR( SC_ID_MODULE_THREAD_AFTER_START_, "" );
00189 }
00190
00191
00192
00193
00194
00195 m_process_kind = SC_THREAD_PROC_;
00196
00197 if (opt_p) {
00198 m_dont_init = opt_p->m_dont_initialize;
00199 if ( opt_p->m_stack_size ) m_stack_size = opt_p->m_stack_size;
00200
00201
00202 for (unsigned int i = 0; i < opt_p->m_sensitive_events.size(); i++) {
00203 sc_sensitive::make_static_sensitivity(
00204 this, *opt_p->m_sensitive_events[i]);
00205 }
00206
00207
00208 for ( unsigned int i = 0; i < opt_p->m_sensitive_port_bases.size(); i++)
00209 {
00210 sc_sensitive::make_static_sensitivity(
00211 this, *opt_p->m_sensitive_port_bases[i]);
00212 }
00213
00214
00215 for ( unsigned int i = 0; i < opt_p->m_sensitive_interfaces.size(); i++)
00216 {
00217 sc_sensitive::make_static_sensitivity(
00218 this, *opt_p->m_sensitive_interfaces[i]);
00219 }
00220
00221
00222 for ( unsigned int i = 0; i < opt_p->m_sensitive_event_finders.size();
00223 i++)
00224 {
00225 sc_sensitive::make_static_sensitivity(
00226 this, *opt_p->m_sensitive_event_finders[i]);
00227 }
00228 }
00229
00230 else
00231 {
00232 m_dont_init = false;
00233 }
00234
00235 }
00236
00237
00238
00239
00240
00241
00242 sc_thread_process::~sc_thread_process()
00243 {
00244
00245
00246
00247 if( m_cor_p != 0 ) {
00248 m_cor_p->stack_protect( false );
00249 delete m_cor_p;
00250 m_cor_p = 0;
00251 }
00252 }
00253
00254
00255
00256
00257
00258
00259
00260 void sc_thread_process::signal_monitors(int type)
00261 {
00262 int mon_n;
00263
00264 mon_n = m_monitor_q.size();
00265 for ( int mon_i = 0; mon_i < mon_n; mon_i++ )
00266 m_monitor_q[mon_i]->signal(this, type);
00267 }
00268
00269
00270
00271
00272
00273
00274 bool sc_thread_process::trigger_dynamic( sc_event* e )
00275 {
00276 if( is_runnable() ) {
00277 return false;
00278 }
00279 m_timed_out = false;
00280 switch( m_trigger_type ) {
00281 case EVENT: {
00282 m_trigger_type = STATIC;
00283 return true;
00284 }
00285 case OR_LIST: {
00286 m_event_list_p->remove_dynamic( this, e );
00287 m_event_list_p->auto_delete();
00288 m_event_list_p = 0;
00289 m_trigger_type = STATIC;
00290 return true;
00291 }
00292 case AND_LIST: {
00293 if( -- m_event_count == 0 ) {
00294
00295 m_event_list_p->auto_delete();
00296 m_event_list_p = 0;
00297 m_trigger_type = STATIC;
00298 return true;
00299 }
00300 return false;
00301 }
00302 case TIMEOUT: {
00303 m_trigger_type = STATIC;
00304 return true;
00305 }
00306 case EVENT_TIMEOUT: {
00307 if( e == m_event_p ) {
00308 m_timeout_event_p->cancel();
00309 m_timeout_event_p->reset();
00310 } else {
00311 m_timed_out = true;
00312 m_event_p->remove_dynamic( this );
00313 }
00314 m_event_p = 0;
00315 m_trigger_type = STATIC;
00316 return true;
00317 }
00318 case OR_LIST_TIMEOUT: {
00319 if( e != m_timeout_event_p ) {
00320 m_timeout_event_p->cancel();
00321 m_timeout_event_p->reset();
00322 } else {
00323 m_timed_out = true;
00324 }
00325 m_event_list_p->remove_dynamic( this, e );
00326 m_event_list_p->auto_delete();
00327 m_event_list_p = 0;
00328 m_trigger_type = STATIC;
00329 return true;
00330 }
00331 case AND_LIST_TIMEOUT: {
00332 if( e == m_timeout_event_p ) {
00333 m_timed_out = true;
00334 m_event_list_p->remove_dynamic( this, e );
00335 m_event_list_p->auto_delete();
00336 m_event_list_p = 0;
00337 m_trigger_type = STATIC;
00338 return true;
00339 } else if( -- m_event_count == 0 ) {
00340 m_timeout_event_p->cancel();
00341 m_timeout_event_p->reset();
00342
00343 m_event_list_p->auto_delete();
00344 m_event_list_p = 0;
00345 m_trigger_type = STATIC;
00346 return true;
00347 }
00348 return false;
00349 }
00350 case STATIC: {
00351
00352 assert( false );
00353 }
00354 }
00355 return false;
00356 }
00357
00358
00359
00360
00361
00362
00363 void
00364 sc_set_stack_size( sc_thread_handle thread_h, std::size_t size )
00365 {
00366 thread_h->set_stack_size( size );
00367 }
00368
00369 }