instance_specific_extensions.cc revision 13523
112027Sjungma@eit.uni-kl.de/*****************************************************************************
212027Sjungma@eit.uni-kl.de
312027Sjungma@eit.uni-kl.de  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412027Sjungma@eit.uni-kl.de  more contributor license agreements.  See the NOTICE file distributed
512027Sjungma@eit.uni-kl.de  with this work for additional information regarding copyright ownership.
612027Sjungma@eit.uni-kl.de  Accellera licenses this file to you under the Apache License, Version 2.0
712027Sjungma@eit.uni-kl.de  (the "License"); you may not use this file except in compliance with the
812027Sjungma@eit.uni-kl.de  License.  You may obtain a copy of the License at
912027Sjungma@eit.uni-kl.de
1012027Sjungma@eit.uni-kl.de    http://www.apache.org/licenses/LICENSE-2.0
1112027Sjungma@eit.uni-kl.de
1212027Sjungma@eit.uni-kl.de  Unless required by applicable law or agreed to in writing, software
1312027Sjungma@eit.uni-kl.de  distributed under the License is distributed on an "AS IS" BASIS,
1412027Sjungma@eit.uni-kl.de  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512027Sjungma@eit.uni-kl.de  implied.  See the License for the specific language governing
1612027Sjungma@eit.uni-kl.de  permissions and limitations under the License.
1712027Sjungma@eit.uni-kl.de
1812027Sjungma@eit.uni-kl.de *****************************************************************************/
1912027Sjungma@eit.uni-kl.de
2012027Sjungma@eit.uni-kl.de#include <tlm_utils/instance_specific_extensions_int.h>
2112027Sjungma@eit.uni-kl.de
2212027Sjungma@eit.uni-kl.de#include <iostream>
2312027Sjungma@eit.uni-kl.de#include <map>
2412027Sjungma@eit.uni-kl.de#include <systemc>
2512027Sjungma@eit.uni-kl.de#include <tlm>
2612027Sjungma@eit.uni-kl.de#include <typeindex>
2712027Sjungma@eit.uni-kl.de
2812027Sjungma@eit.uni-kl.denamespace tlm
2912027Sjungma@eit.uni-kl.de{
3012027Sjungma@eit.uni-kl.de
3112027Sjungma@eit.uni-kl.detemplate class tlm_array<tlm_utils::ispex_base *>;
3212027Sjungma@eit.uni-kl.de
3312027Sjungma@eit.uni-kl.de} // namespace tlm
3412027Sjungma@eit.uni-kl.de
3512027Sjungma@eit.uni-kl.denamespace tlm_utils
3612027Sjungma@eit.uni-kl.de{
3712027Sjungma@eit.uni-kl.de
3812027Sjungma@eit.uni-kl.denamespace
3912027Sjungma@eit.uni-kl.de{
4012027Sjungma@eit.uni-kl.de
4112027Sjungma@eit.uni-kl.declass ispex_registry // Copied from tlm_gp.cpp.
4212027Sjungma@eit.uni-kl.de{
4312027Sjungma@eit.uni-kl.de    typedef unsigned int key_type;
4412027Sjungma@eit.uni-kl.de    typedef std::map<std::type_index, key_type> type_map;
4512027Sjungma@eit.uni-kl.de
4612027Sjungma@eit.uni-kl.de  public:
4712027Sjungma@eit.uni-kl.de    static ispex_registry &
4812027Sjungma@eit.uni-kl.de    instance()
4912027Sjungma@eit.uni-kl.de    {
5012027Sjungma@eit.uni-kl.de        if (!instance_) {
5112027Sjungma@eit.uni-kl.de            // Don't cleanup registry.
5212027Sjungma@eit.uni-kl.de            instance_ = new ispex_registry();
5312027Sjungma@eit.uni-kl.de        }
5412027Sjungma@eit.uni-kl.de        return *instance_;
5512027Sjungma@eit.uni-kl.de    }
5612027Sjungma@eit.uni-kl.de
5712027Sjungma@eit.uni-kl.de    unsigned int
5812027Sjungma@eit.uni-kl.de    register_extension(std::type_index type)
5912027Sjungma@eit.uni-kl.de    {
6012027Sjungma@eit.uni-kl.de        type_map::const_iterator it = ids_.find(type);
6112027Sjungma@eit.uni-kl.de
6212027Sjungma@eit.uni-kl.de        if (it == ids_.end()) {
6312027Sjungma@eit.uni-kl.de            // New extension - generate/store ID.
6412027Sjungma@eit.uni-kl.de            type_map::value_type v(type, static_cast<key_type>(ids_.size()));
6512027Sjungma@eit.uni-kl.de            ids_.insert(v);
6612027Sjungma@eit.uni-kl.de            return v.second;
6712027Sjungma@eit.uni-kl.de        }
6812027Sjungma@eit.uni-kl.de        return it->second;
6912027Sjungma@eit.uni-kl.de    }
7012027Sjungma@eit.uni-kl.de
7112027Sjungma@eit.uni-kl.de    static unsigned int
7212027Sjungma@eit.uni-kl.de    max_num_extensions()
7312027Sjungma@eit.uni-kl.de    {
7412027Sjungma@eit.uni-kl.de        return (instance_) ? instance().ids_.size() : 0;
7512027Sjungma@eit.uni-kl.de    }
7612027Sjungma@eit.uni-kl.de
7712027Sjungma@eit.uni-kl.de  private:
7812027Sjungma@eit.uni-kl.de    static ispex_registry *instance_;
7912027Sjungma@eit.uni-kl.de    type_map ids_;
8012027Sjungma@eit.uni-kl.de    ispex_registry() {}
8112027Sjungma@eit.uni-kl.de};
8212027Sjungma@eit.uni-kl.de
8312027Sjungma@eit.uni-kl.deispex_registry *ispex_registry::instance_ = nullptr;
8412027Sjungma@eit.uni-kl.de
8512027Sjungma@eit.uni-kl.de} //  anonymous namespace
8612027Sjungma@eit.uni-kl.de
8712027Sjungma@eit.uni-kl.deunsigned int
8812027Sjungma@eit.uni-kl.deispex_base::register_private_extension(const std::type_info &type)
8912027Sjungma@eit.uni-kl.de{
9012027Sjungma@eit.uni-kl.de    return ispex_registry::instance().register_extension(type);
9112027Sjungma@eit.uni-kl.de}
9212027Sjungma@eit.uni-kl.de
9312027Sjungma@eit.uni-kl.de// Helper to do the numbering of private extension accessors.
9412027Sjungma@eit.uni-kl.destatic unsigned int
9512027Sjungma@eit.uni-kl.demax_num_ispex_accessors(bool increment=false)
9612027Sjungma@eit.uni-kl.de{
9712027Sjungma@eit.uni-kl.de    static unsigned int max_num = 0;
9812027Sjungma@eit.uni-kl.de    if (increment)
9912027Sjungma@eit.uni-kl.de        ++max_num;
10012027Sjungma@eit.uni-kl.de    return max_num;
10112027Sjungma@eit.uni-kl.de}
10212027Sjungma@eit.uni-kl.de
10312027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
10412027Sjungma@eit.uni-kl.de
10512027Sjungma@eit.uni-kl.de// The pool for the container, plain as can be.
10612027Sjungma@eit.uni-kl.declass instance_specific_extension_container_pool
10712027Sjungma@eit.uni-kl.de{
10812027Sjungma@eit.uni-kl.de    instance_specific_extension_container_pool() : unused(nullptr) {}
10912027Sjungma@eit.uni-kl.de    ~instance_specific_extension_container_pool();
11012027Sjungma@eit.uni-kl.de
11112027Sjungma@eit.uni-kl.de  public:
11212027Sjungma@eit.uni-kl.de    static instance_specific_extension_container_pool &
11312027Sjungma@eit.uni-kl.de    instance()
11412027Sjungma@eit.uni-kl.de    {
11512027Sjungma@eit.uni-kl.de        static instance_specific_extension_container_pool inst;
11612027Sjungma@eit.uni-kl.de        return inst;
11712027Sjungma@eit.uni-kl.de    }
11812027Sjungma@eit.uni-kl.de
11912027Sjungma@eit.uni-kl.de    instance_specific_extension_container *create();
12012027Sjungma@eit.uni-kl.de    void free(instance_specific_extension_container *);
12112027Sjungma@eit.uni-kl.de
12212027Sjungma@eit.uni-kl.de  private:
12312027Sjungma@eit.uni-kl.de    instance_specific_extension_container *unused;
12412027Sjungma@eit.uni-kl.de};
12512027Sjungma@eit.uni-kl.de
12612027Sjungma@eit.uni-kl.deinstance_specific_extension_container *
12712027Sjungma@eit.uni-kl.deinstance_specific_extension_container_pool::create()
12812027Sjungma@eit.uni-kl.de{
12912027Sjungma@eit.uni-kl.de    if (!unused) {
13012027Sjungma@eit.uni-kl.de        unused = new instance_specific_extension_container();
13112027Sjungma@eit.uni-kl.de    }
13212027Sjungma@eit.uni-kl.de    instance_specific_extension_container *tmp = unused;
13312027Sjungma@eit.uni-kl.de    unused = unused->next;
13412027Sjungma@eit.uni-kl.de    return tmp;
13512027Sjungma@eit.uni-kl.de}
13612027Sjungma@eit.uni-kl.de
13712027Sjungma@eit.uni-kl.devoid
13812027Sjungma@eit.uni-kl.deinstance_specific_extension_container_pool::free(
13912027Sjungma@eit.uni-kl.de        instance_specific_extension_container *cont)
14012027Sjungma@eit.uni-kl.de{
14112027Sjungma@eit.uni-kl.de    cont->next = unused;
14212027Sjungma@eit.uni-kl.de    unused = cont;
14312027Sjungma@eit.uni-kl.de}
14412027Sjungma@eit.uni-kl.de
14512027Sjungma@eit.uni-kl.deinstance_specific_extension_container_pool::
14612027Sjungma@eit.uni-kl.de    ~instance_specific_extension_container_pool()
14712027Sjungma@eit.uni-kl.de{
14812027Sjungma@eit.uni-kl.de    while (unused) {
14912027Sjungma@eit.uni-kl.de        instance_specific_extension_container *tmp = unused;
15012027Sjungma@eit.uni-kl.de        unused = unused->next;
15112027Sjungma@eit.uni-kl.de        delete tmp;
15212027Sjungma@eit.uni-kl.de    }
15312027Sjungma@eit.uni-kl.de}
15412027Sjungma@eit.uni-kl.de
15512027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
15612027Sjungma@eit.uni-kl.de
15712027Sjungma@eit.uni-kl.deinstance_specific_extension_container *
15812027Sjungma@eit.uni-kl.deinstance_specific_extension_container::create()
15912027Sjungma@eit.uni-kl.de{
16012027Sjungma@eit.uni-kl.de    return instance_specific_extension_container_pool::instance().create();
16112027Sjungma@eit.uni-kl.de}
16212027Sjungma@eit.uni-kl.de
16312027Sjungma@eit.uni-kl.deinstance_specific_extension_container::
16412027Sjungma@eit.uni-kl.de    instance_specific_extension_container() :
16512027Sjungma@eit.uni-kl.de    use_count(0), m_txn(NULL), m_release_fn(NULL), m_carrier(NULL), next(NULL)
16612027Sjungma@eit.uni-kl.de{
16712027Sjungma@eit.uni-kl.de    resize();
16812027Sjungma@eit.uni-kl.de}
16912027Sjungma@eit.uni-kl.de
17012027Sjungma@eit.uni-kl.devoid
17112027Sjungma@eit.uni-kl.deinstance_specific_extension_container::
17212027Sjungma@eit.uni-kl.de    attach_carrier(instance_specific_extension_carrier *carrier,
17312027Sjungma@eit.uni-kl.de            void *txn, release_fn *rel_fn)
17412027Sjungma@eit.uni-kl.de{
17512027Sjungma@eit.uni-kl.de    m_txn = txn;
17612027Sjungma@eit.uni-kl.de    m_release_fn = rel_fn;
17712027Sjungma@eit.uni-kl.de    m_carrier = carrier;
17812027Sjungma@eit.uni-kl.de}
17912027Sjungma@eit.uni-kl.de
18012027Sjungma@eit.uni-kl.devoid
18112027Sjungma@eit.uni-kl.deinstance_specific_extension_container::resize()
18212027Sjungma@eit.uni-kl.de{
18312027Sjungma@eit.uni-kl.de    m_ispex_per_accessor.resize(max_num_ispex_accessors());
18412027Sjungma@eit.uni-kl.de
18512027Sjungma@eit.uni-kl.de    for (unsigned int i = 0; i < m_ispex_per_accessor.size(); ++i) {
18612027Sjungma@eit.uni-kl.de        m_ispex_per_accessor[i] =
18712027Sjungma@eit.uni-kl.de            new instance_specific_extensions_per_accessor(this);
18812027Sjungma@eit.uni-kl.de        m_ispex_per_accessor[i]->resize_extensions();
18912027Sjungma@eit.uni-kl.de    }
19012027Sjungma@eit.uni-kl.de}
19112027Sjungma@eit.uni-kl.de
19212027Sjungma@eit.uni-kl.deinstance_specific_extension_container::
19312027Sjungma@eit.uni-kl.de    ~instance_specific_extension_container()
19412027Sjungma@eit.uni-kl.de{
19512027Sjungma@eit.uni-kl.de    for (unsigned int i = 0; i < m_ispex_per_accessor.size(); ++i)
19612027Sjungma@eit.uni-kl.de        delete m_ispex_per_accessor[i];
19712027Sjungma@eit.uni-kl.de}
19812027Sjungma@eit.uni-kl.de
19912027Sjungma@eit.uni-kl.devoid
20012027Sjungma@eit.uni-kl.deinstance_specific_extension_container::inc_use_count()
20112027Sjungma@eit.uni-kl.de{
20212027Sjungma@eit.uni-kl.de    use_count++;
20312027Sjungma@eit.uni-kl.de}
20412027Sjungma@eit.uni-kl.de
20512027Sjungma@eit.uni-kl.devoid
20612027Sjungma@eit.uni-kl.deinstance_specific_extension_container::dec_use_count()
20712027Sjungma@eit.uni-kl.de{
20812027Sjungma@eit.uni-kl.de    if ((--use_count) == 0) {
20912027Sjungma@eit.uni-kl.de        // If this container isn't used any more we release the carrier
21012027Sjungma@eit.uni-kl.de        // extension.
21112027Sjungma@eit.uni-kl.de        m_release_fn(m_carrier, m_txn);
21212027Sjungma@eit.uni-kl.de        // We send it back to our pool.
21312027Sjungma@eit.uni-kl.de        instance_specific_extension_container_pool::instance().free(this);
21412027Sjungma@eit.uni-kl.de    }
21512027Sjungma@eit.uni-kl.de}
21612027Sjungma@eit.uni-kl.de
21712027Sjungma@eit.uni-kl.deinstance_specific_extensions_per_accessor *
21812027Sjungma@eit.uni-kl.deinstance_specific_extension_container::get_accessor(unsigned int idx)
21912027Sjungma@eit.uni-kl.de{
22012027Sjungma@eit.uni-kl.de    return m_ispex_per_accessor[idx];
22112027Sjungma@eit.uni-kl.de}
22212027Sjungma@eit.uni-kl.de
22312027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
22412027Sjungma@eit.uni-kl.de
22512027Sjungma@eit.uni-kl.de// non-templatized version with manual index:
22612027Sjungma@eit.uni-kl.deispex_base *
22712027Sjungma@eit.uni-kl.deinstance_specific_extensions_per_accessor::set_extension(
22812027Sjungma@eit.uni-kl.de        unsigned int index, ispex_base *ext)
22912027Sjungma@eit.uni-kl.de{
23012027Sjungma@eit.uni-kl.de    resize_extensions();
23112027Sjungma@eit.uni-kl.de    ispex_base *tmp = m_extensions[index];
23212027Sjungma@eit.uni-kl.de    m_extensions[index] = ext;
23312027Sjungma@eit.uni-kl.de    if (!tmp && ext)
23412027Sjungma@eit.uni-kl.de        m_container->inc_use_count();
23512027Sjungma@eit.uni-kl.de    return tmp;
23612027Sjungma@eit.uni-kl.de}
23712027Sjungma@eit.uni-kl.de
23812027Sjungma@eit.uni-kl.deispex_base *
23912027Sjungma@eit.uni-kl.deinstance_specific_extensions_per_accessor::get_extension(
24012027Sjungma@eit.uni-kl.de        unsigned int index) const
24112027Sjungma@eit.uni-kl.de{
24212027Sjungma@eit.uni-kl.de    return (index < m_extensions.size()) ? m_extensions[index] : nullptr;
24312027Sjungma@eit.uni-kl.de}
24412027Sjungma@eit.uni-kl.de
24512027Sjungma@eit.uni-kl.devoid
24612027Sjungma@eit.uni-kl.deinstance_specific_extensions_per_accessor::clear_extension(unsigned int index)
24712027Sjungma@eit.uni-kl.de{
24812027Sjungma@eit.uni-kl.de    if (index < m_extensions.size()) {
24912027Sjungma@eit.uni-kl.de        if (m_extensions[index])
25012027Sjungma@eit.uni-kl.de            m_container->dec_use_count();
25112027Sjungma@eit.uni-kl.de        m_extensions[index] = static_cast<ispex_base *>(nullptr);
25212027Sjungma@eit.uni-kl.de    }
253}
254
255void
256instance_specific_extensions_per_accessor::resize_extensions()
257{
258    m_extensions.expand(ispex_registry::max_num_extensions());
259}
260
261// ----------------------------------------------------------------------------
262
263instance_specific_extension_accessor::instance_specific_extension_accessor() :
264    m_index(max_num_ispex_accessors(true) - 1)
265{}
266
267} // namespace tlm_utils
268