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