instance_specific_extensions_int.h revision 13511
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 *****************************************************************************/ 1913511Sgabeblack@google.com#ifndef TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_ 2013511Sgabeblack@google.com#define TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_ 2113511Sgabeblack@google.com 2213511Sgabeblack@google.com#ifndef SC_BUILD // incluce full TLM, when not building the library 2313511Sgabeblack@google.com#include <tlm> 2413511Sgabeblack@google.com#else 2513511Sgabeblack@google.com#include "tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h" 2613511Sgabeblack@google.com#endif // SC_BUILD 2713511Sgabeblack@google.com 2813511Sgabeblack@google.comnamespace tlm_utils { 2913511Sgabeblack@google.comclass SC_API ispex_base; 3013511Sgabeblack@google.comclass SC_API instance_specific_extension_accessor; 3113511Sgabeblack@google.comclass SC_API instance_specific_extension_container; 3213511Sgabeblack@google.comclass instance_specific_extension_carrier; 3313511Sgabeblack@google.comclass instance_specific_extension_container_pool; 3413511Sgabeblack@google.com} 3513511Sgabeblack@google.com 3613511Sgabeblack@google.comnamespace tlm { 3713511Sgabeblack@google.comSC_API_TEMPLATE_DECL_ tlm_array<tlm_utils::ispex_base*>; 3813511Sgabeblack@google.com} // namespace tlm 3913511Sgabeblack@google.com 4013511Sgabeblack@google.comnamespace tlm_utils { 4113511Sgabeblack@google.com 4213511Sgabeblack@google.com//The private extension base. Similar to normal extension base, but without clone and free 4313511Sgabeblack@google.comclass SC_API ispex_base 4413511Sgabeblack@google.com{ 4513511Sgabeblack@google.com friend class tlm::tlm_array<ispex_base*>; 4613511Sgabeblack@google.com void free() {} // needed for explicit tlm_array instantiation 4713511Sgabeblack@google.compublic: 4813511Sgabeblack@google.com virtual ~ispex_base() {} 4913511Sgabeblack@google.comprotected: 5013511Sgabeblack@google.com static unsigned int register_private_extension(const std::type_info&); 5113511Sgabeblack@google.com}; 5213511Sgabeblack@google.com 5313511Sgabeblack@google.com//this thing is basically a snippet of the generic_payload 5413511Sgabeblack@google.com// it contains all the extension specific code (the extension API so to speak) 5513511Sgabeblack@google.com// the differences are: 5613511Sgabeblack@google.com// - it calls back to its owner whenever a real (==non-NULL) extension gets set for the first time 5713511Sgabeblack@google.com// - it calls back to its owner whenever a living (==non-NULL) extension gets cleared 5813511Sgabeblack@google.comclass SC_API instance_specific_extensions_per_accessor 5913511Sgabeblack@google.com{ 6013511Sgabeblack@google.compublic: 6113511Sgabeblack@google.com typedef instance_specific_extension_container container_type; 6213511Sgabeblack@google.com 6313511Sgabeblack@google.com explicit 6413511Sgabeblack@google.com instance_specific_extensions_per_accessor(container_type* container) 6513511Sgabeblack@google.com : m_container(container) 6613511Sgabeblack@google.com {} 6713511Sgabeblack@google.com 6813511Sgabeblack@google.com template <typename T> T* set_extension(T* ext) 6913511Sgabeblack@google.com { 7013511Sgabeblack@google.com return static_cast<T*>( set_extension(T::priv_id, ext) ); 7113511Sgabeblack@google.com } 7213511Sgabeblack@google.com 7313511Sgabeblack@google.com // non-templatized version with manual index: 7413511Sgabeblack@google.com ispex_base* set_extension(unsigned int index, ispex_base* ext); 7513511Sgabeblack@google.com 7613511Sgabeblack@google.com // Check for an extension, ext will point to 0 if not present 7713511Sgabeblack@google.com template <typename T> void get_extension(T*& ext) const 7813511Sgabeblack@google.com { 7913511Sgabeblack@google.com ext = static_cast<T*>(get_extension(T::priv_id)); 8013511Sgabeblack@google.com } 8113511Sgabeblack@google.com // Non-templatized version: 8213511Sgabeblack@google.com ispex_base* get_extension(unsigned int index) const; 8313511Sgabeblack@google.com 8413511Sgabeblack@google.com // Clear extension, the argument is needed to find the right index: 8513511Sgabeblack@google.com template <typename T> void clear_extension(const T*) 8613511Sgabeblack@google.com { 8713511Sgabeblack@google.com clear_extension(T::priv_id); 8813511Sgabeblack@google.com } 8913511Sgabeblack@google.com 9013511Sgabeblack@google.com // Non-templatized version with manual index 9113511Sgabeblack@google.com void clear_extension(unsigned int index); 9213511Sgabeblack@google.com 9313511Sgabeblack@google.com // Make sure the extension array is large enough. Can be called once by 9413511Sgabeblack@google.com // an initiator module (before issuing the first transaction) to make 9513511Sgabeblack@google.com // sure that the extension array is of correct size. This is only needed 9613511Sgabeblack@google.com // if the initiator cannot guarantee that the generic payload object is 9713511Sgabeblack@google.com // allocated after C++ static construction time. 9813511Sgabeblack@google.com void resize_extensions(); 9913511Sgabeblack@google.com 10013511Sgabeblack@google.comprivate: 10113511Sgabeblack@google.com tlm::tlm_array<ispex_base*> m_extensions; 10213511Sgabeblack@google.com container_type* m_container; 10313511Sgabeblack@google.com 10413511Sgabeblack@google.com}; // class instance_specific_extensions_per_accessor 10513511Sgabeblack@google.com 10613511Sgabeblack@google.com#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN) 10713511Sgabeblack@google.com#pragma warning(push) 10813511Sgabeblack@google.com#pragma warning(disable: 4251) // DLL import for vector 10913511Sgabeblack@google.com#endif 11013511Sgabeblack@google.com 11113511Sgabeblack@google.com//this thing contains the vector of extensions per accessor 11213511Sgabeblack@google.com//which can be really large so this one should be pool allocated 11313511Sgabeblack@google.com// therefore it keeps a use_count of itself to automatically free itself 11413511Sgabeblack@google.com// - to this end it provides callbacks to the extensions per accessor 11513511Sgabeblack@google.com// to increment and decrement the use_count 11613511Sgabeblack@google.comclass SC_API instance_specific_extension_container 11713511Sgabeblack@google.com{ 11813511Sgabeblack@google.com friend class instance_specific_extension_accessor; 11913511Sgabeblack@google.com friend class instance_specific_extension_carrier; 12013511Sgabeblack@google.com friend class instance_specific_extension_container_pool; 12113511Sgabeblack@google.com friend class instance_specific_extensions_per_accessor; 12213511Sgabeblack@google.com 12313511Sgabeblack@google.com typedef void release_fn(instance_specific_extension_carrier*,void*); 12413511Sgabeblack@google.com 12513511Sgabeblack@google.com instance_specific_extension_container(); 12613511Sgabeblack@google.com ~instance_specific_extension_container(); 12713511Sgabeblack@google.com 12813511Sgabeblack@google.com void resize(); 12913511Sgabeblack@google.com 13013511Sgabeblack@google.com void inc_use_count(); 13113511Sgabeblack@google.com void dec_use_count(); 13213511Sgabeblack@google.com 13313511Sgabeblack@google.com static instance_specific_extension_container* create(); 13413511Sgabeblack@google.com void attach_carrier(instance_specific_extension_carrier*, void* txn, release_fn*); 13513511Sgabeblack@google.com 13613511Sgabeblack@google.com instance_specific_extensions_per_accessor* get_accessor(unsigned int index); 13713511Sgabeblack@google.com 13813511Sgabeblack@google.com std::vector<instance_specific_extensions_per_accessor*> m_ispex_per_accessor; 13913511Sgabeblack@google.com unsigned int use_count; 14013511Sgabeblack@google.com void* m_txn; 14113511Sgabeblack@google.com release_fn* m_release_fn; 14213511Sgabeblack@google.com instance_specific_extension_carrier* m_carrier; 14313511Sgabeblack@google.com instance_specific_extension_container* next; //for pooling 14413511Sgabeblack@google.com 14513511Sgabeblack@google.com}; // class instance_specific_extension_container 14613511Sgabeblack@google.com 14713511Sgabeblack@google.com#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN) 14813511Sgabeblack@google.com#pragma warning(pop) 14913511Sgabeblack@google.com#endif 15013511Sgabeblack@google.com 15113511Sgabeblack@google.com// ---------------------------------------------------------------------------- 15213511Sgabeblack@google.com 15313511Sgabeblack@google.com//This class 'hides' all the instance specific extension stuff from the user 15413511Sgabeblack@google.com// he instantiates one of those (e.g. instance_specific_extension_accessor extAcc;) and can then access 15513511Sgabeblack@google.com// the private extensions 15613511Sgabeblack@google.com// extAcc(txn).extensionAPIFnCall() 15713511Sgabeblack@google.com// where extensionAPIFnCall is set_extension, get_extension, clear_extension,... 15813511Sgabeblack@google.comclass SC_API instance_specific_extension_accessor 15913511Sgabeblack@google.com{ 16013511Sgabeblack@google.compublic: 16113511Sgabeblack@google.com instance_specific_extension_accessor(); 16213511Sgabeblack@google.com 16313511Sgabeblack@google.com template<typename T> // implementation in instance_specific_extensions.h 16413511Sgabeblack@google.com inline instance_specific_extensions_per_accessor& operator()(T& txn); 16513511Sgabeblack@google.com 16613511Sgabeblack@google.comprotected: 16713511Sgabeblack@google.com template<typename T> 16813511Sgabeblack@google.com static void release_carrier(instance_specific_extension_carrier*, void* txn); 16913511Sgabeblack@google.com 17013511Sgabeblack@google.com unsigned int m_index; 17113511Sgabeblack@google.com}; // class instance_specific_extension_accessor 17213511Sgabeblack@google.com 17313511Sgabeblack@google.com} // namespace tlm_utils 17413511Sgabeblack@google.com#endif // TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_ 175