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_time curr_time = m_timestamp.get_time_count();
00543 
00544         
00545         sc_timestamp ts = e->get_notify_timestamp();
00546         switch( e->m_notify_type )
00547         {
00548             case sc_event::DELTA: 
00549                 if ( ts > m_timestamp ) {
00550                     set_timestamp( sc_timestamp( ts.get_time_count(),
00551                                                  ts.get_delta_count() + 1 ) );
00552                 } else {
00553                     set_timestamp( sc_timestamp( m_timestamp.get_time_count(),
00554                                                  m_timestamp.get_delta_count() 
00555                                                      + 1 ) );
00556                 }
00557                 break;
00558             case sc_event::TIMED: 
00559                 set_timestamp( ts );
00560                 break;
00561             case sc_event::NONE:
00562                 assert( 0 ); 
00563         }
00564 
00565         simcontext()->push_runnable_method(this);
00566 
00567         
00568         simcontext()->update_oldest_time( curr_time );
00569     }
00570 }
00571 
00572 #undef DEBUG_MSG
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 
00660 
00661 
00662 
00663 
00664 
00665 
00666 
00667 
00668 
00669 
00670 
00671 #endif // !defined(sc_method_process_h_INCLUDED)