2
0

pooledmm.pp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. {
  2. $Id: header,v 1.1 2000/07/13 06:33:45 michael Exp $
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 1999-2000 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  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.
  10. **********************************************************************}
  11. {
  12. Author: Mattias Gaertner
  13. Abstract:
  14. Defines TPooledMemManager, which is the base class for various
  15. memory managers in the lcl and its interfaces.
  16. An own memory manager is somewhat faster and makes debugging and
  17. profiling easier.
  18. }
  19. unit pooledmm;
  20. {$mode objfpc}{$H+}
  21. interface
  22. uses
  23. Classes;
  24. type
  25. PPooledMemManagerItem = ^TPooledMemManagerItem;
  26. TPooledMemManagerItem = record
  27. Next: PPooledMemManagerItem;
  28. end;
  29. { memory manager template }
  30. TPooledMemManager = class
  31. private
  32. procedure SetMaxFreeRatio(NewValue: integer);
  33. procedure SetMinFree(NewValue: integer);
  34. protected
  35. FFirstFree: PPooledMemManagerItem;
  36. FFreeCount: integer;
  37. FCount: integer;
  38. FMinFree: integer;
  39. FMaxFreeRatio: integer;
  40. FAllocatedCount: int64;
  41. FFreedCount: int64;
  42. procedure DisposeItem(AnItem: PPooledMemManagerItem);
  43. function NewItem: PPooledMemManagerItem;
  44. procedure FreeFirstItem; virtual;
  45. public
  46. property MinimumFreeCount: integer read FMinFree write SetMinFree;
  47. property MaximumFreeCountRatio: integer
  48. read FMaxFreeRatio write SetMaxFreeRatio; // in one eighth steps
  49. property Count: integer read FCount;
  50. property FreeCount: integer read FFreeCount;
  51. property AllocatedCount: int64 read FAllocatedCount;
  52. property FreedCount: int64 read FFreedCount;
  53. procedure Clear;
  54. constructor Create;
  55. destructor Destroy; override;
  56. end;
  57. { TNonFreePooledMemManager - a memory manager for records without freeing }
  58. TEnumItemsMethod = procedure(Item: Pointer) of object;
  59. TNonFreePooledMemManager = class
  60. private
  61. FItemSize: integer;
  62. FItems: TFPList;
  63. FCurItem: Pointer;
  64. FEndItem: Pointer;
  65. FCurSize: integer;
  66. FFirstSize: integer;
  67. public
  68. ClearOnCreate: boolean;
  69. property ItemSize: integer read FItemSize;
  70. procedure Clear;
  71. constructor Create(TheItemSize: integer);
  72. destructor Destroy; override;
  73. function NewItem: Pointer;
  74. procedure EnumerateItems(const Method: TEnumItemsMethod);
  75. end;
  76. implementation
  77. { TPooledMemManager }
  78. procedure TPooledMemManager.Clear;
  79. begin
  80. while FFirstFree<>nil do begin
  81. FreeFirstItem;
  82. inc(FFreedCount);
  83. end;
  84. FFreeCount:=0;
  85. end;
  86. constructor TPooledMemManager.Create;
  87. begin
  88. inherited Create;
  89. FFirstFree:=nil;
  90. FFreeCount:=0;
  91. FCount:=0;
  92. FAllocatedCount:=0;
  93. FFreedCount:=0;
  94. FMinFree:=100000;
  95. FMaxFreeRatio:=8; // 1:1
  96. end;
  97. destructor TPooledMemManager.Destroy;
  98. begin
  99. Clear;
  100. inherited Destroy;
  101. end;
  102. procedure TPooledMemManager.DisposeItem(AnItem: PPooledMemManagerItem);
  103. begin
  104. if AnItem<>nil then begin
  105. if (FFreeCount<FMinFree) or (FFreeCount<((FCount shr 3)*FMaxFreeRatio)) then
  106. begin
  107. // add ANode to Free list
  108. //AddItemToFreeList(AnItem);
  109. inc(FFreeCount);
  110. end else begin
  111. // free list full -> free the ANode
  112. //FreeItem(AnItem);
  113. {$push}{$R-}
  114. inc(FFreedCount);
  115. {$pop}
  116. end;
  117. dec(FCount);
  118. end;
  119. end;
  120. function TPooledMemManager.NewItem: PPooledMemManagerItem;
  121. begin
  122. if FFirstFree<>nil then begin
  123. // take from free list
  124. Result:=FFirstFree;
  125. FFirstFree:=FFirstFree^.Next;
  126. Result^.Next:=nil;
  127. dec(FFreeCount);
  128. end else begin
  129. // free list empty -> create new node
  130. New(Result);
  131. {$push}{$R-}
  132. inc(FAllocatedCount);
  133. {$pop}
  134. end;
  135. inc(FCount);
  136. end;
  137. procedure TPooledMemManager.SetMaxFreeRatio(NewValue: integer);
  138. begin
  139. if NewValue<0 then NewValue:=0;
  140. if NewValue=FMaxFreeRatio then exit;
  141. FMaxFreeRatio:=NewValue;
  142. end;
  143. procedure TPooledMemManager.SetMinFree(NewValue: integer);
  144. begin
  145. if NewValue<0 then NewValue:=0;
  146. if NewValue=FMinFree then exit;
  147. FMinFree:=NewValue;
  148. end;
  149. procedure TPooledMemManager.FreeFirstItem;
  150. var Item: PPooledMemManagerItem;
  151. begin
  152. Item:=FFirstFree;
  153. FFirstFree:=FFirstFree^.Next;
  154. Dispose(Item);
  155. end;
  156. { TNonFreePooledMemManager }
  157. procedure TNonFreePooledMemManager.Clear;
  158. var
  159. i: Integer;
  160. p: Pointer;
  161. begin
  162. if FItems<>nil then begin
  163. for i:=0 to FItems.Count-1 do begin
  164. p:=FItems[i];
  165. FreeMem(p);
  166. end;
  167. FItems.Free;
  168. FItems:=nil;
  169. end;
  170. FCurItem:=nil;
  171. FEndItem:=nil;
  172. FCurSize:=FItemSize*4; // 4 items
  173. end;
  174. constructor TNonFreePooledMemManager.Create(TheItemSize: integer);
  175. begin
  176. FItemSize:=TheItemSize;
  177. FFirstSize:=FItemSize*4; // 4 items => the first item has 8 entries
  178. FCurSize:=FFirstSize;
  179. end;
  180. destructor TNonFreePooledMemManager.Destroy;
  181. begin
  182. Clear;
  183. inherited Destroy;
  184. end;
  185. function TNonFreePooledMemManager.NewItem: Pointer;
  186. begin
  187. if (FCurItem=FEndItem) then begin
  188. // each item has double the size of its predecessor
  189. inc(FCurSize,FCurSize);
  190. GetMem(FCurItem,FCurSize);
  191. if ClearOnCreate then
  192. FillChar(FCurItem^,FCurSize,0);
  193. if FItems=nil then FItems:=TFPList.Create;
  194. FItems.Add(FCurItem);
  195. FEndItem := FCurItem;
  196. Inc(FEndItem, FCurSize);
  197. end;
  198. Result:=FCurItem;
  199. Inc(FCurItem, FItemSize);
  200. end;
  201. procedure TNonFreePooledMemManager.EnumerateItems(
  202. const Method: TEnumItemsMethod);
  203. var
  204. Cnt: Integer;
  205. i: Integer;
  206. p: Pointer;
  207. Size: Integer;
  208. Last: Pointer;
  209. begin
  210. if FItems<>nil then begin
  211. Cnt:=FItems.Count;
  212. Size:=FFirstSize;
  213. for i:=0 to Cnt-1 do begin
  214. // each item has double the size of its predecessor
  215. inc(Size,Size);
  216. p:=FItems[i];
  217. Last := p;
  218. Inc(Last, Size);
  219. if i=Cnt-1 then
  220. Last:=FEndItem;
  221. while p<>Last do begin
  222. Method(p);
  223. Inc(p, FItemSize);
  224. end;
  225. end;
  226. end;
  227. end;
  228. end.