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