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 #if !defined(sc_method_process_h_INCLUDED)
00041 #define sc_method_process_h_INCLUDED
00042
00043 #include "sysc/kernel/sc_process.h"
00044 #include "sysc/kernel/sc_spawn_options.h"
00045 #include "sysc/kernel/sc_cor.h"
00046 #include "sysc/kernel/sc_event.h"
00047 #include "sysc/kernel/sc_except.h"
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #if 0
00059 # define DEBUG_NAME ""
00060 # define DEBUG_MSG(NAME,P,MSG) \
00061 { \
00062 if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
00063 std::cout << "**** " << sc_time_stamp() << " (" \
00064 << sc_get_current_process_name() << "): " << MSG \
00065 << " - " << P->name() << std::endl; \
00066 }
00067 #else
00068 # define DEBUG_MSG(NAME,P,MSG)
00069 #endif
00070
00071
00072 namespace sc_core {
00073
00074
00075
00076 void sc_method_cor_fn( void* );
00077 void sc_cmethod_cor_fn( void* );
00078 void sc_set_stack_size( sc_method_handle, std::size_t );
00079 class sc_event;
00080 class sc_module;
00081 class sc_process_table;
00082 class sc_process_handle;
00083 class sc_simcontext;
00084 class sc_runnable;
00085
00086
00087 sc_cor* get_cor_pointer( sc_process_b* process_p );
00088
00089 void next_trigger( int, sc_simcontext* );
00090 void next_trigger( const sc_event&, int, sc_simcontext* );
00091 void next_trigger( const sc_event_or_list&, int, sc_simcontext* );
00092 void next_trigger( const sc_event_and_list&, int, sc_simcontext* );
00093 void next_trigger( const sc_time&, int, sc_simcontext* );
00094 void next_trigger( const sc_time&, const sc_event&, int, sc_simcontext* );
00095 void next_trigger( const sc_time&, const sc_event_or_list&, int, sc_simcontext* );
00096 void next_trigger( const sc_time&, const sc_event_and_list&, int, sc_simcontext* );
00097
00098 struct sc_invoke_method;
00099
00104 class sc_method_process : public sc_process_b {
00105 friend struct sc_invoke_method;
00106 friend void sc_method_cor_fn( void* );
00107 friend void sc_cmethod_cor_fn( void* );
00108 friend void sc_set_stack_size( sc_method_handle, std::size_t );
00109 friend class sc_event;
00110 friend class sc_module;
00111
00112
00113 friend class sc_channel;
00114
00115 friend class sc_process_table;
00116 friend class sc_process_handle;
00117 friend class sc_simcontext;
00118 friend class sc_runnable;
00119
00120
00121 friend sc_cor* get_cor_pointer( sc_process_b* process_p );
00122
00123
00124 friend void next_trigger( int, sc_simcontext* );
00125 friend void next_trigger( const sc_event&, int,
00126 sc_simcontext* );
00127 friend void next_trigger( const sc_event_or_list&, int,
00128 sc_simcontext* );
00129 friend void next_trigger( const sc_event_and_list&, int,
00130 sc_simcontext* );
00131 friend void next_trigger( const sc_time&, int,
00132 sc_simcontext* );
00133 friend void next_trigger( const sc_time&, const sc_event&, int,
00134 sc_simcontext* );
00135 friend void next_trigger( const sc_time&, const sc_event_or_list&, int,
00136 sc_simcontext* );
00137 friend void next_trigger( const sc_time&, const sc_event_and_list&, int,
00138 sc_simcontext* );
00139
00140 public:
00141 sc_method_process( const char* name_p, bool free_host,
00142 SC_ENTRY_FUNC method_p, sc_process_host* host_p,
00143 const sc_spawn_options* opt_p );
00144
00145 virtual const char* kind() const
00146 { return "sc_method_process"; }
00147
00148 protected:
00149 void check_for_throws();
00150 virtual void disable_process(
00151 sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
00152 virtual void enable_process(
00153 sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
00154 inline bool run_process();
00155 virtual void kill_process(
00156 sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
00157 sc_method_handle next_exist();
00158 sc_method_handle next_runnable();
00159
00163
00164 virtual void prepare_for_simulation();
00165
00170
00171 void clear_trigger( int );
00172
00177
00178 void next_trigger( const sc_event&, int );
00179
00184
00185 void next_trigger( const sc_event_or_list&, int );
00186
00191
00192 void next_trigger( const sc_event_and_list&, int );
00193
00198
00199 void next_trigger( const sc_time&, int );
00200
00205
00206 void next_trigger( const sc_time&, const sc_event&, int );
00207
00212
00213 void next_trigger( const sc_time&, const sc_event_or_list&, int );
00214
00219
00220 void next_trigger( const sc_time&, const sc_event_and_list&, int );
00221
00222 virtual void resume_process(
00223 sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
00224 void set_next_exist( sc_method_handle next_p );
00225 void set_next_runnable( sc_method_handle next_p );
00226
00230
00231 void set_stack_size( std::size_t size );
00232
00233 virtual void suspend_process(
00234 sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
00235 virtual void throw_reset( bool async );
00236 virtual void throw_user( const sc_throw_it_helper& helper,
00237 sc_descendant_inclusion_info descendants = SC_NO_DESCENDANTS );
00238 bool trigger_dynamic( sc_event* );
00239
00244
00245
00246 inline void trigger_static( sc_event* );
00247
00248 protected:
00249 sc_cor* m_cor_p;
00250 std::size_t m_stack_size;
00251 std::vector<sc_process_monitor*> m_monitor_q;
00252
00253 private:
00254
00255 virtual ~sc_method_process();
00256
00257 private:
00258 sc_method_process( const sc_method_process& );
00259 const sc_method_process& operator = ( const sc_method_process& );
00260
00261 };
00262
00263
00264
00265
00266
00267
00268 inline void sc_method_process::set_stack_size( std::size_t size )
00269 {
00270 assert( size );
00271 m_stack_size = size;
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 inline
00302 void
00303 sc_method_process::next_trigger( const sc_event& e, int seg_id )
00304 {
00305
00306 sc_kernel_lock lock;
00307
00308 #ifdef SC_LOCK_CHECK
00309 assert( sc_get_curr_simcontext()->is_locked_and_owner() );
00310 #endif
00311 clear_trigger( seg_id );
00312 e.add_dynamic( this );
00313 m_event_p = &e;
00314 m_trigger_type = EVENT;
00315
00316 }
00317
00318 inline
00319 void
00320 sc_method_process::next_trigger( const sc_event_or_list& el, int seg_id )
00321 {
00322
00323 sc_kernel_lock lock;
00324
00325 #ifdef SC_LOCK_CHECK
00326 assert( sc_get_curr_simcontext()->is_locked_and_owner() );
00327 #endif
00328 clear_trigger( seg_id );
00329 el.add_dynamic( this );
00330 m_event_list_p = ⪙
00331 m_trigger_type = OR_LIST;
00332
00333 }
00334
00335 inline
00336 void
00337 sc_method_process::next_trigger( const sc_event_and_list& el, int seg_id )
00338 {
00339
00340 sc_kernel_lock lock;
00341
00342 #ifdef SC_LOCK_CHECK
00343 assert( sc_get_curr_simcontext()->is_locked_and_owner() );
00344 #endif
00345 clear_trigger( seg_id );
00346 el.add_dynamic( this );
00347 m_event_list_p = ⪙
00348 m_event_count = el.size();
00349 m_trigger_type = AND_LIST;
00350
00351 }
00352
00353 inline
00354 void
00355 sc_method_process::next_trigger( const sc_time& t, int seg_id )
00356 {
00357
00358 sc_kernel_lock lock;
00359
00360 #ifdef SC_LOCK_CHECK
00361 assert( sc_get_curr_simcontext()->is_locked_and_owner() );
00362 #endif
00363 clear_trigger( seg_id );
00364 m_timeout_event_p->notify_internal( t );
00365 m_timeout_event_p->add_dynamic( this );
00366 m_trigger_type = TIMEOUT;
00367
00368 }
00369
00370 inline
00371 void
00372 sc_method_process::next_trigger( const sc_time& t, const sc_event& e,
00373 int seg_id )
00374 {
00375
00376 sc_kernel_lock lock;
00377
00378 #ifdef SC_LOCK_CHECK
00379 assert( sc_get_curr_simcontext()->is_locked_and_owner() );
00380 #endif
00381 clear_trigger( seg_id );
00382 m_timeout_event_p->notify_internal( t );
00383 m_timeout_event_p->add_dynamic( this );
00384 e.add_dynamic( this );
00385 m_event_p = &e;
00386 m_trigger_type = EVENT_TIMEOUT;
00387
00388 }
00389
00390 inline
00391 void
00392 sc_method_process::next_trigger( const sc_time& t, const sc_event_or_list& el,
00393 int seg_id )
00394 {
00395
00396 sc_kernel_lock lock;
00397
00398 #ifdef SC_LOCK_CHECK
00399 assert( sc_get_curr_simcontext()->is_locked_and_owner() );
00400 #endif
00401 clear_trigger( seg_id );
00402 m_timeout_event_p->notify_internal( t );
00403 m_timeout_event_p->add_dynamic( this );
00404 el.add_dynamic( this );
00405 m_event_list_p = ⪙
00406 m_trigger_type = OR_LIST_TIMEOUT;
00407
00408 }
00409
00410 inline
00411 void
00412 sc_method_process::next_trigger( const sc_time& t, const sc_event_and_list& el,
00413 int seg_id )
00414 {
00415
00416 sc_kernel_lock lock;
00417
00418 #ifdef SC_LOCK_CHECK
00419 assert( sc_get_curr_simcontext()->is_locked_and_owner() );
00420 #endif
00421 clear_trigger( seg_id );
00422 m_timeout_event_p->notify_internal( t );
00423 m_timeout_event_p->add_dynamic( this );
00424 el.add_dynamic( this );
00425 m_event_list_p = ⪙
00426 m_event_count = el.size();
00427 m_trigger_type = AND_LIST_TIMEOUT;
00428
00429 }
00430
00431 inline
00432 void sc_method_process::set_next_exist(sc_method_handle next_p)
00433 {
00434 m_exist_p = next_p;
00435 }
00436
00437 inline
00438 sc_method_handle sc_method_process::next_exist()
00439 {
00440 return (sc_method_handle)m_exist_p;
00441 }
00442
00443
00444 inline
00445 void sc_method_process::set_next_runnable(sc_method_handle next_p)
00446 {
00447 m_runnable_p = next_p;
00448 }
00449
00450 inline
00451 sc_method_handle sc_method_process::next_runnable()
00452 {
00453 return (sc_method_handle)m_runnable_p;
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463 inline bool sc_method_process::run_process()
00464 {
00465
00466
00467
00468 bool restart = false;
00469 do {
00470 try {
00471 DEBUG_MSG(DEBUG_NAME,this,"executing method semantics");
00472 semantics();
00473 restart = false;
00474 }
00475 catch( sc_unwind_exception& ex ) {
00476 DEBUG_MSG(DEBUG_NAME,this,"caught unwind exception");
00477 ex.clear();
00478 restart = ex.is_reset();
00479 }
00480 catch( ... ) {
00481 sc_report* err_p = sc_handle_exception();
00482 simcontext()->set_error( err_p );
00483 return false;
00484 }
00485 } while( restart );
00486
00487 return true;
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 inline
00507 void
00508
00509
00510 sc_method_process::trigger_static( sc_event* e )
00511 {
00512
00513
00514
00515
00516
00517
00518
00519 if ( (m_state & ps_bit_disabled) || is_runnable() ||
00520 m_trigger_type != STATIC )
00521 return;
00522
00523 #if ! defined( SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS )
00524 if( SC_UNLIKELY_( sc_get_current_process_b() == this ) )
00525 {
00526 report_immediate_self_notification();
00527 return;
00528 }
00529 #endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS
00530
00531
00532
00533
00534
00535 if ( m_state & ps_bit_suspended )
00536 {
00537 m_state = m_state | ps_bit_ready_to_run;
00538 }
00539 else
00540 {
00541
00542 sc_timestamp ts = e->get_notify_timestamp();
00543 switch( e->m_notify_type )
00544 {
00545 case sc_event::DELTA:
00546 set_timestamp( sc_timestamp( ts.get_time_count(),
00547 ts.get_delta_count() + 1 ) );
00548 break;
00549 case sc_event::TIMED:
00550 set_timestamp( ts );
00551 break;
00552 case sc_event::NONE:
00553 assert( 0 );
00554 }
00555
00556 simcontext()->push_runnable_method(this);
00557 }
00558 }
00559
00560 #undef DEBUG_MSG
00561
00562 }
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 #endif // !defined(sc_method_process_h_INCLUDED)