instance_specific_extensions_int.h revision 13586
113511Sgabeblack@google.com/***************************************************************************** 213511Sgabeblack@google.com 313511Sgabeblack@google.com Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 413511Sgabeblack@google.com more contributor license agreements. See the NOTICE file distributed 513511Sgabeblack@google.com with this work for additional information regarding copyright ownership. 613511Sgabeblack@google.com Accellera licenses this file to you under the Apache License, Version 2.0 713511Sgabeblack@google.com (the "License"); you may not use this file except in compliance with the 813511Sgabeblack@google.com License. You may obtain a copy of the License at 913511Sgabeblack@google.com 1013511Sgabeblack@google.com http://www.apache.org/licenses/LICENSE-2.0 1113511Sgabeblack@google.com 1213511Sgabeblack@google.com Unless required by applicable law or agreed to in writing, software 1313511Sgabeblack@google.com distributed under the License is distributed on an "AS IS" BASIS, 1413511Sgabeblack@google.com WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1513511Sgabeblack@google.com implied. See the License for the specific language governing 1613511Sgabeblack@google.com permissions and limitations under the License. 1713511Sgabeblack@google.com 1813511Sgabeblack@google.com *****************************************************************************/ 1913513Sgabeblack@google.com#ifndef __SYSTEMC_EXT_TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H__ 2013513Sgabeblack@google.com#define __SYSTEMC_EXT_TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H__ 2113511Sgabeblack@google.com 2213586Sgabeblack@google.com#include <vector> 2313586Sgabeblack@google.com 2413586Sgabeblack@google.com#include "../tlm_core/2/generic_payload/array.hh" 2513511Sgabeblack@google.com 2613513Sgabeblack@google.comnamespace tlm_utils 2713513Sgabeblack@google.com{ 2813513Sgabeblack@google.com 2913513Sgabeblack@google.comclass ispex_base; 3013513Sgabeblack@google.comclass instance_specific_extension_accessor; 3113513Sgabeblack@google.comclass instance_specific_extension_container; 3213511Sgabeblack@google.comclass instance_specific_extension_carrier; 3313511Sgabeblack@google.comclass instance_specific_extension_container_pool; 3413511Sgabeblack@google.com 3513513Sgabeblack@google.com} // namespace tlm_utils 3613513Sgabeblack@google.com 3713513Sgabeblack@google.comnamespace tlm 3813513Sgabeblack@google.com{ 3913513Sgabeblack@google.com 4013513Sgabeblack@google.comextern template class tlm_array<tlm_utils::ispex_base *>; 4113513Sgabeblack@google.com 4213511Sgabeblack@google.com} // namespace tlm 4313511Sgabeblack@google.com 4413513Sgabeblack@google.comnamespace tlm_utils 4513513Sgabeblack@google.com{ 4613511Sgabeblack@google.com 4713513Sgabeblack@google.com// The private extension base. Similar to normal extension base, but without 4813513Sgabeblack@google.com// clone and free. 4913513Sgabeblack@google.comclass ispex_base 5013511Sgabeblack@google.com{ 5113511Sgabeblack@google.com friend class tlm::tlm_array<ispex_base*>; 5213513Sgabeblack@google.com void free() {} // Needed for explicit tlm_array instantiation. 5313513Sgabeblack@google.com 5413513Sgabeblack@google.com public: 5513511Sgabeblack@google.com virtual ~ispex_base() {} 5613513Sgabeblack@google.com 5713513Sgabeblack@google.com protected: 5813513Sgabeblack@google.com static unsigned int register_private_extension(const std::type_info &); 5913511Sgabeblack@google.com}; 6013511Sgabeblack@google.com 6113513Sgabeblack@google.com// This thing is basically a snippet of the generic_payload. 6213513Sgabeblack@google.com// It contains all the extension specific code (the extension API so to speak) 6313511Sgabeblack@google.com// the differences are: 6413513Sgabeblack@google.com// - it calls back to its owner whenever a real (==non-NULL) extension gets 6513513Sgabeblack@google.com// set for the first time. 6613513Sgabeblack@google.com// - it calls back to its owner whenever a living (==non-NULL) extension gets 6713513Sgabeblack@google.com// cleared. 6813513Sgabeblack@google.comclass instance_specific_extensions_per_accessor 6913511Sgabeblack@google.com{ 7013513Sgabeblack@google.com public: 7113513Sgabeblack@google.com typedef instance_specific_extension_container container_type; 7213511Sgabeblack@google.com 7313513Sgabeblack@google.com explicit 7413513Sgabeblack@google.com instance_specific_extensions_per_accessor(container_type *container) : 7513513Sgabeblack@google.com m_container(container) 7613513Sgabeblack@google.com {} 7713511Sgabeblack@google.com 7813513Sgabeblack@google.com template <typename T> 7913513Sgabeblack@google.com T * 8013513Sgabeblack@google.com set_extension(T *ext) 8113513Sgabeblack@google.com { 8213513Sgabeblack@google.com return static_cast<T *>(set_extension(T::priv_id, ext)); 8313513Sgabeblack@google.com } 8413511Sgabeblack@google.com 8513513Sgabeblack@google.com // Non-templatized version with manual index: 8613513Sgabeblack@google.com ispex_base *set_extension(unsigned int index, ispex_base *ext); 8713511Sgabeblack@google.com 8813513Sgabeblack@google.com // Check for an extension, ext will be nullptr if not present. 8913513Sgabeblack@google.com template <typename T> 9013513Sgabeblack@google.com void get_extension(T *& ext) const 9113513Sgabeblack@google.com { 9213513Sgabeblack@google.com ext = static_cast<T *>(get_extension(T::priv_id)); 9313513Sgabeblack@google.com } 9413513Sgabeblack@google.com // Non-templatized version: 9513513Sgabeblack@google.com ispex_base *get_extension(unsigned int index) const; 9613511Sgabeblack@google.com 9713513Sgabeblack@google.com // Clear extension, the argument is needed to find the right index: 9813513Sgabeblack@google.com template <typename T> 9913513Sgabeblack@google.com void clear_extension(const T *) 10013513Sgabeblack@google.com { 10113513Sgabeblack@google.com clear_extension(T::priv_id); 10213513Sgabeblack@google.com } 10313511Sgabeblack@google.com 10413513Sgabeblack@google.com // Non-templatized version with manual index 10513513Sgabeblack@google.com void clear_extension(unsigned int index); 10613511Sgabeblack@google.com 10713513Sgabeblack@google.com // Make sure the extension array is large enough. Can be called once by 10813513Sgabeblack@google.com // an initiator module (before issuing the first transaction) to make 10913513Sgabeblack@google.com // sure that the extension array is of correct size. This is only needed 11013513Sgabeblack@google.com // if the initiator cannot guarantee that the generic payload object is 11113513Sgabeblack@google.com // allocated after C++ static construction time. 11213513Sgabeblack@google.com void resize_extensions(); 11313511Sgabeblack@google.com 11413513Sgabeblack@google.com private: 11513513Sgabeblack@google.com tlm::tlm_array<ispex_base *> m_extensions; 11613513Sgabeblack@google.com container_type* m_container; 11713513Sgabeblack@google.com}; 11813511Sgabeblack@google.com 11913513Sgabeblack@google.com// This thing contains the vector of extensions per accessor 12013513Sgabeblack@google.com// which can be really large so this one should be pool allocated. 12113513Sgabeblack@google.com// Therefore it keeps a use_count of itself to automatically free itself. 12213513Sgabeblack@google.com// - to this end it provides callbacks to the extensions per accessor 12313513Sgabeblack@google.com// to increment and decrement the use_count. 12413513Sgabeblack@google.comclass instance_specific_extension_container 12513513Sgabeblack@google.com{ 12613513Sgabeblack@google.com friend class instance_specific_extension_accessor; 12713513Sgabeblack@google.com friend class instance_specific_extension_carrier; 12813513Sgabeblack@google.com friend class instance_specific_extension_container_pool; 12913513Sgabeblack@google.com friend class instance_specific_extensions_per_accessor; 13013511Sgabeblack@google.com 13113513Sgabeblack@google.com typedef void release_fn(instance_specific_extension_carrier *, void *); 13213511Sgabeblack@google.com 13313513Sgabeblack@google.com instance_specific_extension_container(); 13413513Sgabeblack@google.com ~instance_specific_extension_container(); 13513511Sgabeblack@google.com 13613513Sgabeblack@google.com void resize(); 13713511Sgabeblack@google.com 13813513Sgabeblack@google.com void inc_use_count(); 13913513Sgabeblack@google.com void dec_use_count(); 14013511Sgabeblack@google.com 14113513Sgabeblack@google.com static instance_specific_extension_container *create(); 14213513Sgabeblack@google.com void attach_carrier( 14313513Sgabeblack@google.com instance_specific_extension_carrier *, void *txn, release_fn *); 14413511Sgabeblack@google.com 14513513Sgabeblack@google.com instance_specific_extensions_per_accessor * 14613513Sgabeblack@google.com get_accessor(unsigned int index); 14713511Sgabeblack@google.com 14813513Sgabeblack@google.com std::vector<instance_specific_extensions_per_accessor *> 14913513Sgabeblack@google.com m_ispex_per_accessor; 15013513Sgabeblack@google.com unsigned int use_count; 15113513Sgabeblack@google.com void *m_txn; 15213513Sgabeblack@google.com release_fn *m_release_fn; 15313513Sgabeblack@google.com instance_specific_extension_carrier *m_carrier; 15413513Sgabeblack@google.com instance_specific_extension_container *next; // For pooling. 15513513Sgabeblack@google.com}; 15613511Sgabeblack@google.com 15713511Sgabeblack@google.com// ---------------------------------------------------------------------------- 15813511Sgabeblack@google.com 15913513Sgabeblack@google.com// This class 'hides' all the instance specific extension stuff from the user. 16013513Sgabeblack@google.com// They instantiates one of those (e.g. instance_specific_extension_accessor 16113513Sgabeblack@google.com// extAcc;) and can then access the private extensions. 16213511Sgabeblack@google.com// extAcc(txn).extensionAPIFnCall() 16313513Sgabeblack@google.com// where extensionAPIFnCall is set_extension, get_extension, 16413513Sgabeblack@google.com// clear_extension,... 16513513Sgabeblack@google.comclass instance_specific_extension_accessor 16613511Sgabeblack@google.com{ 16713513Sgabeblack@google.com public: 16813513Sgabeblack@google.com instance_specific_extension_accessor(); 16913511Sgabeblack@google.com 17013513Sgabeblack@google.com // Implementation in instance_specific_extensions.h 17113513Sgabeblack@google.com template <typename T> 17213513Sgabeblack@google.com inline instance_specific_extensions_per_accessor &operator () (T &txn); 17313511Sgabeblack@google.com 17413513Sgabeblack@google.com protected: 17513513Sgabeblack@google.com template<typename T> 17613513Sgabeblack@google.com static void release_carrier( 17713513Sgabeblack@google.com instance_specific_extension_carrier *, void * txn); 17813511Sgabeblack@google.com 17913513Sgabeblack@google.com unsigned int m_index; 18013513Sgabeblack@google.com}; 18113511Sgabeblack@google.com 18213511Sgabeblack@google.com} // namespace tlm_utils 18313513Sgabeblack@google.com 18413513Sgabeblack@google.com#endif /* __SYSTEMC_EXT_TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H__ */ 185