sc_context.hh revision 12853
12686Sksewell@umich.edu/*****************************************************************************
25254Sksewell@umich.edu
35254Sksewell@umich.edu  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
42686Sksewell@umich.edu  more contributor license agreements.  See the NOTICE file distributed
55254Sksewell@umich.edu  with this work for additional information regarding copyright ownership.
65254Sksewell@umich.edu  Accellera licenses this file to you under the Apache License, Version 2.0
75254Sksewell@umich.edu  (the "License"); you may not use this file except in compliance with the
85254Sksewell@umich.edu  License.  You may obtain a copy of the License at
95254Sksewell@umich.edu
105254Sksewell@umich.edu    http://www.apache.org/licenses/LICENSE-2.0
115254Sksewell@umich.edu
125254Sksewell@umich.edu  Unless required by applicable law or agreed to in writing, software
135254Sksewell@umich.edu  distributed under the License is distributed on an "AS IS" BASIS,
145254Sksewell@umich.edu  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
152686Sksewell@umich.edu  implied.  See the License for the specific language governing
165254Sksewell@umich.edu  permissions and limitations under the License.
175254Sksewell@umich.edu
185254Sksewell@umich.edu *****************************************************************************/
195254Sksewell@umich.edu
205254Sksewell@umich.edu/*****************************************************************************
215254Sksewell@umich.edu
225254Sksewell@umich.edu  sc_context.h -
235254Sksewell@umich.edu
245254Sksewell@umich.edu  Original Author: Martin Janssen, Synopsys, Inc.
255254Sksewell@umich.edu
265254Sksewell@umich.edu *****************************************************************************/
272706Sksewell@umich.edu
285254Sksewell@umich.edu/*****************************************************************************
292686Sksewell@umich.edu
302686Sksewell@umich.edu  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
314661Sksewell@umich.edu  changes you are making here.
322686Sksewell@umich.edu
334661Sksewell@umich.edu      Name, Affiliation, Date:
344661Sksewell@umich.edu  Description of Modification:
354661Sksewell@umich.edu
364661Sksewell@umich.edu *****************************************************************************/
374661Sksewell@umich.edu
382980Sgblack@eecs.umich.edu// $Log: sc_context.h,v $
392686Sksewell@umich.edu// Revision 1.2  2011/08/24 22:05:43  acg
405222Sksewell@umich.edu//  Torsten Maehne: initialization changes to remove warnings.
415222Sksewell@umich.edu//
425222Sksewell@umich.edu// Revision 1.1.1.1  2006/12/15 20:20:04  acg
435222Sksewell@umich.edu// SystemC 2.3
445222Sksewell@umich.edu//
455222Sksewell@umich.edu// Revision 1.5  2006/05/26 20:36:52  acg
462686Sksewell@umich.edu//  Andy Goodrich: added a using for sc_core::default_ptr_hash_fn to keep HP
474661Sksewell@umich.edu//  aCC happy.
482686Sksewell@umich.edu//
495222Sksewell@umich.edu// Revision 1.4  2006/03/21 00:00:31  acg
505222Sksewell@umich.edu//   Andy Goodrich: changed name of sc_get_current_process_base() to be
512686Sksewell@umich.edu//   sc_get_current_process_b() since its returning an sc_process_b instance.
525222Sksewell@umich.edu//
535222Sksewell@umich.edu// Revision 1.3  2006/01/13 18:53:57  acg
545222Sksewell@umich.edu// Andy Goodrich: added $Log command so that CVS comments are reproduced in
555222Sksewell@umich.edu// the source.
565222Sksewell@umich.edu//
575222Sksewell@umich.edu
585222Sksewell@umich.edu#ifndef __SYSTEMC_EXT_DT_FX_SC_CONTEXT_HH__
595222Sksewell@umich.edu#define __SYSTEMC_EXT_DT_FX_SC_CONTEXT_HH__
605222Sksewell@umich.edu
615222Sksewell@umich.edu#include <map>
625498Ssaidi@eecs.umich.edu
635222Sksewell@umich.edu#include "../../core/sc_process_handle.hh"
645222Sksewell@umich.edu#include "../../utils/sc_report_handler.hh"
655222Sksewell@umich.edu
665222Sksewell@umich.edunamespace sc_dt
675222Sksewell@umich.edu{
685222Sksewell@umich.edu
695222Sksewell@umich.edu// classes defined in this module
705222Sksewell@umich.educlass sc_without_context;
715222Sksewell@umich.edutemplate <class T>
725222Sksewell@umich.educlass sc_global;
735222Sksewell@umich.edutemplate <class T>
745222Sksewell@umich.educlass sc_context;
752686Sksewell@umich.edu
762686Sksewell@umich.edu
772686Sksewell@umich.edu// ----------------------------------------------------------------------------
782686Sksewell@umich.edu//  CLASS : sc_without_context
792686Sksewell@umich.edu//
802686Sksewell@umich.edu//  Empty class that is used for its type only.
812686Sksewell@umich.edu// ----------------------------------------------------------------------------
822686Sksewell@umich.edu
832686Sksewell@umich.educlass sc_without_context {};
842686Sksewell@umich.edu
852686Sksewell@umich.edu
862686Sksewell@umich.edu// ----------------------------------------------------------------------------
872686Sksewell@umich.edu//  TEMPLATE CLASS : sc_global
882686Sksewell@umich.edu//
892686Sksewell@umich.edu//  Template global variable class; singleton; co-routine safe.
902686Sksewell@umich.edu// ----------------------------------------------------------------------------
912686Sksewell@umich.edu
922686Sksewell@umich.edutemplate <class T>
932686Sksewell@umich.educlass sc_global
942686Sksewell@umich.edu{
952686Sksewell@umich.edu    sc_global();
962686Sksewell@umich.edu    void update();
972686Sksewell@umich.edu
982686Sksewell@umich.edu  public:
992686Sksewell@umich.edu    static sc_global<T>* instance();
1002686Sksewell@umich.edu    const T*& value_ptr();
1012686Sksewell@umich.edu
1022686Sksewell@umich.edu  private:
1032686Sksewell@umich.edu    static sc_global<T> *m_instance;
1042686Sksewell@umich.edu
1052686Sksewell@umich.edu    std::map<void *, const T *> m_map;
1062686Sksewell@umich.edu    void *m_proc; // context (current process or NULL)
1072686Sksewell@umich.edu    const T *m_value_ptr;
1082686Sksewell@umich.edu};
1092686Sksewell@umich.edu
1102686Sksewell@umich.edu
1112686Sksewell@umich.edu// ----------------------------------------------------------------------------
1122686Sksewell@umich.edu//  ENUM : sc_context_begin
1132686Sksewell@umich.edu//
1142686Sksewell@umich.edu//  Enumeration of context begin options.
1152686Sksewell@umich.edu// ----------------------------------------------------------------------------
1162686Sksewell@umich.edu
1172686Sksewell@umich.eduenum sc_context_begin
1185222Sksewell@umich.edu{
1192686Sksewell@umich.edu    SC_NOW,
1202686Sksewell@umich.edu    SC_LATER
1212686Sksewell@umich.edu};
1222686Sksewell@umich.edu
1232686Sksewell@umich.edu
1242686Sksewell@umich.edu// ----------------------------------------------------------------------------
1252686Sksewell@umich.edu//  CLASS : sc_context
1262686Sksewell@umich.edu//
1272686Sksewell@umich.edu//  Template context class; co-routine safe.
1282686Sksewell@umich.edu// ----------------------------------------------------------------------------
1295222Sksewell@umich.edu
1302686Sksewell@umich.edutemplate <class T>
1312686Sksewell@umich.educlass sc_context
1322686Sksewell@umich.edu{
1332686Sksewell@umich.edu    // disabled
1342686Sksewell@umich.edu    sc_context(const sc_context<T> &);
1352686Sksewell@umich.edu    void *operator new(std::size_t);
1365222Sksewell@umich.edu
1372686Sksewell@umich.edu  public:
1382686Sksewell@umich.edu    explicit sc_context(const T &, sc_context_begin=SC_NOW);
1392686Sksewell@umich.edu    ~sc_context();
1402686Sksewell@umich.edu
1412686Sksewell@umich.edu    void begin();
1422686Sksewell@umich.edu    void end();
1432686Sksewell@umich.edu
1445222Sksewell@umich.edu    static const T &default_value();
1452686Sksewell@umich.edu    const T &value() const;
1462686Sksewell@umich.edu
1472686Sksewell@umich.edu  private:
1485570Snate@binkert.org    sc_context &operator = (const sc_context &) /* = delete */;
1492686Sksewell@umich.edu
1502686Sksewell@umich.edu    const T m_value;
1512686Sksewell@umich.edu    const T *&m_def_value_ptr;
1522686Sksewell@umich.edu    const T *m_old_value_ptr;
1532686Sksewell@umich.edu};
1542686Sksewell@umich.edu
1552686Sksewell@umich.edu
1565222Sksewell@umich.edu// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
1572686Sksewell@umich.edu
1582686Sksewell@umich.edu// ----------------------------------------------------------------------------
1592686Sksewell@umich.edu//  TEMPLATE CLASS : sc_global
1602686Sksewell@umich.edu//
1612686Sksewell@umich.edu//  Template global variable class; singleton; co-routine safe.
1622686Sksewell@umich.edu// ----------------------------------------------------------------------------
1632686Sksewell@umich.edu
1642686Sksewell@umich.edutemplate <class T>
1652686Sksewell@umich.edusc_global<T> *sc_global<T>::m_instance = 0;
1662686Sksewell@umich.edu
1672686Sksewell@umich.edutemplate <class T>
1682686Sksewell@umich.eduinline sc_global<T>::sc_global() : m_map(),
1692686Sksewell@umich.edu    // use &m_instance as unique "non-process" key (NULL denotes 'sc_main'
1705222Sksewell@umich.edu    // context)
1712686Sksewell@umich.edu    m_proc(&m_instance), m_value_ptr(0)
1722686Sksewell@umich.edu{}
1732686Sksewell@umich.edu
1742686Sksewell@umich.edu
1752686Sksewell@umich.edutemplate <class T>
1762686Sksewell@umich.eduinline void
1772686Sksewell@umich.edusc_global<T>::update()
1782686Sksewell@umich.edu{
1792686Sksewell@umich.edu    void *p = (::sc_gem5::Process *)sc_core::sc_get_current_process_handle();
1802686Sksewell@umich.edu    if (p != m_proc) {
1812686Sksewell@umich.edu        const T *vp = m_map[p];
1822686Sksewell@umich.edu        if (vp == 0) {
1832686Sksewell@umich.edu            vp = new T(sc_without_context());
1842686Sksewell@umich.edu            m_map.emplace(p, vp);
1852686Sksewell@umich.edu        }
1862686Sksewell@umich.edu        m_proc = p;
1872686Sksewell@umich.edu        m_value_ptr = vp;
1882686Sksewell@umich.edu    }
1892686Sksewell@umich.edu}
1902686Sksewell@umich.edu
1912686Sksewell@umich.edu
1922686Sksewell@umich.edutemplate <class T>
1935222Sksewell@umich.eduinline sc_global<T> *
1942686Sksewell@umich.edusc_global<T>::instance()
1952686Sksewell@umich.edu{
1962686Sksewell@umich.edu    if (m_instance == 0) {
1972686Sksewell@umich.edu        m_instance = new sc_global<T>;
1982686Sksewell@umich.edu    }
1992686Sksewell@umich.edu    return m_instance;
2002686Sksewell@umich.edu}
2012686Sksewell@umich.edu
2022686Sksewell@umich.edu
2032686Sksewell@umich.edutemplate <class T>
2042686Sksewell@umich.eduinline const T *&
2052686Sksewell@umich.edusc_global<T>::value_ptr()
2062686Sksewell@umich.edu{
2072686Sksewell@umich.edu    update();
2082686Sksewell@umich.edu    return m_value_ptr;
2092686Sksewell@umich.edu}
2102686Sksewell@umich.edu
2112686Sksewell@umich.edu
2122686Sksewell@umich.edu// ----------------------------------------------------------------------------
2132686Sksewell@umich.edu//  CLASS : sc_context
2142686Sksewell@umich.edu//
2155222Sksewell@umich.edu//  Template context class; co-routine safe.
2162686Sksewell@umich.edu// ----------------------------------------------------------------------------
2172686Sksewell@umich.edu
2182686Sksewell@umich.edutemplate <class T>
2192686Sksewell@umich.eduinline sc_context<T>::sc_context(const T &value_, sc_context_begin begin_) :
2202686Sksewell@umich.edu        m_value(value_),
2212686Sksewell@umich.edu        m_def_value_ptr(sc_global<T>::instance()->value_ptr()),
2222686Sksewell@umich.edu        m_old_value_ptr(0)
2232686Sksewell@umich.edu{
2242686Sksewell@umich.edu    if (begin_ == SC_NOW) {
2252686Sksewell@umich.edu        m_old_value_ptr = m_def_value_ptr;
2262686Sksewell@umich.edu        m_def_value_ptr = &m_value;
2272686Sksewell@umich.edu    }
2282686Sksewell@umich.edu}
2292686Sksewell@umich.edu
2302686Sksewell@umich.edutemplate <class T>
2312686Sksewell@umich.eduinline sc_context<T>::~sc_context()
2322686Sksewell@umich.edu{
2332686Sksewell@umich.edu    if (m_old_value_ptr != 0) {
2342686Sksewell@umich.edu        m_def_value_ptr = m_old_value_ptr;
2354661Sksewell@umich.edu        m_old_value_ptr = 0;
2364661Sksewell@umich.edu    }
2375222Sksewell@umich.edu}
2384661Sksewell@umich.edu
2395222Sksewell@umich.edu
2404661Sksewell@umich.edutemplate <class T>
2415222Sksewell@umich.eduinline void
2425222Sksewell@umich.edusc_context<T>::begin()
2435222Sksewell@umich.edu{
2445222Sksewell@umich.edu    if (m_old_value_ptr == 0) {
2455222Sksewell@umich.edu        m_old_value_ptr = m_def_value_ptr;
2465222Sksewell@umich.edu        m_def_value_ptr = &m_value;
2475222Sksewell@umich.edu    } else {
2485222Sksewell@umich.edu        SC_REPORT_ERROR("context begin failed", 0);
2495222Sksewell@umich.edu    }
2505222Sksewell@umich.edu}
2515222Sksewell@umich.edu
2525222Sksewell@umich.edutemplate <class T>
2535222Sksewell@umich.eduinline void
2545222Sksewell@umich.edusc_context<T>::end()
2555222Sksewell@umich.edu{
2565222Sksewell@umich.edu    if (m_old_value_ptr != 0) {
2575222Sksewell@umich.edu        m_def_value_ptr = m_old_value_ptr;
2585222Sksewell@umich.edu        m_old_value_ptr = 0;
2595222Sksewell@umich.edu    } else {
2605222Sksewell@umich.edu        SC_REPORT_ERROR("context end failed", 0);
2615222Sksewell@umich.edu    }
2625715Shsul@eecs.umich.edu}
2635222Sksewell@umich.edu
2645222Sksewell@umich.edu
2655222Sksewell@umich.edutemplate <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