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 __SYSTEMC_EXT_DT_FX_SC_CONTEXT_HH__ 59#define __SYSTEMC_EXT_DT_FX_SC_CONTEXT_HH__ 60 61#include <map> 62 63#include "../../core/sc_process_handle.hh" 64#include "../../utils/sc_report_handler.hh" 65#include "messages.hh" 66 67namespace sc_dt 68{ 69 70// classes defined in this module 71class sc_without_context; 72template <class T> 73class sc_global; 74template <class T> 75class sc_context; 76 77 78// ---------------------------------------------------------------------------- 79// CLASS : sc_without_context 80// 81// Empty class that is used for its type only. 82// ---------------------------------------------------------------------------- 83 84class sc_without_context {}; 85 86 87// ---------------------------------------------------------------------------- 88// TEMPLATE CLASS : sc_global 89// 90// Template global variable class; singleton; co-routine safe. 91// ---------------------------------------------------------------------------- 92 93template <class T> 94class sc_global 95{ 96 sc_global(); 97 void update(); 98 99 public: 100 static sc_global<T>* instance(); 101 const T*& value_ptr(); 102 103 private: 104 static sc_global<T> *m_instance; 105 106 std::map<void *, const T *> m_map; 107 void *m_proc; // context (current process or NULL) 108 const T *m_value_ptr; 109}; 110 111 112// ---------------------------------------------------------------------------- 113// ENUM : sc_context_begin 114// 115// Enumeration of context begin options. 116// ---------------------------------------------------------------------------- 117 118enum sc_context_begin 119{ 120 SC_NOW, 121 SC_LATER 122}; 123 124 125// ---------------------------------------------------------------------------- 126// CLASS : sc_context 127// 128// Template context class; co-routine safe. 129// ---------------------------------------------------------------------------- 130 131template <class T> 132class sc_context 133{ 134 // disabled 135 sc_context(const sc_context<T> &); 136 void *operator new(std::size_t); 137 138 public: 139 explicit sc_context(const T &, sc_context_begin=SC_NOW); 140 ~sc_context(); 141 142 void begin(); 143 void end(); 144 145 static const T &default_value(); 146 const T &value() const; 147 148 private: 149 sc_context &operator = (const sc_context &) /* = delete */; 150 151 const T m_value; 152 const T *&m_def_value_ptr; 153 const T *m_old_value_ptr; 154}; 155 156 157// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 158 159// ---------------------------------------------------------------------------- 160// TEMPLATE CLASS : sc_global 161// 162// Template global variable class; singleton; co-routine safe. 163// ---------------------------------------------------------------------------- 164 165template <class T> 166sc_global<T> *sc_global<T>::m_instance = 0; 167 168template <class T> 169inline sc_global<T>::sc_global() : m_map(), 170 // use &m_instance as unique "non-process" key (NULL denotes 'sc_main' 171 // context) 172 m_proc(&m_instance), m_value_ptr(0) 173{} 174 175 176template <class T> 177inline void 178sc_global<T>::update() 179{ 180 void *p = (::sc_gem5::Process *)sc_core::sc_get_current_process_handle(); 181 if (p != m_proc) { 182 const T *vp = m_map[p]; 183 if (vp == 0) { 184 vp = new T(sc_without_context()); 185 m_map.emplace(p, vp); 186 } 187 m_proc = p; 188 m_value_ptr = vp; 189 } 190} 191 192 193template <class T> 194inline sc_global<T> * 195sc_global<T>::instance() 196{ 197 if (m_instance == 0) { 198 m_instance = new sc_global<T>; 199 } 200 return m_instance; 201} 202 203 204template <class T> 205inline const T *& 206sc_global<T>::value_ptr() 207{ 208 update(); 209 return m_value_ptr; 210} 211 212 213// ---------------------------------------------------------------------------- 214// CLASS : sc_context 215// 216// Template context class; co-routine safe. 217// ---------------------------------------------------------------------------- 218 219template <class T> 220inline sc_context<T>::sc_context(const T &value_, sc_context_begin begin_) : 221 m_value(value_), 222 m_def_value_ptr(sc_global<T>::instance()->value_ptr()), 223 m_old_value_ptr(0) 224{ 225 if (begin_ == SC_NOW) { 226 m_old_value_ptr = m_def_value_ptr; 227 m_def_value_ptr = &m_value; 228 } 229} 230 231template <class T> 232inline sc_context<T>::~sc_context() 233{ 234 if (m_old_value_ptr != 0) { 235 m_def_value_ptr = m_old_value_ptr; 236 m_old_value_ptr = 0; 237 } 238} 239 240 241template <class T> 242inline void 243sc_context<T>::begin() 244{ 245 if (m_old_value_ptr == 0) { 246 m_old_value_ptr = m_def_value_ptr; 247 m_def_value_ptr = &m_value; 248 } else { 249 SC_REPORT_ERROR(sc_core::SC_ID_CONTEXT_BEGIN_FAILED_, 0); 250 } 251} 252 253template <class T> 254inline void 255sc_context<T>::end() 256{ 257 if (m_old_value_ptr != 0) { 258 m_def_value_ptr = m_old_value_ptr; 259 m_old_value_ptr = 0; 260 } else { 261 SC_REPORT_ERROR(sc_core::SC_ID_CONTEXT_END_FAILED_, 0); 262 } 263} 264 265 266template <class T> 267inline const T & 268sc_context<T>::default_value() 269{ 270 return *sc_global<T>::instance()->value_ptr(); 271} 272 273template <class T> 274inline const T & 275sc_context<T>::value() const 276{ 277 return m_value; 278} 279 280} // namespace sc_dt 281 282#endif // __SYSTEMC_EXT_DT_FX_SC_CONTEXT_HH__ 283