Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4EnhancedVecAllocator.hh
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// Class Description:
27//
28// A class for fast allocation of STL vectors through a static pool.
29// It's meant to be used as alternative allocator for STL vectors.
30
31// ---------------- G4EnhancedVecAllocator ----------------
32//
33// Original author: X.Dong (NorthEastern Univ.), November 2009
34// Reviewed implementation: G.Cosmo (CERN), December 2009
35// ------------------------------------------------------------
36#ifndef G4EnhancedVecAllocator_hh
37#define G4EnhancedVecAllocator_hh 1
38
39#include "G4Types.hh"
40
41typedef struct
42{
44 char *address;
46
53
55{
56 // --------------------------------------------------------------------
57 // Utility class, placeholder for global data on allocation.
58 // Initialisation to zero of the data below *must* be added ONCE only
59 // directly in the client code, where this allocator is to be applied
60 // --------------------------------------------------------------------
61
62 public:
63
67};
68
69template<typename _Tp>
70class G4EnhancedVecAllocator : public std::allocator<_Tp>
71{
72 public:
73
74 template<typename _Tp1>
76
78
80 : std::allocator<_Tp>() {;}
81
82 template<typename _Tp1>
84 : std::allocator<_Tp>() {;}
85
87
88 // override allocate / deallocate
89 //
90 void deallocate(_Tp* _Ptr, std::size_t _Count);
91#ifdef __IBMCPP__
92 _Tp* allocate(std::size_t _Count, void * const hint = 0); // IBM AIX
93#else
94 _Tp* allocate(std::size_t _Count);
95#endif
96};
97
98// ------------------------------------------------------------
99// Inline implementations
100// ------------------------------------------------------------
101
102// ************************************************************
103// deallocate
104// ************************************************************
105//
106template<typename _Tp>
107void G4EnhancedVecAllocator<_Tp>::deallocate(_Tp* _Ptr, std::size_t _Count)
108{
109 G4int found = -1;
111 {
112 for (auto j = 0 ; j < G4AllocStats::numCat ; ++j)
113 {
114 if (G4AllocStats::allocStat[j].size == (_Count * sizeof(_Tp)))
115 {
116 found = j;
117 break;
118 }
119 }
120 }
121 // assert(found != -1);
122
124
125 for (auto k = 0; k < chunk.totalspace; ++k)
126 {
127 if ( (chunk.preAllocated[k]).address == ((char *) _Ptr))
128 {
129 // assert((chunk.preAllocated[k]).isAllocated==1);
130 (chunk.preAllocated[k]).isAllocated = 0;
131 return;
132 }
133 }
134}
135
136// ************************************************************
137// allocate
138// ************************************************************
139//
140#ifdef __IBMCPP__
141template<typename _Tp>
142_Tp* G4EnhancedVecAllocator<_Tp>::allocate(std::size_t _Count, void * const hint)
143#else
144template<typename _Tp>
146#endif
147{
148 std::size_t totalsize = _Count * sizeof(_Tp);
149
150 G4int found = -1;
152 {
153 for (auto j = 0 ; j < G4AllocStats::numCat ; ++j)
154 {
155 if (G4AllocStats::allocStat[j].size == totalsize)
156 {
157 found = j;
158 break;
159 }
160 }
161 }
162
163 if (found == -1) // Find the new size
164 {
167 {
169 // heuristic parameter for different sizes
170
174 // This value must be different than zero; otherwise means
175 // failure in allocating extra space !
176 // assert(G4AllocStats::allocStat != 0);
177 }
178
182
183 found = G4AllocStats::numCat - 1;
185
186 chunk.totalspace = 512;
187 // heuristic for the number of STL vector instances
188
189 chunk.preAllocated = (G4ChunkType *) realloc(chunk.preAllocated,
190 sizeof(G4ChunkType) * chunk.totalspace);
191 // This value must be different than zero; otherwise means
192 // failure in allocating extra space for pointers !
193 // assert(chunk.preAllocated != 0);
194
195 char *newSpace1 = (char *) malloc(totalsize * 512);
196 // This pointer must be different than zero; otherwise means
197 // failure in allocating extra space for instances !
198 // assert(newSpace1 != 0);
199
200 for (auto k = 0; k < 512 ; ++k)
201 {
202 (chunk.preAllocated[k]).isAllocated = 0;
203 (chunk.preAllocated[k]).address = newSpace1+totalsize*k;
204 }
205
206 (chunk.preAllocated[0]).isAllocated = 1;
207 return (_Tp*)((chunk.preAllocated[0]).address);
208 }
209
211
212 // assert(chunk.size == totalsize);
213
214 for (auto k = 0; k < chunk.totalspace; ++k)
215 {
216 if ((chunk.preAllocated[k]).isAllocated == 0)
217 {
218 (chunk.preAllocated[k]).isAllocated = 1;
219 return (_Tp*)((chunk.preAllocated[k]).address);
220 }
221 }
222
223 G4int originalchunknumber = chunk.totalspace;
224
225 chunk.totalspace += 512; // heuristic for the number of STL vector instances
226
227 chunk.preAllocated = (G4ChunkType *) realloc(chunk.preAllocated,
228 sizeof(G4ChunkType) * chunk.totalspace);
229 // This value must be different than zero; otherwise means
230 // failure in allocating extra space for pointers !
231 // assert(chunk.preAllocated != 0);
232
233 char *newSpace = (char *) malloc(totalsize * 512);
234 // This pointer must be different than zero; otherwise means
235 // failure in allocating extra space for instances !
236 // assert(newSpace != 0);
237
238 for (auto k = 0; k < 512 ; ++k)
239 {
240 (chunk.preAllocated[originalchunknumber+k]).isAllocated = 0;
241 (chunk.preAllocated[originalchunknumber+k]).address = newSpace+totalsize*k;
242 }
243
244 (chunk.preAllocated[originalchunknumber]).isAllocated = 1;
245
246 return (_Tp*)((chunk.preAllocated[originalchunknumber]).address);
247}
248
249// ************************************************************
250// operator==
251// ************************************************************
252//
253template<typename _T1, typename _T2>
256{ return true; }
257
258// ************************************************************
259// operator!=
260// ************************************************************
261//
262template<typename _T1, typename _T2>
265{ return false; }
266
267#endif
G4bool operator!=(const G4EnhancedVecAllocator< _T1 > &, const G4EnhancedVecAllocator< _T2 > &)
G4bool operator==(const G4EnhancedVecAllocator< _T1 > &, const G4EnhancedVecAllocator< _T2 > &)
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
static G4ThreadLocal G4int totSpace
static G4ThreadLocal G4ChunkIndexType * allocStat
static G4ThreadLocal G4int numCat
void deallocate(_Tp *_Ptr, std::size_t _Count)
_Tp * allocate(std::size_t _Count)
G4EnhancedVecAllocator(const G4EnhancedVecAllocator< _Tp > &)
G4EnhancedVecAllocator(const G4EnhancedVecAllocator< _Tp1 > &)
G4EnhancedVecAllocator< _Tp1 > other
#define G4ThreadLocal
Definition tls.hh:77