summaryrefslogtreecommitdiff
path: root/src/systemc/ext/tlm_utils/instance_specific_extensions_int.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemc/ext/tlm_utils/instance_specific_extensions_int.h')
-rw-r--r--src/systemc/ext/tlm_utils/instance_specific_extensions_int.h174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/systemc/ext/tlm_utils/instance_specific_extensions_int.h b/src/systemc/ext/tlm_utils/instance_specific_extensions_int.h
new file mode 100644
index 000000000..192a600ba
--- /dev/null
+++ b/src/systemc/ext/tlm_utils/instance_specific_extensions_int.h
@@ -0,0 +1,174 @@
+/*****************************************************************************
+
+ 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 TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_
+#define TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_
+
+#ifndef SC_BUILD // incluce full TLM, when not building the library
+#include <tlm>
+#else
+#include "tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h"
+#endif // SC_BUILD
+
+namespace tlm_utils {
+class SC_API ispex_base;
+class SC_API instance_specific_extension_accessor;
+class SC_API instance_specific_extension_container;
+class instance_specific_extension_carrier;
+class instance_specific_extension_container_pool;
+}
+
+namespace tlm {
+SC_API_TEMPLATE_DECL_ 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 SC_API 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 SC_API 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 point to 0 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;
+
+}; // class instance_specific_extensions_per_accessor
+
+#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
+#pragma warning(push)
+#pragma warning(disable: 4251) // DLL import for vector
+#endif
+
+//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 SC_API 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
+
+}; // class instance_specific_extension_container
+
+#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
+#pragma warning(pop)
+#endif
+
+// ----------------------------------------------------------------------------
+
+//This class 'hides' all the instance specific extension stuff from the user
+// he 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 SC_API instance_specific_extension_accessor
+{
+public:
+ instance_specific_extension_accessor();
+
+ template<typename T> // implementation in instance_specific_extensions.h
+ 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;
+}; // class instance_specific_extension_accessor
+
+} // namespace tlm_utils
+#endif // TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_