instance_specific_extensions_int.h revision 13513
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 2213511Sgabeblack@google.com#include <tlm> 2313511Sgabeblack@google.com 2413513Sgabeblack@google.comnamespace tlm_utils 2513513Sgabeblack@google.com{ 2613513Sgabeblack@google.com 2713513Sgabeblack@google.comclass ispex_base; 2813513Sgabeblack@google.comclass instance_specific_extension_accessor; 2913513Sgabeblack@google.comclass instance_specific_extension_container; 3013511Sgabeblack@google.comclass instance_specific_extension_carrier; 3113511Sgabeblack@google.comclass instance_specific_extension_container_pool; 3213511Sgabeblack@google.com 3313513Sgabeblack@google.com} // namespace tlm_utils 3413513Sgabeblack@google.com 3513513Sgabeblack@google.comnamespace tlm 3613513Sgabeblack@google.com{ 3713513Sgabeblack@google.com 3813513Sgabeblack@google.comextern template class tlm_array<tlm_utils::ispex_base *>; 3913513Sgabeblack@google.com 4013511Sgabeblack@google.com} // namespace tlm 4113511Sgabeblack@google.com 4213513Sgabeblack@google.comnamespace tlm_utils 4313513Sgabeblack@google.com{ 4413511Sgabeblack@google.com 4513513Sgabeblack@google.com// The private extension base. Similar to normal extension base, but without 4613513Sgabeblack@google.com// clone and free. 4713513Sgabeblack@google.comclass ispex_base 4813511Sgabeblack@google.com{ 4913511Sgabeblack@google.com friend class tlm::tlm_array<ispex_base*>; 5013513Sgabeblack@google.com void free() {} // Needed for explicit tlm_array instantiation. 5113513Sgabeblack@google.com 5213513Sgabeblack@google.com public: 5313511Sgabeblack@google.com virtual ~ispex_base() {} 5413513Sgabeblack@google.com 5513513Sgabeblack@google.com protected: 5613513Sgabeblack@google.com static unsigned int register_private_extension(const std::type_info &); 5713511Sgabeblack@google.com}; 5813511Sgabeblack@google.com 5913513Sgabeblack@google.com// This thing is basically a snippet of the generic_payload. 6013513Sgabeblack@google.com// It contains all the extension specific code (the extension API so to speak) 6113511Sgabeblack@google.com// the differences are: 6213513Sgabeblack@google.com// - it calls back to its owner whenever a real (==non-NULL) extension gets 6313513Sgabeblack@google.com// set for the first time. 6413513Sgabeblack@google.com// - it calls back to its owner whenever a living (==non-NULL) extension gets 6513513Sgabeblack@google.com// cleared. 6613513Sgabeblack@google.comclass instance_specific_extensions_per_accessor 6713511Sgabeblack@google.com{ 6813513Sgabeblack@google.com public: 6913513Sgabeblack@google.com typedef instance_specific_extension_container container_type; 7013511Sgabeblack@google.com 7113513Sgabeblack@google.com explicit 7213513Sgabeblack@google.com instance_specific_extensions_per_accessor(container_type *container) : 7313513Sgabeblack@google.com m_container(container) 7413513Sgabeblack@google.com {} 7513511Sgabeblack@google.com 7613513Sgabeblack@google.com template <typename T> 7713513Sgabeblack@google.com T * 7813513Sgabeblack@google.com set_extension(T *ext) 7913513Sgabeblack@google.com { 8013513Sgabeblack@google.com return static_cast<T *>(set_extension(T::priv_id, ext)); 8113513Sgabeblack@google.com } 8213511Sgabeblack@google.com 8313513Sgabeblack@google.com // Non-templatized version with manual index: 8413513Sgabeblack@google.com ispex_base *set_extension(unsigned int index, ispex_base *ext); 8513511Sgabeblack@google.com 8613513Sgabeblack@google.com // Check for an extension, ext will be nullptr if not present. 8713513Sgabeblack@google.com template <typename T> 8813513Sgabeblack@google.com void get_extension(T *& ext) const 8913513Sgabeblack@google.com { 9013513Sgabeblack@google.com ext = static_cast<T *>(get_extension(T::priv_id)); 9113513Sgabeblack@google.com } 9213513Sgabeblack@google.com // Non-templatized version: 9313513Sgabeblack@google.com ispex_base *get_extension(unsigned int index) const; 9413511Sgabeblack@google.com 9513513Sgabeblack@google.com // Clear extension, the argument is needed to find the right index: 9613513Sgabeblack@google.com template <typename T> 9713513Sgabeblack@google.com void clear_extension(const T *) 9813513Sgabeblack@google.com { 9913513Sgabeblack@google.com clear_extension(T::priv_id); 10013513Sgabeblack@google.com } 10113511Sgabeblack@google.com 10213513Sgabeblack@google.com // Non-templatized version with manual index 10313513Sgabeblack@google.com void clear_extension(unsigned int index); 10413511Sgabeblack@google.com 10513513Sgabeblack@google.com // Make sure the extension array is large enough. Can be called once by 10613513Sgabeblack@google.com // an initiator module (before issuing the first transaction) to make 10713513Sgabeblack@google.com // sure that the extension array is of correct size. This is only needed 10813513Sgabeblack@google.com // if the initiator cannot guarantee that the generic payload object is 10913513Sgabeblack@google.com // allocated after C++ static construction time. 11013513Sgabeblack@google.com void resize_extensions(); 11113511Sgabeblack@google.com 11213513Sgabeblack@google.com private: 11313513Sgabeblack@google.com tlm::tlm_array<ispex_base *> m_extensions; 11413513Sgabeblack@google.com container_type* m_container; 11513513Sgabeblack@google.com}; 11613511Sgabeblack@google.com 11713513Sgabeblack@google.com// This thing contains the vector of extensions per accessor 11813513Sgabeblack@google.com// which can be really large so this one should be pool allocated. 11913513Sgabeblack@google.com// Therefore it keeps a use_count of itself to automatically free itself. 12013513Sgabeblack@google.com// - to this end it provides callbacks to the extensions per accessor 12113513Sgabeblack@google.com// to increment and decrement the use_count. 12213513Sgabeblack@google.comclass instance_specific_extension_container 12313513Sgabeblack@google.com{ 12413513Sgabeblack@google.com friend class instance_specific_extension_accessor; 12513513Sgabeblack@google.com friend class instance_specific_extension_carrier; 12613513Sgabeblack@google.com friend class instance_specific_extension_container_pool; 12713513Sgabeblack@google.com friend class instance_specific_extensions_per_accessor; 12813511Sgabeblack@google.com 12913513Sgabeblack@google.com typedef void release_fn(instance_specific_extension_carrier *, void *); 13013511Sgabeblack@google.com 13113513Sgabeblack@google.com instance_specific_extension_container(); 13213513Sgabeblack@google.com ~instance_specific_extension_container(); 13313511Sgabeblack@google.com 13413513Sgabeblack@google.com void resize(); 13513511Sgabeblack@google.com 13613513Sgabeblack@google.com void inc_use_count(); 13713513Sgabeblack@google.com void dec_use_count(); 13813511Sgabeblack@google.com 13913513Sgabeblack@google.com static instance_specific_extension_container *create(); 14013513Sgabeblack@google.com void attach_carrier( 14113513Sgabeblack@google.com instance_specific_extension_carrier *, void *txn, release_fn *); 14213511Sgabeblack@google.com 14313513Sgabeblack@google.com instance_specific_extensions_per_accessor * 14413513Sgabeblack@google.com get_accessor(unsigned int index); 14513511Sgabeblack@google.com 14613513Sgabeblack@google.com std::vector<instance_specific_extensions_per_accessor *> 14713513Sgabeblack@google.com m_ispex_per_accessor; 14813513Sgabeblack@google.com unsigned int use_count; 14913513Sgabeblack@google.com void *m_txn; 15013513Sgabeblack@google.com release_fn *m_release_fn; 15113513Sgabeblack@google.com instance_specific_extension_carrier *m_carrier; 15213513Sgabeblack@google.com instance_specific_extension_container *next; // For pooling. 15313513Sgabeblack@google.com}; 15413511Sgabeblack@google.com 15513511Sgabeblack@google.com// ---------------------------------------------------------------------------- 15613511Sgabeblack@google.com 15713513Sgabeblack@google.com// This class 'hides' all the instance specific extension stuff from the user. 15813513Sgabeblack@google.com// They instantiates one of those (e.g. instance_specific_extension_accessor 15913513Sgabeblack@google.com// extAcc;) and can then access the private extensions. 16013511Sgabeblack@google.com// extAcc(txn).extensionAPIFnCall() 16113513Sgabeblack@google.com// where extensionAPIFnCall is set_extension, get_extension, 16213513Sgabeblack@google.com// clear_extension,... 16313513Sgabeblack@google.comclass instance_specific_extension_accessor 16413511Sgabeblack@google.com{ 16513513Sgabeblack@google.com public: 16613513Sgabeblack@google.com instance_specific_extension_accessor(); 16713511Sgabeblack@google.com 16813513Sgabeblack@google.com // Implementation in instance_specific_extensions.h 16913513Sgabeblack@google.com template <typename T> 17013513Sgabeblack@google.com inline instance_specific_extensions_per_accessor &operator () (T &txn); 17113511Sgabeblack@google.com 17213513Sgabeblack@google.com protected: 17313513Sgabeblack@google.com template<typename T> 17413513Sgabeblack@google.com static void release_carrier( 17513513Sgabeblack@google.com instance_specific_extension_carrier *, void * txn); 17613511Sgabeblack@google.com 17713513Sgabeblack@google.com unsigned int m_index; 17813513Sgabeblack@google.com}; 17913511Sgabeblack@google.com 18013511Sgabeblack@google.com} // namespace tlm_utils 18113513Sgabeblack@google.com 18213513Sgabeblack@google.com#endif /* __SYSTEMC_EXT_TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H__ */ 183