SystemC  2.3.1
Accellera SystemC proof-of-concept library
sc_context.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_context.h -
21 
22  Original Author: Martin Janssen, Synopsys, Inc.
23 
24  *****************************************************************************/
25 
26 /*****************************************************************************
27 
28  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
29  changes you are making here.
30 
31  Name, Affiliation, Date:
32  Description of Modification:
33 
34  *****************************************************************************/
35 
36 // $Log: sc_context.h,v $
37 // Revision 1.2 2011/08/24 22:05:43 acg
38 // Torsten Maehne: initialization changes to remove warnings.
39 //
40 // Revision 1.1.1.1 2006/12/15 20:20:04 acg
41 // SystemC 2.3
42 //
43 // Revision 1.5 2006/05/26 20:36:52 acg
44 // Andy Goodrich: added a using for sc_core::default_ptr_hash_fn to keep HP
45 // aCC happy.
46 //
47 // Revision 1.4 2006/03/21 00:00:31 acg
48 // Andy Goodrich: changed name of sc_get_current_process_base() to be
49 // sc_get_current_process_b() since its returning an sc_process_b instance.
50 //
51 // Revision 1.3 2006/01/13 18:53:57 acg
52 // Andy Goodrich: added $Log command so that CVS comments are reproduced in
53 // the source.
54 //
55 
56 #ifndef SC_CONTEXT_H
57 #define SC_CONTEXT_H
58 
59 
62 #include "sysc/utils/sc_hash.h"
63 
64 
65 namespace sc_core {
66  class sc_process_b;
67 }
68 
69 using sc_core::default_ptr_hash_fn; // To keep HP aCC happy.
70 
71 namespace sc_dt
72 {
73 
74 // classes defined in this module
75 class sc_without_context;
76 template <class T> class sc_global;
77 template <class T> class sc_context;
78 
79 
80 // ----------------------------------------------------------------------------
81 // CLASS : sc_without_context
82 //
83 // Empty class that is used for its type only.
84 // ----------------------------------------------------------------------------
85 
87 
88 
89 // ----------------------------------------------------------------------------
90 // TEMPLATE CLASS : sc_global
91 //
92 // Template global variable class; singleton; co-routine safe.
93 // ----------------------------------------------------------------------------
94 
95 template <class T>
96 class sc_global
97 {
98 
99  sc_global();
100 
101  void update();
102 
103 public:
104 
105  static sc_global<T>* instance();
106 
107  const T*& value_ptr();
108 
109 private:
110  static sc_global<T>* m_instance;
111 
113  void* m_proc; // context (current process or NULL)
114  const T* m_value_ptr;
115 
116 };
117 
118 
119 // ----------------------------------------------------------------------------
120 // ENUM : sc_context_begin
121 //
122 // Enumeration of context begin options.
123 // ----------------------------------------------------------------------------
124 
126 {
129 };
130 
131 
132 // ----------------------------------------------------------------------------
133 // CLASS : sc_context
134 //
135 // Template context class; co-routine safe.
136 // ----------------------------------------------------------------------------
137 
138 template <class T>
139 class sc_context
140 {
141  // disabled
142  sc_context( const sc_context<T>& );
143  void* operator new( std::size_t );
144 
145 public:
146 
147  explicit sc_context( const T&, sc_context_begin = SC_NOW );
148  ~sc_context();
149 
150  void begin();
151  void end();
152 
153  static const T& default_value();
154  const T& value() const;
155 
156 private:
157 
158  const T m_value;
159  const T*& m_def_value_ptr;
160  const T* m_old_value_ptr;
161 };
162 
163 
164 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
165 
166 // ----------------------------------------------------------------------------
167 // TEMPLATE CLASS : sc_global
168 //
169 // Template global variable class; singleton; co-routine safe.
170 // ----------------------------------------------------------------------------
171 
172 template <class T>
173 sc_global<T>* sc_global<T>::m_instance = 0;
174 
175 template <class T>
176 inline
177 sc_global<T>::sc_global()
178  : m_map()
179  // use &m_instance as unique "non-process" key (NULL denotes 'sc_main' context)
180  , m_proc( &m_instance )
181  , m_value_ptr( 0 )
182 {}
183 
184 
185 template <class T>
186 inline
187 void
188 sc_global<T>::update()
189 {
191  if( p != m_proc )
192  {
193  const T* vp = m_map[p];
194  if( vp == 0 )
195  {
196  vp = new T( sc_without_context() );
197  m_map.insert( p, vp );
198  }
199  m_proc = p;
200  m_value_ptr = vp;
201  }
202 }
203 
204 
205 template <class T>
206 inline
207 sc_global<T>*
209 {
210  if( m_instance == 0 )
211  {
212  m_instance = new sc_global<T>;
213  }
214  return m_instance;
215 }
216 
217 
218 template <class T>
219 inline
220 const T*&
222 {
223  update();
224  return m_value_ptr;
225 }
226 
227 
228 // ----------------------------------------------------------------------------
229 // CLASS : sc_context
230 //
231 // Template context class; co-routine safe.
232 // ----------------------------------------------------------------------------
233 
234 template <class T>
235 inline
237 : m_value( value_ ),
238  m_def_value_ptr( sc_global<T>::instance()->value_ptr() ),
239  m_old_value_ptr( 0 )
240 {
241  if( begin == SC_NOW )
242  {
243  m_old_value_ptr = m_def_value_ptr;
244  m_def_value_ptr = &m_value;
245  }
246 }
247 
248 template <class T>
249 inline
251 {
252  if( m_old_value_ptr != 0 )
253  {
254  m_def_value_ptr = m_old_value_ptr;
255  m_old_value_ptr = 0;
256  }
257 }
258 
259 
260 template <class T>
261 inline
262 void
264 {
265  if( m_old_value_ptr == 0 )
266  {
267  m_old_value_ptr = m_def_value_ptr;
268  m_def_value_ptr = &m_value;
269  }
270  else
271  {
272  SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_BEGIN_FAILED_, 0 );
273  }
274 }
275 
276 template <class T>
277 inline
278 void
280 {
281  if( m_old_value_ptr != 0 )
282  {
283  m_def_value_ptr = m_old_value_ptr;
284  m_old_value_ptr = 0;
285  }
286  else
287  {
288  SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_END_FAILED_, 0 );
289  }
290 }
291 
292 
293 template <class T>
294 inline
295 const T&
297 {
298  return *sc_global<T>::instance()->value_ptr();
299 }
300 
301 template <class T>
302 inline
303 const T&
305 {
306  return m_value;
307 }
308 
309 } // namespace sc_dt
310 
311 
312 #endif
313 
314 // Taf!
static sc_global< T > * instance()
Definition: sc_context.h:208
sc_process_b sc_process_b
Definition: sc_process.h:447
sc_process_b * sc_get_current_process_b()
sc_context_begin
Definition: sc_context.h:125
unsigned default_ptr_hash_fn(const void *)
static const T & default_value()
Definition: sc_context.h:296
const T & value() const
Definition: sc_context.h:304
const T *& value_ptr()
Definition: sc_context.h:221
#define SC_REPORT_ERROR(msg_type, msg)
Definition: sc_report.h:213