1 (* Copyright (C) Doom 2D: Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 {$INCLUDE a_modes.inc}
17 {$DEFINE MEM_DISABLE_ACCOUNTING}
20 interface
22 {$IFDEF USE_MEMPOOL}
23 uses
24 SysUtils;
27 type
30 private
38 public
47 public
55 {$IF DEFINED(D2F_DEBUG) and NOT DEFINED(MEM_DISABLE_ACCOUNTING)}
58 {$ENDIF}
60 {$ENDIF}
62 (* Simple "mark/release" allocator *)
63 type
67 private
72 public
75 // free all allocated memory
78 // forget everything
81 // mark current position
83 // forget everything from the given mark
86 // allocate some memory
87 // WARNING! pool can realloc it's internal storage and invalidate all previous pointers!
90 // get pointer for the given mark
91 // WARNING! pointer can become invalid after next call to `alloc()`!
96 var
100 implementation
102 uses
103 SysUtils
104 {$IFDEF USE_MEMPOOL}
105 , hashtable
106 {$ENDIF}
107 ;
110 // ////////////////////////////////////////////////////////////////////////// //
112 begin
114 begin
117 end
118 else
119 begin
127 // free all allocated memory
129 begin
137 // forget everything
139 begin
144 // mark current position
146 begin
151 // forget everything from the given mark
153 begin
154 if (amark < 0) or (amark > mUsed) then raise Exception.Create('MarkReleasePool is fucked (release)');
159 // allocate some memory
160 // WARNING! pool can realloc it's internal storage and invalidate all previous pointers!
162 begin
163 if (size < 0) then raise Exception.Create('MarkReleasePool: cannot allocate negative amount of bytes');
164 if (size > 1024*1024) then raise Exception.Create('MarkReleasePool: why do you need to allocate more than 1MB?');
165 // do we need to get more memory?
167 begin
168 if (mUsed+size > 1024*1024*64) then raise Exception.Create('MarkReleasePool: more than 64MB in MarkReleasePool is insanity!');
170 begin
171 // less than 256KB: 64KB steps
173 // less than 1MB: 128KB steps
175 // otherwise, 1MB steps
187 // get pointer for the given mark
188 // WARNING! pointer can become invalid after next call to `alloc()`!
190 begin
191 if (amark < 0) or (amark > mUsed) then raise Exception.Create('MarkReleasePool is fucked (getPtr)');
196 // ////////////////////////////////////////////////////////////////////////// //
197 {$IFDEF USE_MEMPOOL}
198 uses
199 hashtable;
201 type
203 public
209 THashPtrPtr = specialize THashBase<Pointer, PMemPool, THashKeyPtr>; // key: TClass; value: PMemPool
211 var
215 // ////////////////////////////////////////////////////////////////////////// //
216 class function THashKeyPtr.hash (const k: Pointer): LongWord; inline; begin result := fnvHash(PByte(@k)^, sizeof(k)); end;
217 class function THashKeyPtr.equ (const a, b: Pointer): Boolean; inline; begin result := (a = b); end;
222 begin
225 begin
233 // ////////////////////////////////////////////////////////////////////////// //
235 begin
246 procedure TMemPool.setCapacity (acount: Integer); // ensure capacity for at least `acount` objects
247 begin
252 begin
257 begin
267 begin
272 // ////////////////////////////////////////////////////////////////////////// //
273 {$IF DEFINED(D2F_DEBUG) and NOT DEFINED(MEM_DISABLE_ACCOUNTING)}
275 var
276 {$IF DEFINED(D2F_DEBUG) and NOT DEFINED(MEM_DISABLE_ACCOUNTING)}
278 {$ENDIF}
280 begin
281 {$IF DEFINED(D2F_DEBUG) and NOT DEFINED(MEM_DISABLE_ACCOUNTING)}
284 {$ELSE}
287 {$ENDIF}
294 var
296 begin
300 {$ENDIF}
303 // ////////////////////////////////////////////////////////////////////////// //
304 {$IF DEFINED(D2F_DEBUG) and NOT DEFINED(MEM_DISABLE_ACCOUNTING)}
306 var
309 begin
313 begin
318 {$ENDIF}
321 initialization
322 //mpoolMap := TMemPool.Create('textmap', 64);
324 finalization
325 {$IF DEFINED(D2F_DEBUG) and NOT DEFINED(MEM_DISABLE_ACCOUNTING)}
327 {$ENDIF}