SystemC  Recoding Infrastructure for SystemC v0.6.3 derived from Accellera SystemC 2.3.1
Accellera SystemC proof-of-concept library
sc_simcontext_int.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  The following code is derived, directly or indirectly, from the SystemC
4  source code Copyright (c) 1996-2014 by all Contributors.
5  All Rights reserved.
6 
7  The contents of this file are subject to the restrictions and limitations
8  set forth in the SystemC Open Source License (the "License");
9  You may not use this file except in compliance with such restrictions and
10  limitations. You may obtain instructions on how to receive a copy of the
11  License at http://www.accellera.org/. Software distributed by Contributors
12  under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
13  ANY KIND, either express or implied. See the License for the specific
14  language governing rights and limitations under the License.
15 
16  *****************************************************************************/
17 
18 /*****************************************************************************
19 
20  sc_simcontext_int.h -- For inline definitions of some utility functions.
21  DO NOT EXPORT THIS INCLUDE FILE. Include this file
22  after "sc_process_int.h" so that we can get the base
23  class right.
24 
25  Original Author: Stan Y. Liao, Synopsys, Inc.
26 
27  CHANGE LOG AT THE END OF THE FILE
28  *****************************************************************************/
29 
30 #ifndef SC_SIMCONTEXT_INT_H
31 #define SC_SIMCONTEXT_INT_H
32 
36 
37 // DEBUGGING MACROS:
38 //
39 // DEBUG_MSG(NAME,P,MSG)
40 // MSG = message to print
41 // NAME = name that must match the process for the message to print, or
42 // null if the message should be printed unconditionally.
43 // P = pointer to process message is for, or NULL in which case the
44 // message will not print.
45 #if 0
46 # define DEBUG_NAME ""
47 # define DEBUG_MSG(NAME,P,MSG) \
48  { \
49  if ( P && ( (strlen(NAME)==0) || !strcmp(NAME,P->name())) ) \
50  std::cout << "**** " << sc_time_stamp() << " (" \
51  << sc_get_current_process_name() << "): " << MSG \
52  << " - " << P->name() << std::endl; \
53  }
54 #else
55 # define DEBUG_MSG(NAME,P,MSG)
56 #endif
57 
58 // 02/22/2016 ZC: to enable verbose display or not
59 #ifndef _SYSC_PRINT_VERBOSE_MESSAGE_ENV_VAR
60 #define _SYSC_PRINT_VERBOSE_MESSAGE_ENV_VAR "SYSC_PRINT_VERBOSE_MESSAGE"
61 #endif
62 namespace sc_core {
63 extern bool verbosity_flag_1;
64 extern bool verbosity_flag_2;
65 extern bool verbosity_flag_3;
66 extern bool verbosity_flag_4;
67 extern bool verbosity_flag_5;
68 extern bool verbosity_flag_6;
69 extern bool verbosity_flag;
70 inline
71 const char*
73 {
74  sc_process_b* active_p; // active process to get name of.
75  const char* result; // name of active process.
76 
77  active_p = sc_get_curr_simcontext()->get_curr_proc();
78  if ( active_p )
79  result = active_p->name();
80  else
81  result = "** NONE **";
82  return result;
83 }
84 
85 // We use m_current_writer rather than m_curr_proc_info.process_handle to
86 // return the active process for sc_signal<T>::check_write since that lets
87 // us turn it off a library compile time, and only incur the overhead at
88 // the time of process switches rather than having to interrogate an
89 // additional switch every time a signal is written.
90 
91 inline
92 void
94 {
95  assert( 0 ); // 10/29/2014 GL TODO: clean up the codes later
96  //m_curr_proc_info.process_handle = process_h;
97  //m_curr_proc_info.kind = process_h->proc_kind();
98  //m_current_writer = m_write_check ? process_h : (sc_object*)0;
99 }
100 
101 inline
102 void
104 {
105  //m_curr_proc_info.process_handle = 0;
106  //m_curr_proc_info.kind = SC_NO_PROC_;
107  //m_current_writer = 0;
109 }
110 
111 inline
112 void
113 sc_simcontext::execute_method_next( sc_method_handle method_h )
114 {
115  m_runnable->execute_method_next( method_h );
116 }
117 
118 inline
119 void
120 sc_simcontext::execute_thread_next( sc_thread_handle thread_h )
121 {
122  m_runnable->execute_thread_next( thread_h );
123 }
124 
125 // +----------------------------------------------------------------------------
126 // |"sc_simcontext::preempt_with"
127 // |
128 // | This method executes the supplied thread immediately, suspending the
129 // | caller. After executing the supplied thread the caller's execution will
130 // | be restored. It is used to allow a thread to immediately throw an
131 // | exception, e.g., when the thread's kill_process() method was called.
132 // | There are three cases to consider:
133 // | (1) The caller is a method, e.g., murder by method.
134 // | (2) The caller is another thread instance, e.g., murder by thread.
135 // | (3) The caller is this thread instance, e.g., suicide.
136 // |
137 // | Arguments:
138 // | thread_h -> thread to be executed.
139 // +----------------------------------------------------------------------------
140 inline
141 void
142 sc_simcontext::preempt_with( sc_thread_handle thread_h )
143 {
144  assert( 0 ); // 10/28/2014 GL TODO: clean up the codes later
145 /*
146 
147  sc_thread_handle active_p; // active thread or null.
148  sc_curr_proc_info caller_info; // process info for caller.
149 
150  // Determine the active process and take the thread to be run off the
151  // run queue, if its there, since we will be explicitly causing its
152  // execution.
153 
154  active_p = DCAST<sc_thread_handle>(sc_get_current_process_b());
155  if ( thread_h->next_runnable() != NULL )
156  remove_runnable_thread( thread_h );
157 
158  // THE CALLER IS A METHOD:
159  //
160  // (a) Set the current process information to our thread.
161  // (b) If the method was called by an invoker thread push that thread
162  // onto the front of the run queue, this will cause the method
163  // to be resumed after this thread waits.
164  // (c) Invoke our thread directly by-passing the run queue.
165  // (d) Restore the process info to the caller.
166  // (e) Check to see if the calling method should throw an exception
167  // because of activity that occurred during the preemption.
168 
169  if ( active_p == NULL )
170  {
171  std::vector<sc_thread_handle>* invokers_p; // active invokers stack.
172  sc_thread_handle invoke_thread_p; // latest invocation thread.
173  sc_method_handle method_p; // active method.
174 
175  method_p = DCAST<sc_method_handle>(sc_get_current_process_b());
176  invokers_p = &get_active_invokers();
177  caller_info = m_curr_proc_info;
178  if ( invokers_p->size() != 0 )
179  {
180  invoke_thread_p = invokers_p->back();
181  DEBUG_MSG( DEBUG_NAME, invoke_thread_p,
182  "queueing invocation thread to execute next" );
183  execute_thread_next(invoke_thread_p);
184  }
185  DEBUG_MSG( DEBUG_NAME, thread_h, "preempting method with thread" );
186  set_curr_proc( (sc_process_b*)thread_h );
187  m_cor_pkg->yield( thread_h->m_cor_p );
188  m_curr_proc_info = caller_info;
189  DEBUG_MSG(DEBUG_NAME, thread_h, "back from preempting method w/thread");
190  method_p->check_for_throws();
191  }
192 
193  // CALLER IS A THREAD, BUT NOT THE THREAD TO BE RUN:
194  //
195  // (a) Push the calling thread onto the front of the runnable queue
196  // so it be the first thread to be run after this thread.
197  // (b) Push the thread to be run onto the front of the runnable queue so
198  // it will execute when we suspend the calling thread.
199  // (c) Suspend the active thread.
200 
201  else if ( active_p != thread_h )
202  {
203  DEBUG_MSG( DEBUG_NAME, thread_h,
204  "preempting active thread with thread" );
205  execute_thread_next( active_p );
206  execute_thread_next( thread_h );
207  active_p->suspend_me();
208  }
209 
210  // CALLER IS THE THREAD TO BE RUN:
211  //
212  // (a) Push the thread to be run onto the front of the runnable queue so
213  // it will execute when we suspend the calling thread.
214  // (b) Suspend the active thread.
215 
216  else
217  {
218  DEBUG_MSG(DEBUG_NAME,thread_h,"self preemption of active thread");
219  execute_thread_next( thread_h );
220  active_p->suspend_me();
221  }*/
222 }
223 
224 
225 inline
226 void
227 sc_simcontext::push_runnable_method( sc_method_handle method_h )
228 {
229  //DM 07/29/2019 experiment
230  for(std::vector<sc_method_process*>::iterator method_iter =
231  method_h->m_contingent_methods.begin();
232  method_iter != method_h->m_contingent_methods.end();
233  method_iter++)
234  {
235  (*method_iter)->dependent_methods.erase(method_h);
236  }
237  method_h->PWT_defining_proc = NULL;
238  m_runnable->push_back_method( method_h );
239 }
240 
241 inline
242 void
243 sc_simcontext::push_runnable_method_front( sc_method_handle method_h )
244 {
245  //DM 07/29/2019 experiment
246  for(std::vector<sc_method_process*>::iterator method_iter =
247  method_h->m_contingent_methods.begin();
248  method_iter != method_h->m_contingent_methods.end();
249  method_iter++)
250  {
251  (*method_iter)->dependent_methods.erase(method_h);
252  }
253  method_h->PWT_defining_proc = NULL;
254  m_runnable->push_front_method( method_h );
255 }
256 
257 inline
258 void
259 sc_simcontext::push_runnable_thread( sc_thread_handle thread_h )
260 {
261  //DM 07/29/2019 experiment
262  for(std::vector<sc_method_process*>::iterator method_iter =
263  thread_h->m_contingent_methods[thread_h->get_segment_id()].begin();
264  method_iter != thread_h->m_contingent_methods[thread_h->get_segment_id()].end();
265  method_iter++)
266  {
267  (*method_iter)->dependent_threads.erase(thread_h);
268  }
269  thread_h->PWT_defining_proc = NULL;
270  m_runnable->push_back_thread( thread_h );
271 }
272 
273 inline
274 void
275 sc_simcontext::push_runnable_thread_front( sc_thread_handle thread_h )
276 {
277  //DM 07/29/2019 experiment
278  for(std::vector<sc_method_process*>::iterator method_iter =
279  thread_h->m_contingent_methods[thread_h->get_segment_id()].begin();
280  method_iter != thread_h->m_contingent_methods[thread_h->get_segment_id()].end();
281  method_iter++)
282  {
283  (*method_iter)->dependent_threads.erase(thread_h);
284  }
285  thread_h->PWT_defining_proc = NULL;
286  m_runnable->push_front_thread( thread_h );
287 }
288 
289 
290 inline
292 sc_simcontext::pop_runnable_method()
293 {
294  sc_method_handle method_h = m_runnable->pop_method();
295  if( method_h == 0 ) {
296  reset_curr_proc();
297  return 0;
298  }
299 // set_curr_proc( (sc_process_b*)method_h );
300  return method_h;
301 }
302 
303 inline
305 sc_simcontext::pop_runnable_thread()
306 {
307  sc_thread_handle thread_h = m_runnable->pop_thread();
308  if( thread_h == 0 ) {
309  reset_curr_proc();
310  return 0;
311  }
312 // set_curr_proc( (sc_process_b*)thread_h );
313  return thread_h;
314 }
315 
316 inline
317 void
318 sc_simcontext::remove_runnable_method( sc_method_handle method_h )
319 {
320  m_runnable->remove_method( method_h );
321 }
322 
323 inline
324 void
325 sc_simcontext::remove_runnable_thread( sc_thread_handle thread_h )
326 {
327  m_runnable->remove_thread( thread_h );
328 }
329 
330 inline
331 std::vector<sc_thread_handle>&
333 {
334  return m_active_invokers;
335 }
336 
337 // ----------------------------------------------------------------------------
338 
339 extern void sc_defunct_process_function( sc_module* );
340 
341 
342 } // namespace sc_core
343 
344 #undef DEBUG_MSG
345 #undef DEBUG_NAME
346 
347 // $Log: sc_simcontext_int.h,v $
348 // Revision 1.14 2011/08/29 18:04:32 acg
349 // Philipp A. Hartmann: miscellaneous clean ups.
350 //
351 // Revision 1.13 2011/08/26 20:46:11 acg
352 // Andy Goodrich: moved the modification log to the end of the file to
353 // eliminate source line number skew when check-ins are done.
354 //
355 // Revision 1.12 2011/07/29 22:45:06 acg
356 // Andy Goodrich: added invocation of sc_method_process::check_for_throws()
357 // to the preempt_with() code to handle case where the preempting process
358 // causes a throw on the invoking method process.
359 //
360 // Revision 1.11 2011/04/13 02:45:11 acg
361 // Andy Goodrich: eliminated warning message that occurred if the DEBUG_MSG
362 // macro was used.
363 //
364 // Revision 1.10 2011/04/11 22:05:48 acg
365 // Andy Goodrich: use the DEBUG_NAME macro in DEBUG_MSG invocations.
366 //
367 // Revision 1.9 2011/04/10 22:12:32 acg
368 // Andy Goodrich: adding debugging macros.
369 //
370 // Revision 1.8 2011/04/08 18:26:07 acg
371 // Andy Goodrich: added execute_method_next() to handle method dispatch
372 // for asynchronous notifications that occur outside the evaluation phase.
373 //
374 // Revision 1.7 2011/02/18 20:27:14 acg
375 // Andy Goodrich: Updated Copyrights.
376 //
377 // Revision 1.6 2011/02/13 21:47:38 acg
378 // Andy Goodrich: update copyright notice.
379 //
380 // Revision 1.5 2011/02/08 08:17:50 acg
381 // Andy Goodrich: fixed bug in preempt_with() where I was resetting the
382 // process context rather than saving and restoring it.
383 //
384 // Revision 1.4 2011/02/01 21:12:56 acg
385 // Andy Goodrich: addition of preempt_with() method to allow immediate
386 // execution of threads for throws.
387 //
388 // Revision 1.3 2011/01/25 20:50:37 acg
389 // Andy Goodrich: changes for IEEE 1666 2011.
390 //
391 // Revision 1.2 2008/05/22 17:06:26 acg
392 // Andy Goodrich: updated copyright notice to include 2008.
393 //
394 // Revision 1.1.1.1 2006/12/15 20:20:05 acg
395 // SystemC 2.3
396 //
397 // Revision 1.6 2006/05/26 20:33:16 acg
398 // Andy Goodrich: changes required by additional platform compilers (i.e.,
399 // Microsoft VC++, Sun Forte, HP aCC).
400 //
401 // Revision 1.5 2006/01/19 00:29:52 acg
402 // Andy Goodrich: Yet another implementation for signal write checking. This
403 // one uses an environment variable SC_SIGNAL_WRITE_CHECK, that when set to
404 // DISABLE will disable write checking on signals.
405 //
406 // Revision 1.4 2006/01/18 21:42:37 acg
407 // Andy Goodrich: Changes for check writer support.
408 //
409 // Revision 1.3 2006/01/13 18:44:30 acg
410 // Added $Log to record CVS changes into the source.
411 
412 #endif
void push_back_thread(sc_thread_handle)
bool verbosity_flag_4
sc_thread_handle pop_thread()
void push_back_method(sc_method_handle)
bool verbosity_flag_1
void execute_method_next(sc_method_handle)
const char * name() const
Definition: sc_object.h:71
bool verbosity_flag_2
class sc_method_process * sc_method_handle
Definition: sc_process.h:120
sc_process_b * get_curr_proc() const
bool verbosity_flag_6
User initiated dynamic process support.
Definition: sc_process.h:558
bool verbosity_flag
void remove_method(sc_method_handle)
void sc_defunct_process_function(sc_module *)
void push_front_thread(sc_thread_handle)
static sc_process_b * m_last_created_process_p
Definition: sc_process.h:957
void push_front_method(sc_method_handle)
class sc_thread_process * sc_thread_handle
Definition: sc_process.h:121
bool verbosity_flag_3
sc_method_handle pop_method()
void remove_thread(sc_thread_handle)
Base class for all structural entities.
Definition: sc_module.h:83
void execute_thread_next(sc_thread_handle)
sc_simcontext * sc_get_curr_simcontext()
void set_curr_proc(sc_process_b *)
This function is not supported by the out-of-order simulation in the current release.
bool verbosity_flag_5
const char * sc_get_current_process_name()
std::vector< sc_thread_handle > & get_active_invokers()