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 #if !defined(sc_thread_process_h_INCLUDED)
00055 #define sc_thread_process_h_INCLUDED
00056
00057 #include "sysc/kernel/sc_spawn_options.h"
00058 #include "sysc/kernel/sc_process.h"
00059 #include "sysc/kernel/sc_cor.h"
00060 #include "sysc/kernel/sc_event.h"
00061 #include "sysc/kernel/sc_except.h"
00062 #include "sysc/kernel/sc_reset.h"
00063
00064
00065 namespace sc_core {
00066
00067 class sc_event_and_list;
00068 class sc_event_or_list;
00069 class sc_reset;
00070
00071
00072 void sc_thread_cor_fn( void* );
00073 void sc_cthread_cor_fn( void* );
00074 void sc_set_stack_size( sc_thread_handle, std::size_t );
00075 class sc_event;
00076 class sc_join;
00077 class sc_module;
00078 class sc_process_handle;
00079 class sc_process_table;
00080 class sc_simcontext;
00081 class sc_runnable;
00082 sc_cor* get_cor_pointer( sc_process_b* process_p );
00083
00084 void wait( sc_simcontext* );
00085 void wait( const sc_event&,
00086 sc_simcontext* );
00087 void wait( sc_event_or_list&,
00088 sc_simcontext* );
00089 void wait( sc_event_and_list&,
00090 sc_simcontext* );
00091 void wait( const sc_time&,
00092 sc_simcontext* );
00093 void wait( const sc_time&, const sc_event&,
00094 sc_simcontext* );
00095 void wait( const sc_time&, sc_event_or_list&,
00096 sc_simcontext* );
00097 void wait( const sc_time&, sc_event_and_list&,
00098 sc_simcontext* );
00099
00100
00101
00102 void sc_set_stack_size( sc_thread_handle thread_h, std::size_t size );
00103
00104
00105
00106
00107
00108 class sc_thread_process : public sc_process_b {
00109 friend void sc_thread_cor_fn( void* );
00110 friend void sc_cthread_cor_fn( void* );
00111 friend void sc_set_stack_size( sc_thread_handle, std::size_t );
00112 friend class sc_event;
00113 friend class sc_join;
00114 friend class sc_module;
00115 friend class sc_process_handle;
00116 friend class sc_process_table;
00117 friend class sc_simcontext;
00118 friend class sc_runnable;
00119 friend sc_cor* get_cor_pointer( sc_process_b* process_p );
00120
00121 friend void wait( sc_simcontext* );
00122 friend void wait( const sc_event&,
00123 sc_simcontext* );
00124 friend void wait( sc_event_or_list&,
00125 sc_simcontext* );
00126 friend void wait( sc_event_and_list&,
00127 sc_simcontext* );
00128 friend void wait( const sc_time&,
00129 sc_simcontext* );
00130 friend void wait( const sc_time&, const sc_event&,
00131 sc_simcontext* );
00132 friend void wait( const sc_time&, sc_event_or_list&,
00133 sc_simcontext* );
00134 friend void wait( const sc_time&, sc_event_and_list&,
00135 sc_simcontext* );
00136 public:
00137 sc_thread_process( const char* name_p, bool free_host,
00138 SC_ENTRY_FUNC method_p, sc_process_host* host_p,
00139 const sc_spawn_options* opt_p );
00140
00141 virtual ~sc_thread_process();
00142
00143 virtual const char* kind() const
00144 { return "sc_thread_process"; }
00145
00146 protected:
00147 virtual void kill_process();
00148 sc_thread_handle next_exist();
00149 sc_thread_handle next_runnable();
00150 virtual void prepare_for_simulation();
00151 inline bool ready_to_run();
00152 void set_next_exist( sc_thread_handle next_p );
00153 void set_next_runnable( sc_thread_handle next_p );
00154
00155 void set_stack_size( std::size_t size );
00156 inline void suspend_me();
00157
00158 bool trigger_dynamic( sc_event* );
00159
00160 void wait( const sc_event& );
00161 void wait( sc_event_or_list& );
00162 void wait( sc_event_and_list& );
00163 void wait( const sc_time& );
00164 void wait( const sc_time&, const sc_event& );
00165 void wait( const sc_time&, sc_event_or_list& );
00166 void wait( const sc_time&, sc_event_and_list& );
00167 void wait_cycles( int n=1 );
00168
00169 protected:
00170 void add_monitor( sc_process_monitor* monitor_p );
00171 void remove_monitor( sc_process_monitor* monitor_p);
00172 void signal_monitors( int type = 0 );
00173
00174 protected:
00175 sc_cor* m_cor_p;
00176 static sc_cor* m_dead_cor_p;
00177 std::vector<sc_process_monitor*> m_monitor_q;
00178 std::size_t m_stack_size;
00179 int m_wait_cycle_n;
00180
00181 private:
00182 sc_thread_process( const sc_thread_process& );
00183 const sc_thread_process& operator = ( const sc_thread_process& );
00184
00185 };
00186
00187
00188
00189
00190
00191
00192 inline bool sc_thread_process::ready_to_run()
00193 {
00194 if ( (m_throw_type == THROW_NONE) && ( m_wait_cycle_n > 0 ) )
00195 {
00196 --m_wait_cycle_n;
00197 return false;
00198 }
00199 return true;
00200 }
00201
00202
00203
00204
00205
00206
00207 inline void sc_thread_process::set_stack_size( std::size_t size )
00208 {
00209 assert( size );
00210 m_stack_size = size;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219 inline void sc_thread_process::suspend_me()
00220 {
00221 sc_simcontext* simc_p = simcontext();
00222 simc_p->cor_pkg()->yield( simc_p->next_cor() );
00223
00224 switch ( m_throw_type )
00225 {
00226 case THROW_NONE:
00227 break;
00228 case THROW_RESET:
00229 throw sc_user();
00230 default:
00231 break;
00232 }
00233 }
00234
00235
00236
00237
00238
00239 inline
00240 void
00241 sc_thread_process::wait( const sc_event& e )
00242 {
00243 e.add_dynamic( this );
00244 m_trigger_type = EVENT;
00245 suspend_me();
00246 }
00247
00248 inline
00249 void
00250 sc_thread_process::wait( sc_event_or_list& el )
00251 {
00252 el.add_dynamic( this );
00253 m_event_list_p = ⪙
00254 m_trigger_type = OR_LIST;
00255 suspend_me();
00256 }
00257
00258 inline
00259 void
00260 sc_thread_process::wait( sc_event_and_list& el )
00261 {
00262 el.add_dynamic( this );
00263 m_event_list_p = ⪙
00264 m_event_count = el.size();
00265 m_trigger_type = AND_LIST;
00266 suspend_me();
00267 }
00268
00269 inline
00270 void
00271 sc_thread_process::wait( const sc_time& t )
00272 {
00273 m_timeout_event_p->notify_internal( t );
00274 m_timeout_event_p->add_dynamic( this );
00275 m_trigger_type = TIMEOUT;
00276 suspend_me();
00277 }
00278
00279 inline
00280 void
00281 sc_thread_process::wait( const sc_time& t, const sc_event& e )
00282 {
00283 m_timeout_event_p->notify_internal( t );
00284 m_timeout_event_p->add_dynamic( this );
00285 e.add_dynamic( this );
00286 m_event_p = &e;
00287 m_trigger_type = EVENT_TIMEOUT;
00288 suspend_me();
00289 }
00290
00291 inline
00292 void
00293 sc_thread_process::wait( const sc_time& t, sc_event_or_list& el )
00294 {
00295 m_timeout_event_p->notify_internal( t );
00296 m_timeout_event_p->add_dynamic( this );
00297 el.add_dynamic( this );
00298 m_event_list_p = ⪙
00299 m_trigger_type = OR_LIST_TIMEOUT;
00300 suspend_me();
00301 }
00302
00303 inline
00304 void
00305 sc_thread_process::wait( const sc_time& t, sc_event_and_list& el )
00306 {
00307 m_timeout_event_p->notify_internal( t );
00308 m_timeout_event_p->add_dynamic( this );
00309 el.add_dynamic( this );
00310 m_event_list_p = ⪙
00311 m_event_count = el.size();
00312 m_trigger_type = AND_LIST_TIMEOUT;
00313 suspend_me();
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 inline
00326 void
00327 sc_thread_process::wait_cycles( int n )
00328 {
00329 m_wait_cycle_n = n-1;
00330 suspend_me();
00331 }
00332
00333
00334
00335
00336
00337 inline
00338 void sc_thread_process::add_monitor(sc_process_monitor* monitor_p)
00339 {
00340 m_monitor_q.push_back(monitor_p);
00341 }
00342
00343
00344 inline
00345 void sc_thread_process::remove_monitor(sc_process_monitor* monitor_p)
00346 {
00347 int mon_n = m_monitor_q.size();
00348
00349 for ( int mon_i = 0; mon_i < mon_n; mon_i++ )
00350 {
00351 if ( m_monitor_q[mon_i] == monitor_p )
00352 {
00353 m_monitor_q[mon_i] = m_monitor_q[mon_n-1];
00354 m_monitor_q.resize(mon_n-1);
00355 }
00356 }
00357 }
00358
00359 inline
00360 void sc_thread_process::set_next_exist(sc_thread_handle next_p)
00361 {
00362 m_exist_p = next_p;
00363 }
00364
00365 inline
00366 sc_thread_handle sc_thread_process::next_exist()
00367 {
00368 return (sc_thread_handle)m_exist_p;
00369 }
00370
00371 inline
00372 void sc_thread_process::set_next_runnable(sc_thread_handle next_p)
00373 {
00374 m_runnable_p = next_p;
00375 }
00376
00377 inline
00378 sc_thread_handle sc_thread_process::next_runnable()
00379 {
00380 return (sc_thread_handle)m_runnable_p;
00381 }
00382
00383 inline sc_cor* get_cor_pointer( sc_process_b* process_p )
00384 {
00385 sc_thread_handle thread_p = DCAST<sc_thread_handle>(process_p);
00386 return thread_p->m_cor_p;
00387 }
00388
00389 }
00390
00391 #endif // !defined(sc_thread_process_h_INCLUDED)