instance_specific_extensions_int.h revision 13511:dc5864c73df3
12SN/A/***************************************************************************** 21762SN/A 32SN/A Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 42SN/A more contributor license agreements. See the NOTICE file distributed 52SN/A with this work for additional information regarding copyright ownership. 62SN/A Accellera licenses this file to you under the Apache License, Version 2.0 72SN/A (the "License"); you may not use this file except in compliance with the 82SN/A License. You may obtain a copy of the License at 92SN/A 102SN/A http://www.apache.org/licenses/LICENSE-2.0 112SN/A 122SN/A Unless required by applicable law or agreed to in writing, software 132SN/A distributed under the License is distributed on an "AS IS" BASIS, 142SN/A WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 152SN/A implied. See the License for the specific language governing 162SN/A permissions and limitations under the License. 172SN/A 182SN/A *****************************************************************************/ 192SN/A#ifndef TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_ 202SN/A#define TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_ 212SN/A 222SN/A#ifndef SC_BUILD // incluce full TLM, when not building the library 232SN/A#include <tlm> 242SN/A#else 252SN/A#include "tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h" 262SN/A#endif // SC_BUILD 272665SN/A 282665SN/Anamespace tlm_utils { 292SN/Aclass SC_API ispex_base; 302SN/Aclass SC_API instance_specific_extension_accessor; 3111263Sandreas.sandberg@arm.comclass SC_API instance_specific_extension_container; 3211263Sandreas.sandberg@arm.comclass instance_specific_extension_carrier; 3312334Sgabeblack@google.comclass instance_specific_extension_container_pool; 3456SN/A} 352SN/A 362SN/Anamespace tlm { 3713782Sgabeblack@google.comSC_API_TEMPLATE_DECL_ tlm_array<tlm_utils::ispex_base*>; 3813782Sgabeblack@google.com} // namespace tlm 3913782Sgabeblack@google.com 4013782Sgabeblack@google.comnamespace tlm_utils { 4113782Sgabeblack@google.com 4213782Sgabeblack@google.com//The private extension base. Similar to normal extension base, but without clone and free 4313782Sgabeblack@google.comclass SC_API ispex_base 4413782Sgabeblack@google.com{ 4513782Sgabeblack@google.com friend class tlm::tlm_array<ispex_base*>; 4613782Sgabeblack@google.com void free() {} // needed for explicit tlm_array instantiation 4713782Sgabeblack@google.compublic: 4813782Sgabeblack@google.com virtual ~ispex_base() {} 4913782Sgabeblack@google.comprotected: 5013782Sgabeblack@google.com static unsigned int register_private_extension(const std::type_info&); 5113782Sgabeblack@google.com}; 5213782Sgabeblack@google.com 5313782Sgabeblack@google.com//this thing is basically a snippet of the generic_payload 5413782Sgabeblack@google.com// it contains all the extension specific code (the extension API so to speak) 5513782Sgabeblack@google.com// the differences are: 562SN/A// - it calls back to its owner whenever a real (==non-NULL) extension gets set for the first time 572SN/A// - it calls back to its owner whenever a living (==non-NULL) extension gets cleared 582SN/Aclass SC_API instance_specific_extensions_per_accessor 592SN/A{ 602SN/Apublic: 612SN/A typedef instance_specific_extension_container container_type; 622SN/A 632SN/A explicit 64 instance_specific_extensions_per_accessor(container_type* container) 65 : m_container(container) 66 {} 67 68 template <typename T> T* set_extension(T* ext) 69 { 70 return static_cast<T*>( set_extension(T::priv_id, ext) ); 71 } 72 73 // non-templatized version with manual index: 74 ispex_base* set_extension(unsigned int index, ispex_base* ext); 75 76 // Check for an extension, ext will point to 0 if not present 77 template <typename T> void get_extension(T*& ext) const 78 { 79 ext = static_cast<T*>(get_extension(T::priv_id)); 80 } 81 // Non-templatized version: 82 ispex_base* get_extension(unsigned int index) const; 83 84 // Clear extension, the argument is needed to find the right index: 85 template <typename T> void clear_extension(const T*) 86 { 87 clear_extension(T::priv_id); 88 } 89 90 // Non-templatized version with manual index 91 void clear_extension(unsigned int index); 92 93 // Make sure the extension array is large enough. Can be called once by 94 // an initiator module (before issuing the first transaction) to make 95 // sure that the extension array is of correct size. This is only needed 96 // if the initiator cannot guarantee that the generic payload object is 97 // allocated after C++ static construction time. 98 void resize_extensions(); 99 100private: 101 tlm::tlm_array<ispex_base*> m_extensions; 102 container_type* m_container; 103 104}; // class instance_specific_extensions_per_accessor 105 106#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN) 107#pragma warning(push) 108#pragma warning(disable: 4251) // DLL import for vector 109#endif 110 111//this thing contains the vector of extensions per accessor 112//which can be really large so this one should be pool allocated 113// therefore it keeps a use_count of itself to automatically free itself 114// - to this end it provides callbacks to the extensions per accessor 115// to increment and decrement the use_count 116class SC_API instance_specific_extension_container 117{ 118 friend class instance_specific_extension_accessor; 119 friend class instance_specific_extension_carrier; 120 friend class instance_specific_extension_container_pool; 121 friend class instance_specific_extensions_per_accessor; 122 123 typedef void release_fn(instance_specific_extension_carrier*,void*); 124 125 instance_specific_extension_container(); 126 ~instance_specific_extension_container(); 127 128 void resize(); 129 130 void inc_use_count(); 131 void dec_use_count(); 132 133 static instance_specific_extension_container* create(); 134 void attach_carrier(instance_specific_extension_carrier*, void* txn, release_fn*); 135 136 instance_specific_extensions_per_accessor* get_accessor(unsigned int index); 137 138 std::vector<instance_specific_extensions_per_accessor*> m_ispex_per_accessor; 139 unsigned int use_count; 140 void* m_txn; 141 release_fn* m_release_fn; 142 instance_specific_extension_carrier* m_carrier; 143 instance_specific_extension_container* next; //for pooling 144 145}; // class instance_specific_extension_container 146 147#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN) 148#pragma warning(pop) 149#endif 150 151// ---------------------------------------------------------------------------- 152 153//This class 'hides' all the instance specific extension stuff from the user 154// he instantiates one of those (e.g. instance_specific_extension_accessor extAcc;) and can then access 155// the private extensions 156// extAcc(txn).extensionAPIFnCall() 157// where extensionAPIFnCall is set_extension, get_extension, clear_extension,... 158class SC_API instance_specific_extension_accessor 159{ 160public: 161 instance_specific_extension_accessor(); 162 163 template<typename T> // implementation in instance_specific_extensions.h 164 inline instance_specific_extensions_per_accessor& operator()(T& txn); 165 166protected: 167 template<typename T> 168 static void release_carrier(instance_specific_extension_carrier*, void* txn); 169 170 unsigned int m_index; 171}; // class instance_specific_extension_accessor 172 173} // namespace tlm_utils 174#endif // TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_ 175