gem5  v22.1.0.0
instance_specific_extensions.cc
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 #include <tlm_utils/instance_specific_extensions_int.h>
21 
22 #include <iostream>
23 #include <map>
24 #include <typeindex>
25 
26 namespace tlm
27 {
28 
29 template class tlm_array<tlm_utils::ispex_base *>;
30 
31 } // namespace tlm
32 
33 namespace tlm_utils
34 {
35 
36 namespace
37 {
38 
39 class ispex_registry // Copied from tlm_gp.cpp.
40 {
41  typedef unsigned int key_type;
42  typedef std::map<std::type_index, key_type> type_map;
43 
44  public:
45  static ispex_registry &
46  instance()
47  {
48  if (!instance_) {
49  // Don't cleanup registry.
50  instance_ = new ispex_registry();
51  }
52  return *instance_;
53  }
54 
55  unsigned int
56  register_extension(std::type_index type)
57  {
58  type_map::const_iterator it = ids_.find(type);
59 
60  if (it == ids_.end()) {
61  // New extension - generate/store ID.
62  type_map::value_type v(type, static_cast<key_type>(ids_.size()));
63  ids_.insert(v);
64  return v.second;
65  }
66  return it->second;
67  }
68 
69  static unsigned int
71  {
72  return (instance_) ? instance().ids_.size() : 0;
73  }
74 
75  private:
76  static ispex_registry *instance_;
77  type_map ids_;
78  ispex_registry() {}
79 };
80 
81 ispex_registry *ispex_registry::instance_ = nullptr;
82 
83 } // anonymous namespace
84 
85 unsigned int
86 ispex_base::register_private_extension(const std::type_info &type)
87 {
88  return ispex_registry::instance().register_extension(type);
89 }
90 
91 // Helper to do the numbering of private extension accessors.
92 static unsigned int
93 max_num_ispex_accessors(bool increment=false)
94 {
95  static unsigned int max_num = 0;
96  if (increment)
97  ++max_num;
98  return max_num;
99 }
100 
101 // ----------------------------------------------------------------------------
102 
103 // The pool for the container, plain as can be.
105 {
108 
109  public:
112  {
114  return inst;
115  }
116 
119 
120  private:
122 };
123 
125 instance_specific_extension_container_pool::create()
126 {
127  if (!unused) {
129  }
131  unused = unused->next;
132  return tmp;
133 }
134 
135 void
136 instance_specific_extension_container_pool::free(
138 {
139  cont->next = unused;
140  unused = cont;
141 }
142 
143 instance_specific_extension_container_pool::
144  ~instance_specific_extension_container_pool()
145 {
146  while (unused) {
148  unused = unused->next;
149  delete tmp;
150  }
151 }
152 
153 // ----------------------------------------------------------------------------
154 
156 instance_specific_extension_container::create()
157 {
158  return instance_specific_extension_container_pool::instance().create();
159 }
160 
161 instance_specific_extension_container::
162  instance_specific_extension_container() :
163  use_count(0), m_txn(NULL), m_release_fn(NULL), m_carrier(NULL), next(NULL)
164 {
165  resize();
166 }
167 
168 void
171  void *txn, release_fn *rel_fn)
172 {
173  m_txn = txn;
174  m_release_fn = rel_fn;
175  m_carrier = carrier;
176 }
177 
178 void
180 {
182 
183  for (unsigned int i = 0; i < m_ispex_per_accessor.size(); ++i) {
186  m_ispex_per_accessor[i]->resize_extensions();
187  }
188 }
189 
192 {
193  for (unsigned int i = 0; i < m_ispex_per_accessor.size(); ++i)
194  delete m_ispex_per_accessor[i];
195 }
196 
197 void
199 {
200  use_count++;
201 }
202 
203 void
205 {
206  if ((--use_count) == 0) {
207  // If this container isn't used any more we release the carrier
208  // extension.
210  // We send it back to our pool.
212  }
213 }
214 
217 {
218  return m_ispex_per_accessor[idx];
219 }
220 
221 // ----------------------------------------------------------------------------
222 
223 // non-templatized version with manual index:
224 ispex_base *
226  unsigned int index, ispex_base *ext)
227 {
229  ispex_base *tmp = m_extensions[index];
231  if (!tmp && ext)
233  return tmp;
234 }
235 
236 ispex_base *
238  unsigned int index) const
239 {
240  return (index < m_extensions.size()) ? m_extensions[index] : nullptr;
241 }
242 
243 void
245 {
246  if (index < m_extensions.size()) {
247  if (m_extensions[index])
249  m_extensions[index] = static_cast<ispex_base *>(nullptr);
250  }
251 }
252 
253 void
255 {
257 }
258 
259 // ----------------------------------------------------------------------------
260 
262  m_index(max_num_ispex_accessors(true) - 1)
263 {}
264 
265 } // namespace tlm_utils
static instance_specific_extension_container_pool & instance()
std::vector< instance_specific_extensions_per_accessor * > m_ispex_per_accessor
void attach_carrier(instance_specific_extension_carrier *, void *txn, release_fn *)
instance_specific_extensions_per_accessor * get_accessor(unsigned int index)
static instance_specific_extension_container * create()
static ispex_registry * instance_
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 12 > ext
Definition: misc_types.hh:434
Bitfield< 30, 0 > index
Bitfield< 0 > v
Definition: pagetable.hh:65
static unsigned int max_num_ispex_accessors(bool increment=false)
unsigned int max_num_extensions()
Definition: gp.cc:85

Generated on Wed Dec 21 2022 10:22:50 for gem5 by doxygen 1.9.1