| /***************************************************************************** | |
| Licensed to Accellera Systems Initiative Inc. (Accellera) under one or | |
| more contributor license agreements. See the NOTICE file distributed | |
| with this work for additional information regarding copyright ownership. | |
| Accellera licenses this file to you under the Apache License, Version 2.0 | |
| (the "License"); you may not use this file except in compliance with the | |
| License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
| implied. See the License for the specific language governing | |
| permissions and limitations under the License. | |
| *****************************************************************************/ | |
| #ifndef __SYSTEMC_EXT_TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H__ | |
| #define __SYSTEMC_EXT_TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H__ | |
| #include <vector> | |
| #include "../tlm_core/2/generic_payload/array.hh" | |
| namespace tlm_utils | |
| { | |
| class ispex_base; | |
| class instance_specific_extension_accessor; | |
| class instance_specific_extension_container; | |
| class instance_specific_extension_carrier; | |
| class instance_specific_extension_container_pool; | |
| } // namespace tlm_utils | |
| namespace tlm | |
| { | |
| extern template class tlm_array<tlm_utils::ispex_base *>; | |
| } // namespace tlm | |
| namespace tlm_utils | |
| { | |
| // The private extension base. Similar to normal extension base, but without | |
| // clone and free. | |
| class ispex_base | |
| { | |
| friend class tlm::tlm_array<ispex_base*>; | |
| void free() {} // Needed for explicit tlm_array instantiation. | |
| public: | |
| virtual ~ispex_base() {} | |
| protected: | |
| static unsigned int register_private_extension(const std::type_info &); | |
| }; | |
| // This thing is basically a snippet of the generic_payload. | |
| // It contains all the extension specific code (the extension API so to speak) | |
| // the differences are: | |
| // - it calls back to its owner whenever a real (==non-NULL) extension gets | |
| // set for the first time. | |
| // - it calls back to its owner whenever a living (==non-NULL) extension gets | |
| // cleared. | |
| class instance_specific_extensions_per_accessor | |
| { | |
| public: | |
| typedef instance_specific_extension_container container_type; | |
| explicit | |
| instance_specific_extensions_per_accessor(container_type *container) : | |
| m_container(container) | |
| {} | |
| template <typename T> | |
| T * | |
| set_extension(T *ext) | |
| { | |
| return static_cast<T *>(set_extension(T::priv_id, ext)); | |
| } | |
| // Non-templatized version with manual index: | |
| ispex_base *set_extension(unsigned int index, ispex_base *ext); | |
| // Check for an extension, ext will be nullptr if not present. | |
| template <typename T> | |
| void get_extension(T *& ext) const | |
| { | |
| ext = static_cast<T *>(get_extension(T::priv_id)); | |
| } | |
| // Non-templatized version: | |
| ispex_base *get_extension(unsigned int index) const; | |
| // Clear extension, the argument is needed to find the right index: | |
| template <typename T> | |
| void clear_extension(const T *) | |
| { | |
| clear_extension(T::priv_id); | |
| } | |
| // Non-templatized version with manual index | |
| void clear_extension(unsigned int index); | |
| // Make sure the extension array is large enough. Can be called once by | |
| // an initiator module (before issuing the first transaction) to make | |
| // sure that the extension array is of correct size. This is only needed | |
| // if the initiator cannot guarantee that the generic payload object is | |
| // allocated after C++ static construction time. | |
| void resize_extensions(); | |
| private: | |
| tlm::tlm_array<ispex_base *> m_extensions; | |
| container_type* m_container; | |
| }; | |
| // This thing contains the vector of extensions per accessor | |
| // which can be really large so this one should be pool allocated. | |
| // Therefore it keeps a use_count of itself to automatically free itself. | |
| // - to this end it provides callbacks to the extensions per accessor | |
| // to increment and decrement the use_count. | |
| class instance_specific_extension_container | |
| { | |
| friend class instance_specific_extension_accessor; | |
| friend class instance_specific_extension_carrier; | |
| friend class instance_specific_extension_container_pool; | |
| friend class instance_specific_extensions_per_accessor; | |
| typedef void release_fn(instance_specific_extension_carrier *, void *); | |
| instance_specific_extension_container(); | |
| ~instance_specific_extension_container(); | |
| void resize(); | |
| void inc_use_count(); | |
| void dec_use_count(); | |
| static instance_specific_extension_container *create(); | |
| void attach_carrier( | |
| instance_specific_extension_carrier *, void *txn, release_fn *); | |
| instance_specific_extensions_per_accessor * | |
| get_accessor(unsigned int index); | |
| std::vector<instance_specific_extensions_per_accessor *> | |
| m_ispex_per_accessor; | |
| unsigned int use_count; | |
| void *m_txn; | |
| release_fn *m_release_fn; | |
| instance_specific_extension_carrier *m_carrier; | |
| instance_specific_extension_container *next; // For pooling. | |
| }; | |
| // ---------------------------------------------------------------------------- | |
| // This class 'hides' all the instance specific extension stuff from the user. | |
| // They instantiates one of those (e.g. instance_specific_extension_accessor | |
| // extAcc;) and can then access the private extensions. | |
| // extAcc(txn).extensionAPIFnCall() | |
| // where extensionAPIFnCall is set_extension, get_extension, | |
| // clear_extension,... | |
| class instance_specific_extension_accessor | |
| { | |
| public: | |
| instance_specific_extension_accessor(); | |
| // Implementation in instance_specific_extensions.h | |
| template <typename T> | |
| inline instance_specific_extensions_per_accessor &operator () (T &txn); | |
| protected: | |
| template<typename T> | |
| static void release_carrier( | |
| instance_specific_extension_carrier *, void * txn); | |
| unsigned int m_index; | |
| }; | |
| } // namespace tlm_utils | |
| #endif /* __SYSTEMC_EXT_TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H__ */ |