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, version 3 of the License ONLY.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *)
15 {$INCLUDE a_modes.inc}
16 {$DEFINE MEM_DISABLE_ACCOUNTING}
19 interface
21 {$IFDEF USE_MEMPOOL}
22 uses
23 SysUtils;
26 type
29 private
37 public
46 public
54 {$IF DEFINED(D2F_DEBUG) and NOT DEFINED(MEM_DISABLE_ACCOUNTING)}
57 {$ENDIF}
59 {$ENDIF}
61 (* Simple "mark/release" allocator *)
62 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()`!
97 type
99 public
103 private
110 public
111 constructor Create (var apool: TPoolMarkRelease); // idiotic FPC doesn't support arg-less ctors for rectord
124 public
129 var
133 implementation
135 uses
136 SysUtils
137 {$IFDEF USE_MEMPOOL}
138 , hashtable
139 {$ENDIF}
140 ;
143 // ////////////////////////////////////////////////////////////////////////// //
145 begin
147 begin
150 end
151 else
152 begin
160 // free all allocated memory
162 begin
170 // forget everything
172 begin
177 // mark current position
179 begin
184 // forget everything from the given mark
186 begin
187 if (amark < 0) or (amark > mUsed) then raise Exception.Create('MarkReleasePool is fucked (release)');
192 // allocate some memory
193 // WARNING! pool can realloc it's internal storage and invalidate all previous pointers!
195 begin
196 if (size < 0) then raise Exception.Create('MarkReleasePool: cannot allocate negative amount of bytes');
197 if (size > 1024*1024) then raise Exception.Create('MarkReleasePool: why do you need to allocate more than 1MB?');
198 // do we need to get more memory?
200 begin
201 if (mUsed+size > 1024*1024*64) then raise Exception.Create('MarkReleasePool: more than 64MB in MarkReleasePool is insanity!');
203 begin
204 // less than 256KB: 64KB steps
206 // less than 1MB: 128KB steps
208 // otherwise, 1MB steps
220 // get pointer for the given mark
221 // WARNING! pointer can become invalid after next call to `alloc()`!
223 begin
224 if (amark < 0) or (amark > mUsed) then raise Exception.Create('MarkReleasePool is fucked (getPtr)');
230 begin
236 // ////////////////////////////////////////////////////////////////////////// //
238 begin
248 begin
258 begin
265 begin
266 //if (mCurrent+1 >= 0) and (mCurrent+1 < mCount) then result := mCount-(mCurrent+1) else result := 0;
272 begin
283 begin
292 begin
294 if (mCurrent < 0) or (mCurrent >= mCount) then raise Exception.Create('getCurrent() range error');
300 begin
306 begin
313 // ////////////////////////////////////////////////////////////////////////// //
314 {$IFDEF USE_MEMPOOL}
315 uses
316 hashtable;
318 type
320 public
326 THashPtrPtr = specialize THashBase<Pointer, PMemPool, THashKeyPtr>; // key: TClass; value: PMemPool
328 var
332 // ////////////////////////////////////////////////////////////////////////// //
333 class function THashKeyPtr.hash (const k: Pointer): LongWord; inline; begin result := fnvHash(PByte(@k)^, sizeof(k)); end;
334 class function THashKeyPtr.equ (const a, b: Pointer): Boolean; inline; begin result := (a = b); end;
339 begin
342 begin
350 // ////////////////////////////////////////////////////////////////////////// //
352 begin
363 procedure TMemPool.setCapacity (acount: Integer); // ensure capacity for at least `acount` objects
364 begin
369 begin
374 begin
384 begin
389 // ////////////////////////////////////////////////////////////////////////// //
390 {$IF DEFINED(D2F_DEBUG) and NOT DEFINED(MEM_DISABLE_ACCOUNTING)}
392 var
393 {$IF DEFINED(D2F_DEBUG) and NOT DEFINED(MEM_DISABLE_ACCOUNTING)}
395 {$ENDIF}
397 begin
398 {$IF DEFINED(D2F_DEBUG) and NOT DEFINED(MEM_DISABLE_ACCOUNTING)}
401 {$ELSE}
404 {$ENDIF}
411 var
413 begin
417 {$ENDIF}
420 // ////////////////////////////////////////////////////////////////////////// //
421 {$IF DEFINED(D2F_DEBUG) and NOT DEFINED(MEM_DISABLE_ACCOUNTING)}
423 var
426 begin
430 begin
435 {$ENDIF}
438 initialization
439 //mpoolMap := TMemPool.Create('textmap', 64);
441 finalization
442 {$IF DEFINED(D2F_DEBUG) and NOT DEFINED(MEM_DISABLE_ACCOUNTING)}
444 {$ENDIF}