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