SystemC  Recoding Infrastructure for SystemC v0.6.0 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 
230  m_runnable->push_back_method( method_h );
231 }
232 
233 inline
234 void
235 sc_simcontext::push_runnable_method_front( sc_method_handle method_h )
236 {
237  m_runnable->push_front_method( method_h );
238 }
239 
240 inline
241 void
242 sc_simcontext::push_runnable_thread( sc_thread_handle thread_h )
243 {
244 
245  m_runnable->push_back_thread( thread_h );
246 }
247 
248 inline
249 void
250 sc_simcontext::push_runnable_thread_front( sc_thread_handle thread_h )
251 {
252 
253  m_runnable->push_front_thread( thread_h );
254 }
255 
256 
257 inline
259 sc_simcontext::pop_runnable_method()
260 {
261  sc_method_handle method_h = m_runnable->pop_method();
262  if( method_h == 0 ) {
263  reset_curr_proc();
264  return 0;
265  }
266 // set_curr_proc( (sc_process_b*)method_h );
267  return method_h;
268 }
269 
270 inline
272 sc_simcontext::pop_runnable_thread()
273 {
274  sc_thread_handle thread_h = m_runnable->pop_thread();
275  if( thread_h == 0 ) {
276  reset_curr_proc();
277  return 0;
278  }
279 // set_curr_proc( (sc_process_b*)thread_h );
280  return thread_h;
281 }
282 
283 inline
284 void
285 sc_simcontext::remove_runnable_method( sc_method_handle method_h )
286 {
287  m_runnable->remove_method( method_h );
288 }
289 
290 inline
291 void
292 sc_simcontext::remove_runnable_thread( sc_thread_handle thread_h )
293 {
294  m_runnable->remove_thread( thread_h );
295 }
296 
297 inline
298 std::vector<sc_thread_handle>&
300 {
301  return m_active_invokers;
302 }
303 
304 // ----------------------------------------------------------------------------
305 
306 extern void sc_defunct_process_function( sc_module* );
307 
308 
309 } // namespace sc_core
310 
311 #undef DEBUG_MSG
312 #undef DEBUG_NAME
313 
314 // $Log: sc_simcontext_int.h,v $
315 // Revision 1.14 2011/08/29 18:04:32 acg
316 // Philipp A. Hartmann: miscellaneous clean ups.
317 //
318 // Revision 1.13 2011/08/26 20:46:11 acg
319 // Andy Goodrich: moved the modification log to the end of the file to
320 // eliminate source line number skew when check-ins are done.
321 //
322 // Revision 1.12 2011/07/29 22:45:06 acg
323 // Andy Goodrich: added invocation of sc_method_process::check_for_throws()
324 // to the preempt_with() code to handle case where the preempting process
325 // causes a throw on the invoking method process.
326 //
327 // Revision 1.11 2011/04/13 02:45:11 acg
328 // Andy Goodrich: eliminated warning message that occurred if the DEBUG_MSG
329 // macro was used.
330 //
331 // Revision 1.10 2011/04/11 22:05:48 acg
332 // Andy Goodrich: use the DEBUG_NAME macro in DEBUG_MSG invocations.
333 //
334 // Revision 1.9 2011/04/10 22:12:32 acg
335 // Andy Goodrich: adding debugging macros.
336 //
337 // Revision 1.8 2011/04/08 18:26:07 acg
338 // Andy Goodrich: added execute_method_next() to handle method dispatch
339 // for asynchronous notifications that occur outside the evaluation phase.
340 //
341 // Revision 1.7 2011/02/18 20:27:14 acg
342 // Andy Goodrich: Updated Copyrights.
343 //
344 // Revision 1.6 2011/02/13 21:47:38 acg
345 // Andy Goodrich: update copyright notice.
346 //
347 // Revision 1.5 2011/02/08 08:17:50 acg
348 // Andy Goodrich: fixed bug in preempt_with() where I was resetting the
349 // process context rather than saving and restoring it.
350 //
351 // Revision 1.4 2011/02/01 21:12:56 acg
352 // Andy Goodrich: addition of preempt_with() method to allow immediate
353 // execution of threads for throws.
354 //
355 // Revision 1.3 2011/01/25 20:50:37 acg
356 // Andy Goodrich: changes for IEEE 1666 2011.
357 //
358 // Revision 1.2 2008/05/22 17:06:26 acg
359 // Andy Goodrich: updated copyright notice to include 2008.
360 //
361 // Revision 1.1.1.1 2006/12/15 20:20:05 acg
362 // SystemC 2.3
363 //
364 // Revision 1.6 2006/05/26 20:33:16 acg
365 // Andy Goodrich: changes required by additional platform compilers (i.e.,
366 // Microsoft VC++, Sun Forte, HP aCC).
367 //
368 // Revision 1.5 2006/01/19 00:29:52 acg
369 // Andy Goodrich: Yet another implementation for signal write checking. This
370 // one uses an environment variable SC_SIGNAL_WRITE_CHECK, that when set to
371 // DISABLE will disable write checking on signals.
372 //
373 // Revision 1.4 2006/01/18 21:42:37 acg
374 // Andy Goodrich: Changes for check writer support.
375 //
376 // Revision 1.3 2006/01/13 18:44:30 acg
377 // Added $Log to record CVS changes into the source.
378 
379 #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:119
sc_process_b * get_curr_proc() const
bool verbosity_flag_6
User initiated dynamic process support.
Definition: sc_process.h:555
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:954
void push_front_method(sc_method_handle)
class sc_thread_process * sc_thread_handle
Definition: sc_process.h:120
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()