sc_context.hh revision 12853
112853Sgabeblack@google.com/*****************************************************************************
212853Sgabeblack@google.com
312853Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412853Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512853Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612853Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712853Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812853Sgabeblack@google.com  License.  You may obtain a copy of the License at
912853Sgabeblack@google.com
1012853Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112853Sgabeblack@google.com
1212853Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312853Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412853Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512853Sgabeblack@google.com  implied.  See the License for the specific language governing
1612853Sgabeblack@google.com  permissions and limitations under the License.
1712853Sgabeblack@google.com
1812853Sgabeblack@google.com *****************************************************************************/
1912853Sgabeblack@google.com
2012853Sgabeblack@google.com/*****************************************************************************
2112853Sgabeblack@google.com
2212853Sgabeblack@google.com  sc_context.h -
2312853Sgabeblack@google.com
2412853Sgabeblack@google.com  Original Author: Martin Janssen, Synopsys, Inc.
2512853Sgabeblack@google.com
2612853Sgabeblack@google.com *****************************************************************************/
2712853Sgabeblack@google.com
2812853Sgabeblack@google.com/*****************************************************************************
2912853Sgabeblack@google.com
3012853Sgabeblack@google.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3112853Sgabeblack@google.com  changes you are making here.
3212853Sgabeblack@google.com
3312853Sgabeblack@google.com      Name, Affiliation, Date:
3412853Sgabeblack@google.com  Description of Modification:
3512853Sgabeblack@google.com
3612853Sgabeblack@google.com *****************************************************************************/
3712853Sgabeblack@google.com
3812853Sgabeblack@google.com// $Log: sc_context.h,v $
3912853Sgabeblack@google.com// Revision 1.2  2011/08/24 22:05:43  acg
4012853Sgabeblack@google.com//  Torsten Maehne: initialization changes to remove warnings.
4112853Sgabeblack@google.com//
4212853Sgabeblack@google.com// Revision 1.1.1.1  2006/12/15 20:20:04  acg
4312853Sgabeblack@google.com// SystemC 2.3
4412853Sgabeblack@google.com//
4512853Sgabeblack@google.com// Revision 1.5  2006/05/26 20:36:52  acg
4612853Sgabeblack@google.com//  Andy Goodrich: added a using for sc_core::default_ptr_hash_fn to keep HP
4712853Sgabeblack@google.com//  aCC happy.
4812853Sgabeblack@google.com//
4912853Sgabeblack@google.com// Revision 1.4  2006/03/21 00:00:31  acg
5012853Sgabeblack@google.com//   Andy Goodrich: changed name of sc_get_current_process_base() to be
5112853Sgabeblack@google.com//   sc_get_current_process_b() since its returning an sc_process_b instance.
5212853Sgabeblack@google.com//
5312853Sgabeblack@google.com// Revision 1.3  2006/01/13 18:53:57  acg
5412853Sgabeblack@google.com// Andy Goodrich: added $Log command so that CVS comments are reproduced in
5512853Sgabeblack@google.com// the source.
5612853Sgabeblack@google.com//
5712853Sgabeblack@google.com
5812853Sgabeblack@google.com#ifndef __SYSTEMC_EXT_DT_FX_SC_CONTEXT_HH__
5912853Sgabeblack@google.com#define __SYSTEMC_EXT_DT_FX_SC_CONTEXT_HH__
6012853Sgabeblack@google.com
6112853Sgabeblack@google.com#include <map>
6212853Sgabeblack@google.com
6312853Sgabeblack@google.com#include "../../core/sc_process_handle.hh"
6412853Sgabeblack@google.com#include "../../utils/sc_report_handler.hh"
6512853Sgabeblack@google.com
6612853Sgabeblack@google.comnamespace sc_dt
6712853Sgabeblack@google.com{
6812853Sgabeblack@google.com
6912853Sgabeblack@google.com// classes defined in this module
7012853Sgabeblack@google.comclass sc_without_context;
7112853Sgabeblack@google.comtemplate <class T>
7212853Sgabeblack@google.comclass sc_global;
7312853Sgabeblack@google.comtemplate <class T>
7412853Sgabeblack@google.comclass sc_context;
7512853Sgabeblack@google.com
7612853Sgabeblack@google.com
7712853Sgabeblack@google.com// ----------------------------------------------------------------------------
7812853Sgabeblack@google.com//  CLASS : sc_without_context
7912853Sgabeblack@google.com//
8012853Sgabeblack@google.com//  Empty class that is used for its type only.
8112853Sgabeblack@google.com// ----------------------------------------------------------------------------
8212853Sgabeblack@google.com
8312853Sgabeblack@google.comclass sc_without_context {};
8412853Sgabeblack@google.com
8512853Sgabeblack@google.com
8612853Sgabeblack@google.com// ----------------------------------------------------------------------------
8712853Sgabeblack@google.com//  TEMPLATE CLASS : sc_global
8812853Sgabeblack@google.com//
8912853Sgabeblack@google.com//  Template global variable class; singleton; co-routine safe.
9012853Sgabeblack@google.com// ----------------------------------------------------------------------------
9112853Sgabeblack@google.com
9212853Sgabeblack@google.comtemplate <class T>
9312853Sgabeblack@google.comclass sc_global
9412853Sgabeblack@google.com{
9512853Sgabeblack@google.com    sc_global();
9612853Sgabeblack@google.com    void update();
9712853Sgabeblack@google.com
9812853Sgabeblack@google.com  public:
9912853Sgabeblack@google.com    static sc_global<T>* instance();
10012853Sgabeblack@google.com    const T*& value_ptr();
10112853Sgabeblack@google.com
10212853Sgabeblack@google.com  private:
10312853Sgabeblack@google.com    static sc_global<T> *m_instance;
10412853Sgabeblack@google.com
10512853Sgabeblack@google.com    std::map<void *, const T *> m_map;
10612853Sgabeblack@google.com    void *m_proc; // context (current process or NULL)
10712853Sgabeblack@google.com    const T *m_value_ptr;
10812853Sgabeblack@google.com};
10912853Sgabeblack@google.com
11012853Sgabeblack@google.com
11112853Sgabeblack@google.com// ----------------------------------------------------------------------------
11212853Sgabeblack@google.com//  ENUM : sc_context_begin
11312853Sgabeblack@google.com//
11412853Sgabeblack@google.com//  Enumeration of context begin options.
11512853Sgabeblack@google.com// ----------------------------------------------------------------------------
11612853Sgabeblack@google.com
11712853Sgabeblack@google.comenum sc_context_begin
11812853Sgabeblack@google.com{
11912853Sgabeblack@google.com    SC_NOW,
12012853Sgabeblack@google.com    SC_LATER
12112853Sgabeblack@google.com};
12212853Sgabeblack@google.com
12312853Sgabeblack@google.com
12412853Sgabeblack@google.com// ----------------------------------------------------------------------------
12512853Sgabeblack@google.com//  CLASS : sc_context
12612853Sgabeblack@google.com//
12712853Sgabeblack@google.com//  Template context class; co-routine safe.
12812853Sgabeblack@google.com// ----------------------------------------------------------------------------
12912853Sgabeblack@google.com
13012853Sgabeblack@google.comtemplate <class T>
13112853Sgabeblack@google.comclass sc_context
13212853Sgabeblack@google.com{
13312853Sgabeblack@google.com    // disabled
13412853Sgabeblack@google.com    sc_context(const sc_context<T> &);
13512853Sgabeblack@google.com    void *operator new(std::size_t);
13612853Sgabeblack@google.com
13712853Sgabeblack@google.com  public:
13812853Sgabeblack@google.com    explicit sc_context(const T &, sc_context_begin=SC_NOW);
13912853Sgabeblack@google.com    ~sc_context();
14012853Sgabeblack@google.com
14112853Sgabeblack@google.com    void begin();
14212853Sgabeblack@google.com    void end();
14312853Sgabeblack@google.com
14412853Sgabeblack@google.com    static const T &default_value();
14512853Sgabeblack@google.com    const T &value() const;
14612853Sgabeblack@google.com
14712853Sgabeblack@google.com  private:
14812853Sgabeblack@google.com    sc_context &operator = (const sc_context &) /* = delete */;
14912853Sgabeblack@google.com
15012853Sgabeblack@google.com    const T m_value;
15112853Sgabeblack@google.com    const T *&m_def_value_ptr;
15212853Sgabeblack@google.com    const T *m_old_value_ptr;
15312853Sgabeblack@google.com};
15412853Sgabeblack@google.com
15512853Sgabeblack@google.com
15612853Sgabeblack@google.com// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
15712853Sgabeblack@google.com
15812853Sgabeblack@google.com// ----------------------------------------------------------------------------
15912853Sgabeblack@google.com//  TEMPLATE CLASS : sc_global
16012853Sgabeblack@google.com//
16112853Sgabeblack@google.com//  Template global variable class; singleton; co-routine safe.
16212853Sgabeblack@google.com// ----------------------------------------------------------------------------
16312853Sgabeblack@google.com
16412853Sgabeblack@google.comtemplate <class T>
16512853Sgabeblack@google.comsc_global<T> *sc_global<T>::m_instance = 0;
16612853Sgabeblack@google.com
16712853Sgabeblack@google.comtemplate <class T>
16812853Sgabeblack@google.cominline sc_global<T>::sc_global() : m_map(),
16912853Sgabeblack@google.com    // use &m_instance as unique "non-process" key (NULL denotes 'sc_main'
17012853Sgabeblack@google.com    // context)
17112853Sgabeblack@google.com    m_proc(&m_instance), m_value_ptr(0)
17212853Sgabeblack@google.com{}
17312853Sgabeblack@google.com
17412853Sgabeblack@google.com
17512853Sgabeblack@google.comtemplate <class T>
17612853Sgabeblack@google.cominline void
17712853Sgabeblack@google.comsc_global<T>::update()
17812853Sgabeblack@google.com{
17912853Sgabeblack@google.com    void *p = (::sc_gem5::Process *)sc_core::sc_get_current_process_handle();
18012853Sgabeblack@google.com    if (p != m_proc) {
18112853Sgabeblack@google.com        const T *vp = m_map[p];
18212853Sgabeblack@google.com        if (vp == 0) {
18312853Sgabeblack@google.com            vp = new T(sc_without_context());
18412853Sgabeblack@google.com            m_map.emplace(p, vp);
18512853Sgabeblack@google.com        }
18612853Sgabeblack@google.com        m_proc = p;
18712853Sgabeblack@google.com        m_value_ptr = vp;
18812853Sgabeblack@google.com    }
18912853Sgabeblack@google.com}
19012853Sgabeblack@google.com
19112853Sgabeblack@google.com
19212853Sgabeblack@google.comtemplate <class T>
19312853Sgabeblack@google.cominline sc_global<T> *
19412853Sgabeblack@google.comsc_global<T>::instance()
19512853Sgabeblack@google.com{
19612853Sgabeblack@google.com    if (m_instance == 0) {
19712853Sgabeblack@google.com        m_instance = new sc_global<T>;
19812853Sgabeblack@google.com    }
19912853Sgabeblack@google.com    return m_instance;
20012853Sgabeblack@google.com}
20112853Sgabeblack@google.com
20212853Sgabeblack@google.com
20312853Sgabeblack@google.comtemplate <class T>
20412853Sgabeblack@google.cominline const T *&
20512853Sgabeblack@google.comsc_global<T>::value_ptr()
20612853Sgabeblack@google.com{
20712853Sgabeblack@google.com    update();
20812853Sgabeblack@google.com    return m_value_ptr;
20912853Sgabeblack@google.com}
21012853Sgabeblack@google.com
21112853Sgabeblack@google.com
21212853Sgabeblack@google.com// ----------------------------------------------------------------------------
21312853Sgabeblack@google.com//  CLASS : sc_context
21412853Sgabeblack@google.com//
21512853Sgabeblack@google.com//  Template context class; co-routine safe.
21612853Sgabeblack@google.com// ----------------------------------------------------------------------------
21712853Sgabeblack@google.com
21812853Sgabeblack@google.comtemplate <class T>
21912853Sgabeblack@google.cominline sc_context<T>::sc_context(const T &value_, sc_context_begin begin_) :
22012853Sgabeblack@google.com        m_value(value_),
22112853Sgabeblack@google.com        m_def_value_ptr(sc_global<T>::instance()->value_ptr()),
22212853Sgabeblack@google.com        m_old_value_ptr(0)
22312853Sgabeblack@google.com{
22412853Sgabeblack@google.com    if (begin_ == SC_NOW) {
22512853Sgabeblack@google.com        m_old_value_ptr = m_def_value_ptr;
22612853Sgabeblack@google.com        m_def_value_ptr = &m_value;
22712853Sgabeblack@google.com    }
22812853Sgabeblack@google.com}
22912853Sgabeblack@google.com
23012853Sgabeblack@google.comtemplate <class T>
23112853Sgabeblack@google.cominline sc_context<T>::~sc_context()
23212853Sgabeblack@google.com{
23312853Sgabeblack@google.com    if (m_old_value_ptr != 0) {
23412853Sgabeblack@google.com        m_def_value_ptr = m_old_value_ptr;
23512853Sgabeblack@google.com        m_old_value_ptr = 0;
23612853Sgabeblack@google.com    }
23712853Sgabeblack@google.com}
23812853Sgabeblack@google.com
23912853Sgabeblack@google.com
24012853Sgabeblack@google.comtemplate <class T>
24112853Sgabeblack@google.cominline void
24212853Sgabeblack@google.comsc_context<T>::begin()
24312853Sgabeblack@google.com{
24412853Sgabeblack@google.com    if (m_old_value_ptr == 0) {
24512853Sgabeblack@google.com        m_old_value_ptr = m_def_value_ptr;
24612853Sgabeblack@google.com        m_def_value_ptr = &m_value;
24712853Sgabeblack@google.com    } else {
24812853Sgabeblack@google.com        SC_REPORT_ERROR("context begin failed", 0);
24912853Sgabeblack@google.com    }
25012853Sgabeblack@google.com}
25112853Sgabeblack@google.com
25212853Sgabeblack@google.comtemplate <class T>
25312853Sgabeblack@google.cominline void
25412853Sgabeblack@google.comsc_context<T>::end()
25512853Sgabeblack@google.com{
25612853Sgabeblack@google.com    if (m_old_value_ptr != 0) {
25712853Sgabeblack@google.com        m_def_value_ptr = m_old_value_ptr;
25812853Sgabeblack@google.com        m_old_value_ptr = 0;
25912853Sgabeblack@google.com    } else {
26012853Sgabeblack@google.com        SC_REPORT_ERROR("context end failed", 0);
26112853Sgabeblack@google.com    }
26212853Sgabeblack@google.com}
26312853Sgabeblack@google.com
26412853Sgabeblack@google.com
26512853Sgabeblack@google.comtemplate <class T>
26612853Sgabeblack@google.cominline const T &
26712853Sgabeblack@google.comsc_context<T>::default_value()
26812853Sgabeblack@google.com{
26912853Sgabeblack@google.com    return *sc_global<T>::instance()->value_ptr();
27012853Sgabeblack@google.com}
27112853Sgabeblack@google.com
27212853Sgabeblack@google.comtemplate <class T>
27312853Sgabeblack@google.cominline const T &
27412853Sgabeblack@google.comsc_context<T>::value() const
27512853Sgabeblack@google.com{
27612853Sgabeblack@google.com    return m_value;
27712853Sgabeblack@google.com}
27812853Sgabeblack@google.com
27912853Sgabeblack@google.com} // namespace sc_dt
28012853Sgabeblack@google.com
28112853Sgabeblack@google.com#endif // __SYSTEMC_EXT_DT_FX_SC_CONTEXT_HH__
282