instance_specific_extensions_int.h revision 13511
113511Sgabeblack@google.com/*****************************************************************************
213511Sgabeblack@google.com
313511Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
413511Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
513511Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
613511Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
713511Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
813511Sgabeblack@google.com  License.  You may obtain a copy of the License at
913511Sgabeblack@google.com
1013511Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1113511Sgabeblack@google.com
1213511Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1313511Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1413511Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1513511Sgabeblack@google.com  implied.  See the License for the specific language governing
1613511Sgabeblack@google.com  permissions and limitations under the License.
1713511Sgabeblack@google.com
1813511Sgabeblack@google.com *****************************************************************************/
1913511Sgabeblack@google.com#ifndef TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_
2013511Sgabeblack@google.com#define TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_
2113511Sgabeblack@google.com
2213511Sgabeblack@google.com#ifndef SC_BUILD // incluce full TLM, when not building the library
2313511Sgabeblack@google.com#include <tlm>
2413511Sgabeblack@google.com#else
2513511Sgabeblack@google.com#include "tlm_core/tlm_2/tlm_generic_payload/tlm_gp.h"
2613511Sgabeblack@google.com#endif // SC_BUILD
2713511Sgabeblack@google.com
2813511Sgabeblack@google.comnamespace tlm_utils {
2913511Sgabeblack@google.comclass SC_API ispex_base;
3013511Sgabeblack@google.comclass SC_API instance_specific_extension_accessor;
3113511Sgabeblack@google.comclass SC_API instance_specific_extension_container;
3213511Sgabeblack@google.comclass instance_specific_extension_carrier;
3313511Sgabeblack@google.comclass instance_specific_extension_container_pool;
3413511Sgabeblack@google.com}
3513511Sgabeblack@google.com
3613511Sgabeblack@google.comnamespace tlm {
3713511Sgabeblack@google.comSC_API_TEMPLATE_DECL_ tlm_array<tlm_utils::ispex_base*>;
3813511Sgabeblack@google.com} // namespace tlm
3913511Sgabeblack@google.com
4013511Sgabeblack@google.comnamespace tlm_utils {
4113511Sgabeblack@google.com
4213511Sgabeblack@google.com//The private extension base. Similar to normal extension base, but without clone and free
4313511Sgabeblack@google.comclass SC_API ispex_base
4413511Sgabeblack@google.com{
4513511Sgabeblack@google.com    friend class tlm::tlm_array<ispex_base*>;
4613511Sgabeblack@google.com    void free() {} // needed for explicit tlm_array instantiation
4713511Sgabeblack@google.compublic:
4813511Sgabeblack@google.com    virtual ~ispex_base() {}
4913511Sgabeblack@google.comprotected:
5013511Sgabeblack@google.com    static unsigned int register_private_extension(const std::type_info&);
5113511Sgabeblack@google.com};
5213511Sgabeblack@google.com
5313511Sgabeblack@google.com//this thing is basically a snippet of the generic_payload
5413511Sgabeblack@google.com// it contains all the extension specific code (the extension API so to speak)
5513511Sgabeblack@google.com// the differences are:
5613511Sgabeblack@google.com// - it calls back to its owner whenever a real (==non-NULL) extension gets set for the first time
5713511Sgabeblack@google.com// - it calls back to its owner whenever a living (==non-NULL) extension gets cleared
5813511Sgabeblack@google.comclass SC_API instance_specific_extensions_per_accessor
5913511Sgabeblack@google.com{
6013511Sgabeblack@google.compublic:
6113511Sgabeblack@google.com  typedef instance_specific_extension_container container_type;
6213511Sgabeblack@google.com
6313511Sgabeblack@google.com  explicit
6413511Sgabeblack@google.com  instance_specific_extensions_per_accessor(container_type* container)
6513511Sgabeblack@google.com    : m_container(container)
6613511Sgabeblack@google.com  {}
6713511Sgabeblack@google.com
6813511Sgabeblack@google.com  template <typename T> T* set_extension(T* ext)
6913511Sgabeblack@google.com  {
7013511Sgabeblack@google.com      return static_cast<T*>( set_extension(T::priv_id, ext) );
7113511Sgabeblack@google.com  }
7213511Sgabeblack@google.com
7313511Sgabeblack@google.com  // non-templatized version with manual index:
7413511Sgabeblack@google.com  ispex_base* set_extension(unsigned int index, ispex_base* ext);
7513511Sgabeblack@google.com
7613511Sgabeblack@google.com  // Check for an extension, ext will point to 0 if not present
7713511Sgabeblack@google.com  template <typename T> void get_extension(T*& ext) const
7813511Sgabeblack@google.com  {
7913511Sgabeblack@google.com      ext = static_cast<T*>(get_extension(T::priv_id));
8013511Sgabeblack@google.com  }
8113511Sgabeblack@google.com  // Non-templatized version:
8213511Sgabeblack@google.com   ispex_base* get_extension(unsigned int index) const;
8313511Sgabeblack@google.com
8413511Sgabeblack@google.com  // Clear extension, the argument is needed to find the right index:
8513511Sgabeblack@google.com  template <typename T> void clear_extension(const T*)
8613511Sgabeblack@google.com  {
8713511Sgabeblack@google.com      clear_extension(T::priv_id);
8813511Sgabeblack@google.com  }
8913511Sgabeblack@google.com
9013511Sgabeblack@google.com  // Non-templatized version with manual index
9113511Sgabeblack@google.com  void clear_extension(unsigned int index);
9213511Sgabeblack@google.com
9313511Sgabeblack@google.com  // Make sure the extension array is large enough. Can be called once by
9413511Sgabeblack@google.com  // an initiator module (before issuing the first transaction) to make
9513511Sgabeblack@google.com  // sure that the extension array is of correct size. This is only needed
9613511Sgabeblack@google.com  // if the initiator cannot guarantee that the generic payload object is
9713511Sgabeblack@google.com  // allocated after C++ static construction time.
9813511Sgabeblack@google.com  void resize_extensions();
9913511Sgabeblack@google.com
10013511Sgabeblack@google.comprivate:
10113511Sgabeblack@google.com  tlm::tlm_array<ispex_base*> m_extensions;
10213511Sgabeblack@google.com  container_type* m_container;
10313511Sgabeblack@google.com
10413511Sgabeblack@google.com}; // class instance_specific_extensions_per_accessor
10513511Sgabeblack@google.com
10613511Sgabeblack@google.com#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
10713511Sgabeblack@google.com#pragma warning(push)
10813511Sgabeblack@google.com#pragma warning(disable: 4251) // DLL import for vector
10913511Sgabeblack@google.com#endif
11013511Sgabeblack@google.com
11113511Sgabeblack@google.com//this thing contains the vector of extensions per accessor
11213511Sgabeblack@google.com//which can be really large so this one should be pool allocated
11313511Sgabeblack@google.com// therefore it keeps a use_count of itself to automatically free itself
11413511Sgabeblack@google.com// - to this end it provides callbacks to the extensions per accessor
11513511Sgabeblack@google.com//   to increment and decrement the use_count
11613511Sgabeblack@google.comclass SC_API instance_specific_extension_container
11713511Sgabeblack@google.com{
11813511Sgabeblack@google.com  friend class instance_specific_extension_accessor;
11913511Sgabeblack@google.com  friend class instance_specific_extension_carrier;
12013511Sgabeblack@google.com  friend class instance_specific_extension_container_pool;
12113511Sgabeblack@google.com  friend class instance_specific_extensions_per_accessor;
12213511Sgabeblack@google.com
12313511Sgabeblack@google.com  typedef void release_fn(instance_specific_extension_carrier*,void*);
12413511Sgabeblack@google.com
12513511Sgabeblack@google.com  instance_specific_extension_container();
12613511Sgabeblack@google.com  ~instance_specific_extension_container();
12713511Sgabeblack@google.com
12813511Sgabeblack@google.com  void resize();
12913511Sgabeblack@google.com
13013511Sgabeblack@google.com  void inc_use_count();
13113511Sgabeblack@google.com  void dec_use_count();
13213511Sgabeblack@google.com
13313511Sgabeblack@google.com  static instance_specific_extension_container* create();
13413511Sgabeblack@google.com  void attach_carrier(instance_specific_extension_carrier*, void* txn, release_fn*);
13513511Sgabeblack@google.com
13613511Sgabeblack@google.com  instance_specific_extensions_per_accessor* get_accessor(unsigned int index);
13713511Sgabeblack@google.com
13813511Sgabeblack@google.com  std::vector<instance_specific_extensions_per_accessor*> m_ispex_per_accessor;
13913511Sgabeblack@google.com  unsigned int use_count;
14013511Sgabeblack@google.com  void* m_txn;
14113511Sgabeblack@google.com  release_fn* m_release_fn;
14213511Sgabeblack@google.com  instance_specific_extension_carrier* m_carrier;
14313511Sgabeblack@google.com  instance_specific_extension_container* next; //for pooling
14413511Sgabeblack@google.com
14513511Sgabeblack@google.com}; // class instance_specific_extension_container
14613511Sgabeblack@google.com
14713511Sgabeblack@google.com#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
14813511Sgabeblack@google.com#pragma warning(pop)
14913511Sgabeblack@google.com#endif
15013511Sgabeblack@google.com
15113511Sgabeblack@google.com// ----------------------------------------------------------------------------
15213511Sgabeblack@google.com
15313511Sgabeblack@google.com//This class 'hides' all the instance specific extension stuff from the user
15413511Sgabeblack@google.com// he instantiates one of those (e.g. instance_specific_extension_accessor extAcc;) and can then access
15513511Sgabeblack@google.com// the private extensions
15613511Sgabeblack@google.com//    extAcc(txn).extensionAPIFnCall()
15713511Sgabeblack@google.com//  where extensionAPIFnCall is set_extension, get_extension, clear_extension,...
15813511Sgabeblack@google.comclass SC_API instance_specific_extension_accessor
15913511Sgabeblack@google.com{
16013511Sgabeblack@google.compublic:
16113511Sgabeblack@google.com  instance_specific_extension_accessor();
16213511Sgabeblack@google.com
16313511Sgabeblack@google.com  template<typename T> // implementation in instance_specific_extensions.h
16413511Sgabeblack@google.com  inline instance_specific_extensions_per_accessor& operator()(T& txn);
16513511Sgabeblack@google.com
16613511Sgabeblack@google.comprotected:
16713511Sgabeblack@google.com  template<typename T>
16813511Sgabeblack@google.com  static void release_carrier(instance_specific_extension_carrier*, void* txn);
16913511Sgabeblack@google.com
17013511Sgabeblack@google.com  unsigned int m_index;
17113511Sgabeblack@google.com}; // class instance_specific_extension_accessor
17213511Sgabeblack@google.com
17313511Sgabeblack@google.com} // namespace tlm_utils
17413511Sgabeblack@google.com#endif // TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_INT_H_INCLUDED_
175