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"
6513325Sgabeblack@google.com#include "messages.hh"
6612853Sgabeblack@google.com
6712853Sgabeblack@google.comnamespace sc_dt
6812853Sgabeblack@google.com{
6912853Sgabeblack@google.com
7012853Sgabeblack@google.com// classes defined in this module
7112853Sgabeblack@google.comclass sc_without_context;
7212853Sgabeblack@google.comtemplate <class T>
7312853Sgabeblack@google.comclass sc_global;
7412853Sgabeblack@google.comtemplate <class T>
7512853Sgabeblack@google.comclass sc_context;
7612853Sgabeblack@google.com
7712853Sgabeblack@google.com
7812853Sgabeblack@google.com// ----------------------------------------------------------------------------
7912853Sgabeblack@google.com//  CLASS : sc_without_context
8012853Sgabeblack@google.com//
8112853Sgabeblack@google.com//  Empty class that is used for its type only.
8212853Sgabeblack@google.com// ----------------------------------------------------------------------------
8312853Sgabeblack@google.com
8412853Sgabeblack@google.comclass sc_without_context {};
8512853Sgabeblack@google.com
8612853Sgabeblack@google.com
8712853Sgabeblack@google.com// ----------------------------------------------------------------------------
8812853Sgabeblack@google.com//  TEMPLATE CLASS : sc_global
8912853Sgabeblack@google.com//
9012853Sgabeblack@google.com//  Template global variable class; singleton; co-routine safe.
9112853Sgabeblack@google.com// ----------------------------------------------------------------------------
9212853Sgabeblack@google.com
9312853Sgabeblack@google.comtemplate <class T>
9412853Sgabeblack@google.comclass sc_global
9512853Sgabeblack@google.com{
9612853Sgabeblack@google.com    sc_global();
9712853Sgabeblack@google.com    void update();
9812853Sgabeblack@google.com
9912853Sgabeblack@google.com  public:
10012853Sgabeblack@google.com    static sc_global<T>* instance();
10112853Sgabeblack@google.com    const T*& value_ptr();
10212853Sgabeblack@google.com
10312853Sgabeblack@google.com  private:
10412853Sgabeblack@google.com    static sc_global<T> *m_instance;
10512853Sgabeblack@google.com
10612853Sgabeblack@google.com    std::map<void *, const T *> m_map;
10712853Sgabeblack@google.com    void *m_proc; // context (current process or NULL)
10812853Sgabeblack@google.com    const T *m_value_ptr;
10912853Sgabeblack@google.com};
11012853Sgabeblack@google.com
11112853Sgabeblack@google.com
11212853Sgabeblack@google.com// ----------------------------------------------------------------------------
11312853Sgabeblack@google.com//  ENUM : sc_context_begin
11412853Sgabeblack@google.com//
11512853Sgabeblack@google.com//  Enumeration of context begin options.
11612853Sgabeblack@google.com// ----------------------------------------------------------------------------
11712853Sgabeblack@google.com
11812853Sgabeblack@google.comenum sc_context_begin
11912853Sgabeblack@google.com{
12012853Sgabeblack@google.com    SC_NOW,
12112853Sgabeblack@google.com    SC_LATER
12212853Sgabeblack@google.com};
12312853Sgabeblack@google.com
12412853Sgabeblack@google.com
12512853Sgabeblack@google.com// ----------------------------------------------------------------------------
12612853Sgabeblack@google.com//  CLASS : sc_context
12712853Sgabeblack@google.com//
12812853Sgabeblack@google.com//  Template context class; co-routine safe.
12912853Sgabeblack@google.com// ----------------------------------------------------------------------------
13012853Sgabeblack@google.com
13112853Sgabeblack@google.comtemplate <class T>
13212853Sgabeblack@google.comclass sc_context
13312853Sgabeblack@google.com{
13412853Sgabeblack@google.com    // disabled
13512853Sgabeblack@google.com    sc_context(const sc_context<T> &);
13612853Sgabeblack@google.com    void *operator new(std::size_t);
13712853Sgabeblack@google.com
13812853Sgabeblack@google.com  public:
13912853Sgabeblack@google.com    explicit sc_context(const T &, sc_context_begin=SC_NOW);
14012853Sgabeblack@google.com    ~sc_context();
14112853Sgabeblack@google.com
14212853Sgabeblack@google.com    void begin();
14312853Sgabeblack@google.com    void end();
14412853Sgabeblack@google.com
14512853Sgabeblack@google.com    static const T &default_value();
14612853Sgabeblack@google.com    const T &value() const;
14712853Sgabeblack@google.com
14812853Sgabeblack@google.com  private:
14912853Sgabeblack@google.com    sc_context &operator = (const sc_context &) /* = delete */;
15012853Sgabeblack@google.com
15112853Sgabeblack@google.com    const T m_value;
15212853Sgabeblack@google.com    const T *&m_def_value_ptr;
15312853Sgabeblack@google.com    const T *m_old_value_ptr;
15412853Sgabeblack@google.com};
15512853Sgabeblack@google.com
15612853Sgabeblack@google.com
15712853Sgabeblack@google.com// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
15812853Sgabeblack@google.com
15912853Sgabeblack@google.com// ----------------------------------------------------------------------------
16012853Sgabeblack@google.com//  TEMPLATE CLASS : sc_global
16112853Sgabeblack@google.com//
16212853Sgabeblack@google.com//  Template global variable class; singleton; co-routine safe.
16312853Sgabeblack@google.com// ----------------------------------------------------------------------------
16412853Sgabeblack@google.com
16512853Sgabeblack@google.comtemplate <class T>
16612853Sgabeblack@google.comsc_global<T> *sc_global<T>::m_instance = 0;
16712853Sgabeblack@google.com
16812853Sgabeblack@google.comtemplate <class T>
16912853Sgabeblack@google.cominline sc_global<T>::sc_global() : m_map(),
17012853Sgabeblack@google.com    // use &m_instance as unique "non-process" key (NULL denotes 'sc_main'
17112853Sgabeblack@google.com    // context)
17212853Sgabeblack@google.com    m_proc(&m_instance), m_value_ptr(0)
17312853Sgabeblack@google.com{}
17412853Sgabeblack@google.com
17512853Sgabeblack@google.com
17612853Sgabeblack@google.comtemplate <class T>
17712853Sgabeblack@google.cominline void
17812853Sgabeblack@google.comsc_global<T>::update()
17912853Sgabeblack@google.com{
18012853Sgabeblack@google.com    void *p = (::sc_gem5::Process *)sc_core::sc_get_current_process_handle();
18112853Sgabeblack@google.com    if (p != m_proc) {
18212853Sgabeblack@google.com        const T *vp = m_map[p];
18312853Sgabeblack@google.com        if (vp == 0) {
18412853Sgabeblack@google.com            vp = new T(sc_without_context());
18512853Sgabeblack@google.com            m_map.emplace(p, vp);
18612853Sgabeblack@google.com        }
18712853Sgabeblack@google.com        m_proc = p;
18812853Sgabeblack@google.com        m_value_ptr = vp;
18912853Sgabeblack@google.com    }
19012853Sgabeblack@google.com}
19112853Sgabeblack@google.com
19212853Sgabeblack@google.com
19312853Sgabeblack@google.comtemplate <class T>
19412853Sgabeblack@google.cominline sc_global<T> *
19512853Sgabeblack@google.comsc_global<T>::instance()
19612853Sgabeblack@google.com{
19712853Sgabeblack@google.com    if (m_instance == 0) {
19812853Sgabeblack@google.com        m_instance = new sc_global<T>;
19912853Sgabeblack@google.com    }
20012853Sgabeblack@google.com    return m_instance;
20112853Sgabeblack@google.com}
20212853Sgabeblack@google.com
20312853Sgabeblack@google.com
20412853Sgabeblack@google.comtemplate <class T>
20512853Sgabeblack@google.cominline const T *&
20612853Sgabeblack@google.comsc_global<T>::value_ptr()
20712853Sgabeblack@google.com{
20812853Sgabeblack@google.com    update();
20912853Sgabeblack@google.com    return m_value_ptr;
21012853Sgabeblack@google.com}
21112853Sgabeblack@google.com
21212853Sgabeblack@google.com
21312853Sgabeblack@google.com// ----------------------------------------------------------------------------
21412853Sgabeblack@google.com//  CLASS : sc_context
21512853Sgabeblack@google.com//
21612853Sgabeblack@google.com//  Template context class; co-routine safe.
21712853Sgabeblack@google.com// ----------------------------------------------------------------------------
21812853Sgabeblack@google.com
21912853Sgabeblack@google.comtemplate <class T>
22012853Sgabeblack@google.cominline sc_context<T>::sc_context(const T &value_, sc_context_begin begin_) :
22112853Sgabeblack@google.com        m_value(value_),
22212853Sgabeblack@google.com        m_def_value_ptr(sc_global<T>::instance()->value_ptr()),
22312853Sgabeblack@google.com        m_old_value_ptr(0)
22412853Sgabeblack@google.com{
22512853Sgabeblack@google.com    if (begin_ == SC_NOW) {
22612853Sgabeblack@google.com        m_old_value_ptr = m_def_value_ptr;
22712853Sgabeblack@google.com        m_def_value_ptr = &m_value;
22812853Sgabeblack@google.com    }
22912853Sgabeblack@google.com}
23012853Sgabeblack@google.com
23112853Sgabeblack@google.comtemplate <class T>
23212853Sgabeblack@google.cominline sc_context<T>::~sc_context()
23312853Sgabeblack@google.com{
23412853Sgabeblack@google.com    if (m_old_value_ptr != 0) {
23512853Sgabeblack@google.com        m_def_value_ptr = m_old_value_ptr;
23612853Sgabeblack@google.com        m_old_value_ptr = 0;
23712853Sgabeblack@google.com    }
23812853Sgabeblack@google.com}
23912853Sgabeblack@google.com
24012853Sgabeblack@google.com
24112853Sgabeblack@google.comtemplate <class T>
24212853Sgabeblack@google.cominline void
24312853Sgabeblack@google.comsc_context<T>::begin()
24412853Sgabeblack@google.com{
24512853Sgabeblack@google.com    if (m_old_value_ptr == 0) {
24612853Sgabeblack@google.com        m_old_value_ptr = m_def_value_ptr;
24712853Sgabeblack@google.com        m_def_value_ptr = &m_value;
24812853Sgabeblack@google.com    } else {
24913325Sgabeblack@google.com        SC_REPORT_ERROR(sc_core::SC_ID_CONTEXT_BEGIN_FAILED_, 0);
25012853Sgabeblack@google.com    }
25112853Sgabeblack@google.com}
25212853Sgabeblack@google.com
25312853Sgabeblack@google.comtemplate <class T>
25412853Sgabeblack@google.cominline void
25512853Sgabeblack@google.comsc_context<T>::end()
25612853Sgabeblack@google.com{
25712853Sgabeblack@google.com    if (m_old_value_ptr != 0) {
25812853Sgabeblack@google.com        m_def_value_ptr = m_old_value_ptr;
25912853Sgabeblack@google.com        m_old_value_ptr = 0;
26012853Sgabeblack@google.com    } else {
26113325Sgabeblack@google.com        SC_REPORT_ERROR(sc_core::SC_ID_CONTEXT_END_FAILED_, 0);
26212853Sgabeblack@google.com    }
26312853Sgabeblack@google.com}
26412853Sgabeblack@google.com
26512853Sgabeblack@google.com
26612853Sgabeblack@google.comtemplate <class T>
26712853Sgabeblack@google.cominline const T &
26812853Sgabeblack@google.comsc_context<T>::default_value()
26912853Sgabeblack@google.com{
27012853Sgabeblack@google.com    return *sc_global<T>::instance()->value_ptr();
27112853Sgabeblack@google.com}
27212853Sgabeblack@google.com
27312853Sgabeblack@google.comtemplate <class T>
27412853Sgabeblack@google.cominline const T &
27512853Sgabeblack@google.comsc_context<T>::value() const
27612853Sgabeblack@google.com{
27712853Sgabeblack@google.com    return m_value;
27812853Sgabeblack@google.com}
27912853Sgabeblack@google.com
28012853Sgabeblack@google.com} // namespace sc_dt
28112853Sgabeblack@google.com
28212853Sgabeblack@google.com#endif // __SYSTEMC_EXT_DT_FX_SC_CONTEXT_HH__
283