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