instance_specific_extensions_int.h revision 13511
110478SAndrew.Bardsley@arm.com/*****************************************************************************
210478SAndrew.Bardsley@arm.com
310478SAndrew.Bardsley@arm.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
410478SAndrew.Bardsley@arm.com  more contributor license agreements.  See the NOTICE file distributed
510478SAndrew.Bardsley@arm.com  with this work for additional information regarding copyright ownership.
610478SAndrew.Bardsley@arm.com  Accellera licenses this file to you under the Apache License, Version 2.0
710478SAndrew.Bardsley@arm.com  (the "License"); you may not use this file except in compliance with the
810478SAndrew.Bardsley@arm.com  License.  You may obtain a copy of the License at
910478SAndrew.Bardsley@arm.com
1010478SAndrew.Bardsley@arm.com    http://www.apache.org/licenses/LICENSE-2.0
1110478SAndrew.Bardsley@arm.com
1210478SAndrew.Bardsley@arm.com  Unless required by applicable law or agreed to in writing, software
1310478SAndrew.Bardsley@arm.com  distributed under the License is distributed on an "AS IS" BASIS,
1410478SAndrew.Bardsley@arm.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1510478SAndrew.Bardsley@arm.com  implied.  See the License for the specific language governing
1610478SAndrew.Bardsley@arm.com  permissions and limitations under the License.
1710478SAndrew.Bardsley@arm.com
1810478SAndrew.Bardsley@arm.com *****************************************************************************/
1910478SAndrew.Bardsley@arm.com#ifndef TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_
2010478SAndrew.Bardsley@arm.com#define TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_
2110478SAndrew.Bardsley@arm.com
2210478SAndrew.Bardsley@arm.com#ifndef SC_BUILD // incluce full TLM, when not building the library
2310478SAndrew.Bardsley@arm.com#include <tlm>
2410478SAndrew.Bardsley@arm.com#else
2510478SAndrew.Bardsley@arm.com#include "tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h"
2610478SAndrew.Bardsley@arm.com#endif // SC_BUILD
2710478SAndrew.Bardsley@arm.com
2810478SAndrew.Bardsley@arm.comnamespace tlm_utils {
2910478SAndrew.Bardsley@arm.comclass SC_API ispex_base;
3010478SAndrew.Bardsley@arm.comclass SC_API instance_specific_extension_accessor;
3110478SAndrew.Bardsley@arm.comclass SC_API instance_specific_extension_container;
3210478SAndrew.Bardsley@arm.comclass instance_specific_extension_carrier;
3310478SAndrew.Bardsley@arm.comclass instance_specific_extension_container_pool;
3410478SAndrew.Bardsley@arm.com}
3510478SAndrew.Bardsley@arm.com
3610478SAndrew.Bardsley@arm.comnamespace tlm {
3710478SAndrew.Bardsley@arm.comSC_API_TEMPLATE_DECL_ tlm_array<tlm_utils::ispex_base*>;
3810478SAndrew.Bardsley@arm.com} // namespace tlm
3913892Sgabeblack@google.com
4010478SAndrew.Bardsley@arm.comnamespace tlm_utils {
4113892Sgabeblack@google.com
4210478SAndrew.Bardsley@arm.com//The private extension base. Similar to normal extension base, but without clone and free
4310478SAndrew.Bardsley@arm.comclass SC_API ispex_base
4410478SAndrew.Bardsley@arm.com{
4510478SAndrew.Bardsley@arm.com    friend class tlm::tlm_array<ispex_base*>;
4610478SAndrew.Bardsley@arm.com    void free() {} // needed for explicit tlm_array instantiation
4710478SAndrew.Bardsley@arm.compublic:
4810478SAndrew.Bardsley@arm.com    virtual ~ispex_base() {}
4910478SAndrew.Bardsley@arm.comprotected:
5010478SAndrew.Bardsley@arm.com    static unsigned int register_private_extension(const std::type_info&);
5110478SAndrew.Bardsley@arm.com};
5210478SAndrew.Bardsley@arm.com
5310478SAndrew.Bardsley@arm.com//this thing is basically a snippet of the generic_payload
5410478SAndrew.Bardsley@arm.com// 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