File indexing completed on 2025-01-18 09:58:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #ifndef G4EnhancedVecAllocator_hh
0037 #define G4EnhancedVecAllocator_hh 1
0038
0039 #include "G4Types.hh"
0040
0041 typedef struct
0042 {
0043 G4int isAllocated;
0044 char *address;
0045 } G4ChunkType;
0046
0047 typedef struct
0048 {
0049 std::size_t size;
0050 G4int totalspace;
0051 G4ChunkType *preAllocated;
0052 } G4ChunkIndexType;
0053
0054 class G4AllocStats
0055 {
0056
0057
0058
0059
0060
0061
0062 public:
0063
0064 static G4ThreadLocal G4ChunkIndexType * allocStat;
0065 static G4ThreadLocal G4int totSpace;
0066 static G4ThreadLocal G4int numCat;
0067 };
0068
0069 template<typename _Tp>
0070 class G4EnhancedVecAllocator : public std::allocator<_Tp>
0071 {
0072 public:
0073
0074 template<typename _Tp1>
0075 struct rebind { typedef G4EnhancedVecAllocator<_Tp1> other; };
0076
0077 G4EnhancedVecAllocator() {;}
0078
0079 G4EnhancedVecAllocator(const G4EnhancedVecAllocator<_Tp>&)
0080 : std::allocator<_Tp>() {;}
0081
0082 template<typename _Tp1>
0083 G4EnhancedVecAllocator(const G4EnhancedVecAllocator<_Tp1>&)
0084 : std::allocator<_Tp>() {;}
0085
0086 ~G4EnhancedVecAllocator() {;}
0087
0088
0089
0090 void deallocate(_Tp* _Ptr, std::size_t _Count);
0091 #ifdef __IBMCPP__
0092 _Tp* allocate(std::size_t _Count, void * const hint = 0);
0093 #else
0094 _Tp* allocate(std::size_t _Count);
0095 #endif
0096 };
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 template<typename _Tp>
0107 void G4EnhancedVecAllocator<_Tp>::deallocate(_Tp* _Ptr, std::size_t _Count)
0108 {
0109 G4int found = -1;
0110 if (G4AllocStats::allocStat != 0)
0111 {
0112 for (auto j = 0 ; j < G4AllocStats::numCat ; ++j)
0113 {
0114 if (G4AllocStats::allocStat[j].size == (_Count * sizeof(_Tp)))
0115 {
0116 found = j;
0117 break;
0118 }
0119 }
0120 }
0121
0122
0123 G4ChunkIndexType& chunk = G4AllocStats::allocStat[found];
0124
0125 for (auto k = 0; k < chunk.totalspace; ++k)
0126 {
0127 if ( (chunk.preAllocated[k]).address == ((char *) _Ptr))
0128 {
0129
0130 (chunk.preAllocated[k]).isAllocated = 0;
0131 return;
0132 }
0133 }
0134 }
0135
0136
0137
0138
0139
0140 #ifdef __IBMCPP__
0141 template<typename _Tp>
0142 _Tp* G4EnhancedVecAllocator<_Tp>::allocate(std::size_t _Count, void * const hint)
0143 #else
0144 template<typename _Tp>
0145 _Tp* G4EnhancedVecAllocator<_Tp>::allocate(std::size_t _Count)
0146 #endif
0147 {
0148 std::size_t totalsize = _Count * sizeof(_Tp);
0149
0150 G4int found = -1;
0151 if (G4AllocStats::allocStat != 0)
0152 {
0153 for (auto j = 0 ; j < G4AllocStats::numCat ; ++j)
0154 {
0155 if (G4AllocStats::allocStat[j].size == totalsize)
0156 {
0157 found = j;
0158 break;
0159 }
0160 }
0161 }
0162
0163 if (found == -1)
0164 {
0165 ++G4AllocStats::numCat;
0166 if (G4AllocStats::numCat > G4AllocStats::totSpace)
0167 {
0168 G4AllocStats::totSpace = G4AllocStats::totSpace + 128;
0169
0170
0171 G4AllocStats::allocStat =
0172 (G4ChunkIndexType *) realloc(G4AllocStats::allocStat,
0173 sizeof(G4ChunkIndexType) * G4AllocStats::totSpace);
0174
0175
0176
0177 }
0178
0179 G4AllocStats::allocStat[G4AllocStats::numCat-1].size = totalsize;
0180 G4AllocStats::allocStat[G4AllocStats::numCat-1].totalspace = 0;
0181 G4AllocStats::allocStat[G4AllocStats::numCat-1].preAllocated = 0;
0182
0183 found = G4AllocStats::numCat - 1;
0184 G4ChunkIndexType& chunk = G4AllocStats::allocStat[found];
0185
0186 chunk.totalspace = 512;
0187
0188
0189 chunk.preAllocated = (G4ChunkType *) realloc(chunk.preAllocated,
0190 sizeof(G4ChunkType) * chunk.totalspace);
0191
0192
0193
0194
0195 char *newSpace1 = (char *) malloc(totalsize * 512);
0196
0197
0198
0199
0200 for (auto k = 0; k < 512 ; ++k)
0201 {
0202 (chunk.preAllocated[k]).isAllocated = 0;
0203 (chunk.preAllocated[k]).address = newSpace1+totalsize*k;
0204 }
0205
0206 (chunk.preAllocated[0]).isAllocated = 1;
0207 return (_Tp*)((chunk.preAllocated[0]).address);
0208 }
0209
0210 G4ChunkIndexType& chunk = G4AllocStats::allocStat[found];
0211
0212
0213
0214 for (auto k = 0; k < chunk.totalspace; ++k)
0215 {
0216 if ((chunk.preAllocated[k]).isAllocated == 0)
0217 {
0218 (chunk.preAllocated[k]).isAllocated = 1;
0219 return (_Tp*)((chunk.preAllocated[k]).address);
0220 }
0221 }
0222
0223 G4int originalchunknumber = chunk.totalspace;
0224
0225 chunk.totalspace += 512;
0226
0227 chunk.preAllocated = (G4ChunkType *) realloc(chunk.preAllocated,
0228 sizeof(G4ChunkType) * chunk.totalspace);
0229
0230
0231
0232
0233 char *newSpace = (char *) malloc(totalsize * 512);
0234
0235
0236
0237
0238 for (auto k = 0; k < 512 ; ++k)
0239 {
0240 (chunk.preAllocated[originalchunknumber+k]).isAllocated = 0;
0241 (chunk.preAllocated[originalchunknumber+k]).address = newSpace+totalsize*k;
0242 }
0243
0244 (chunk.preAllocated[originalchunknumber]).isAllocated = 1;
0245
0246 return (_Tp*)((chunk.preAllocated[originalchunknumber]).address);
0247 }
0248
0249
0250
0251
0252
0253 template<typename _T1, typename _T2>
0254 inline G4bool operator==(const G4EnhancedVecAllocator<_T1>&,
0255 const G4EnhancedVecAllocator<_T2>&)
0256 { return true; }
0257
0258
0259
0260
0261
0262 template<typename _T1, typename _T2>
0263 inline G4bool operator!=(const G4EnhancedVecAllocator<_T1>&,
0264 const G4EnhancedVecAllocator<_T2>&)
0265 { return false; }
0266
0267 #endif