instance_specific_extensions_int.h revision 13511
1/***************************************************************************** 2 3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 more contributor license agreements. See the NOTICE file distributed 5 with this work for additional information regarding copyright ownership. 6 Accellera licenses this file to you under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with the 8 License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 implied. See the License for the specific language governing 16 permissions and limitations under the License. 17 18 *****************************************************************************/ 19#ifndef TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_ 20#define TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_ 21 22#ifndef SC_BUILD // incluce full TLM, when not building the library 23#include <tlm> 24#else 25#include "tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h" 26#endif // SC_BUILD 27 28namespace tlm_utils { 29class SC_API ispex_base; 30class SC_API instance_specific_extension_accessor; 31class SC_API instance_specific_extension_container; 32class instance_specific_extension_carrier; 33class instance_specific_extension_container_pool; 34} 35 36namespace tlm { 37SC_API_TEMPLATE_DECL_ tlm_array<tlm_utils::ispex_base*>; 38} // namespace tlm 39 40namespace tlm_utils { 41 42//The private extension base. Similar to normal extension base, but without clone and free 43class SC_API ispex_base 44{ 45 friend class tlm::tlm_array<ispex_base*>; 46 void free() {} // needed for explicit tlm_array instantiation 47public: 48 virtual ~ispex_base() {} 49protected: 50 static unsigned int register_private_extension(const std::type_info&); 51}; 52 53//this thing is basically a snippet of the generic_payload 54// it contains all the extension specific code (the extension API so to speak) 55// the differences are: 56// - it calls back to its owner whenever a real (==non-NULL) extension gets set for the first time 57// - it calls back to its owner whenever a living (==non-NULL) extension gets cleared 58class SC_API instance_specific_extensions_per_accessor 59{ 60public: 61 typedef instance_specific_extension_container container_type; 62 63 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