TLM-2.0  2.0.4
Accellera TLM-2.0 proof-of-concept library
instance_specific_extensions.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements. See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License. You may obtain a copy of the License at
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied. See the License for the specific language governing
16  permissions and limitations under the License.
17 
18  *****************************************************************************/
19 
20 /*
21 Instance specific extensions, are extension that only a single instance of a module
22 may access. They are invisible to all other modules; they are private to this
23 instance so to speak.
24 
25 As they are only of value to a certain instance, this instance knows very well
26 when it needs them and when it does not need them any longer (usually when
27 a transaction passes through a module for the last time).
28 It does not have to care if anyone else in the system may still have a
29 reference to the transaction as this one is not able to access the extension
30 anyway.
31 Therefore the instance is obliged to call set_extension when it wants to add a
32 private extension and clear_extension when it does not need it any more.
33 
34 To get access to an instance specifc extension the module must own a so called
35 instance_specific_extension_accessor that provides the exclusive access rights.
36 Assuming the instance_specific_extension_accessor of a given module is called m_accessor
37 and the transaction of which the private extension is about to be accessed
38 is called txn, then the calls have to be
39 
40 m_accessor(txn).set_extension(...);
41 or
42 m_accessor(txn).clear_extension(...);
43 
44 The owner of the private extension is responsible to allocate/deallocate
45 the extension before/after setting/clearing the extension.
46 */
47 
48 #ifndef TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_H_INCLUDED_
49 #define TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_H_INCLUDED_
50 
52 
53 namespace tlm_utils {
54 
55 //The templated private extension. Similar to normal extension
56 template <typename T>
58 public:
60  const static unsigned int priv_id;
61 };
62 
63 template <typename T>
66 
67 // ----------------------------------------------------------------------------
68 
69 // This is the class that actually sits in the extension array
70 // - we keep this small since that one gets allocated and deallocated all the times
71 // - we keep the implementation in the header to avoid registration
72 // of the extension itself unless used in the model
74  : public tlm::tlm_extension<instance_specific_extension_carrier>
75 {
77 public:
79  : m_container()
80  {}
81 
82  virtual tlm::tlm_extension_base* clone() const {
83  //we don't clone since private info is instance specific and associated to a given txn (the original)
84  //so the deep copied txn will be virgin in terms of private info
85  return NULL;
86  }
87 
88  void copy_from(tlm::tlm_extension_base const &) { return; }
89  void free() { return; }
90 
91 private:
93 };
94 
95 // ----------------------------------------------------------------------------
96 
97 template<typename T>
100 {
101  instance_specific_extension_carrier* carrier = NULL;
102  txn.get_extension(carrier);
103  if (!carrier) {
104  carrier = new instance_specific_extension_carrier();
105  carrier->m_container = instance_specific_extension_container::create();
106  carrier->m_container->attach_carrier(carrier, &txn, &release_carrier<T>);
107  txn.set_extension(carrier);
108  }
109  return *carrier->m_container->get_accessor(m_index);
110 }
111 
112 template<typename T>
113 void
116 {
117  T* typed_txn = static_cast<T*>(txn);
118  typed_txn->clear_extension(carrier);
119  delete carrier;
120 }
121 
122 } // namespace tlm_utils
123 
124 #endif // TLM_UTILS_INSTANCE_SPECIFIC_EXTENSIONS_H_INCLUDED_
instance_specific_extensions_per_accessor & operator()(T &txn)
static void release_carrier(instance_specific_extension_carrier *, void *txn)
virtual tlm::tlm_extension_base * clone() const
static unsigned int register_private_extension(const std::type_info &)