Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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//
27// $Id$
28//
29//
30// ------------------------------------------------------------
31// GEANT 4 class header file
32//
33// Class Description:
34//
35// A class for fast allocation of STL vectors through a static pool.
36// It's meant to be used as alternative allocator for STL vectors.
37
38// ---------------- G4EnhancedVecAllocator ----------------
39//
40// Original author: X.Dong (NorthEastern Univ.), November 2009
41// Reviewed implementation: G.Cosmo (CERN), December 2009
42// ------------------------------------------------------------
43
44#ifndef G4EnhancedVecAllocator_h
45#define G4EnhancedVecAllocator_h 1
46
47#include "G4Types.hh"
48
49// #include <cstdlib>
50
51typedef struct
52{
54 char *address;
56
57typedef struct
58{
59 size_t size;
63
65{
66 // --------------------------------------------------------------------
67 // Utility class, placeholder for global data on allocation.
68 // Initialisation to zero of the data below *must* be added ONCE only
69 // directly in the client code, where this allocator is to be applied
70 // --------------------------------------------------------------------
71
72 public:
73
76 static G4int numCat;
77};
78
79template<typename _Tp>
80class G4EnhancedVecAllocator : public std::allocator<_Tp>
81{
82 public:
83
84 template<typename _Tp1>
86
88
90 : std::allocator<_Tp>() {;}
91
92 template<typename _Tp1>
94 : std::allocator<_Tp>() {;}
95
97
98 // override allocate / deallocate
99 //
100 void deallocate(_Tp* _Ptr, size_t _Count);
101#ifdef __IBMCPP__
102 _Tp* allocate(size_t _Count, void * const hint = 0); // IBM AIX
103#else
104 _Tp* allocate(size_t _Count);
105#endif
106};
107
108// ------------------------------------------------------------
109// Inline implementations
110// ------------------------------------------------------------
111
112// ************************************************************
113// deallocate
114// ************************************************************
115//
116template<typename _Tp>
117void G4EnhancedVecAllocator<_Tp>::deallocate(_Tp* _Ptr, size_t _Count)
118{
119 G4int found = -1;
120 for (register int j = 0 ; j < G4AllocStats::numCat ; j++)
121 {
122 if ( (G4AllocStats::allocStat != 0)
123 && (G4AllocStats::allocStat[j].size == (_Count * sizeof(_Tp))))
124 {
125 found = j;
126 break;
127 }
128 }
129 // assert(found != -1);
130
131 for (register int k = 0; k < G4AllocStats::allocStat[found].totalspace; k++)
132 {
133 if ( ((G4AllocStats::allocStat[found]).preAllocated[k]).address
134 == ((char *) _Ptr))
135 {
136 // assert(((G4AllocStats::allocStat[found]).preAllocated[k]).isAllocated==1);
137 ((G4AllocStats::allocStat[found]).preAllocated[k]).isAllocated = 0;
138 return;
139 }
140 }
141}
142
143// ************************************************************
144// allocate
145// ************************************************************
146//
147#ifdef __IBMCPP__
148template<typename _Tp>
149_Tp* G4EnhancedVecAllocator<_Tp>::allocate(size_t _Count, void * const hint)
150#else
151template<typename _Tp>
153#endif
154{
155 size_t totalsize = _Count * sizeof(_Tp);
156
157 G4int found = -1;
158 for (register int j = 0 ; j < G4AllocStats::numCat ; j++)
159 {
160 if ( (G4AllocStats::allocStat != 0)
161 && (G4AllocStats::allocStat[j].size == totalsize) )
162 {
163 found = j;
164 break;
165 }
166 }
167
168 if (found == -1) // Find the new size
169 {
172 {
174 // heuristic parameter for different sizes
175
179 // This value must be different than zero; otherwise means
180 // failure in allocating extra space !
181 // assert(G4AllocStats::allocStat != 0);
182 }
183
187
188 found = G4AllocStats::numCat - 1;
189
191 // heuristic for the number of STL vector instances
192
194 (G4ChunkType *) realloc(G4AllocStats::allocStat[found].preAllocated,
196 // This value must be different than zero; otherwise means
197 // failure in allocating extra space for pointers !
198 // assert(G4AllocStats::allocStat[found].preAllocated != 0);
199
200 char *newSpace1 = (char *) malloc(totalsize * 512);
201 // This pointer must be different than zero; otherwise means
202 // failure in allocating extra space for instances !
203 // assert(newSpace1 != 0);
204
205 for (register int k = 0; k < 512 ; k++)
206 {
207 ((G4AllocStats::allocStat[found]).preAllocated[k]).isAllocated = 0;
208 ((G4AllocStats::allocStat[found]).preAllocated[k]).address =
209 newSpace1+totalsize*k;
210 }
211
212 ((G4AllocStats::allocStat[found]).preAllocated[0]).isAllocated = 1;
213 return (_Tp*)(((G4AllocStats::allocStat[found]).preAllocated[0]).address);
214 }
215
216 // assert(G4AllocStats::allocStat[found].size == totalsize);
217
218 for (register int k = 0; k < G4AllocStats::allocStat[found].totalspace; k++)
219 {
220 if (((G4AllocStats::allocStat[found]).preAllocated[k]).isAllocated == 0)
221 {
222 ((G4AllocStats::allocStat[found]).preAllocated[k]).isAllocated = 1;
223 return (_Tp*)(((G4AllocStats::allocStat[found]).preAllocated[k]).address);
224 }
225 }
226
227 G4int originalchunknumber = G4AllocStats::allocStat[found].totalspace;
228
229 G4AllocStats::allocStat[found].totalspace = // heuristic for the number
230 G4AllocStats::allocStat[found].totalspace+512; // of STL vector instances
231
233 (G4ChunkType *) realloc(G4AllocStats::allocStat[found].preAllocated,
235 // This value must be different than zero; otherwise means
236 // failure in allocating extra space for pointers !
237 // assert(G4AllocStats::allocStat[found].preAllocated != 0);
238
239 char *newSpace = (char *) malloc(totalsize * 512);
240 // This pointer must be different than zero; otherwise means
241 // failure in allocating extra space for instances !
242 // assert(newSpace != 0);
243
244 for (register int k = 0; k < 512 ; k++)
245 {
246 ((G4AllocStats::allocStat[found]).
247 preAllocated[originalchunknumber + k]).isAllocated= 0;
248 ((G4AllocStats::allocStat[found]).
249 preAllocated[originalchunknumber + k]).address= newSpace+totalsize*k;
250 }
251
252 ((G4AllocStats::allocStat[found]).preAllocated[originalchunknumber])
253 .isAllocated = 1;
254
255 return (_Tp*)(((G4AllocStats::allocStat[found]).
256 preAllocated[originalchunknumber]).address);
257}
258
259// ************************************************************
260// operator==
261// ************************************************************
262//
263template<typename _T1, typename _T2>
266{ return true; }
267
268// ************************************************************
269// operator!=
270// ************************************************************
271//
272template<typename _T1, typename _T2>
275{ return false; }
276
277#endif
bool operator==(const G4EnhancedVecAllocator< _T1 > &, const G4EnhancedVecAllocator< _T2 > &)
bool operator!=(const G4EnhancedVecAllocator< _T1 > &, const G4EnhancedVecAllocator< _T2 > &)
int G4int
Definition: G4Types.hh:66
static G4ChunkIndexType * allocStat
_Tp * allocate(size_t _Count)
void deallocate(_Tp *_Ptr, size_t _Count)
G4EnhancedVecAllocator(const G4EnhancedVecAllocator< _Tp > &)
G4EnhancedVecAllocator(const G4EnhancedVecAllocator< _Tp1 > &)
G4EnhancedVecAllocator< _Tp1 > other