gwnavruntime/kernel/HeapPT/HeapPT_FreeBin.h Source File

HeapPT_FreeBin.h
Go to the documentation of this file.
1 /*
2 * Copyright 2015 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 /**************************************************************************
8 
9 Filename : HeapPT_FreeBin.h
10 Content :
11 Created : 2009
12 Authors : Maxim Shemanarev
13 
14 Notes : Containers to store information about free memory areas
15 
16 **************************************************************************/
17 
18 #ifndef INC_KY_Kernel_HeapPT_FreeBin_H
19 #define INC_KY_Kernel_HeapPT_FreeBin_H
20 
22 
23 namespace Kaim {
24 
25 namespace Heap { class SegVisitor; }
26 
27 namespace HeapPT {
28 
29 using namespace Heap;
30 
31 // The structure of free zones.
32 //
33 // If the size is less than Limit (see below) it's stored in "ShortSize".
34 // Otherwise, ShortSize equals to Limit, and the size is stored in UPInt,
35 // right after sizeof(BinLNode). If the size is more than Heap_MinSize,
36 // the Filler is not used. In the smallest possible free block it's used
37 // as the size at the end of the block. So that, for sizes < Limit:
38 // +----------+----------+----------+-----+-----+- - -+-----+
39 // | pPrev | pNext | pSegment |Size |Filler ... |Size |
40 // +-One-UPInt+----------+----------+-----+-----+- - -+-----+
41 //
42 // For sizes >= Limit:
43 // +----------+----------+----------+-----+-----+----------+- - -+----------+-----+-----+
44 // | pPrev | pNext | pSegment |Limit|Filler Size | ... | Size Filler|Limit|
45 // +-One-UPInt+----------+----------+-----+-----+----------+- - -+----------+-----+-----+
46 //
47 // (pPrev and pNext belong to GListNode<BinLNode>).
48 //------------------------------------------------------------------------
49 struct BinLNode
50 {
51  BinLNode* pPrev;
52  BinLNode* pNext;
53  HeapSegment* pSegment;
54  UPIntHalf ShortSize;
55  UPIntHalf Filler;
56 };
57 
58 //------------------------------------------------------------------------
59 struct BinTNode : BinLNode
60 {
61  UPInt Size;
62  BinTNode* Parent;
63  BinTNode* Child[2];
64  UPInt Index;
65 };
66 
67 
68 //------------------------------------------------------------------------
69 struct ListBin
70 {
71  enum { BinSize = 8*sizeof(UPInt) }; // Assume Byte is 8 bits.
72 
73  ListBin();
74  void Reset();
75 
76  //--------------------------------------------------------------------
77  void PushNode(UPInt idx, BinLNode* node);
78  void PullNode(UPInt idx, BinLNode* node);
79 
80  BinLNode* PullBest(UPInt idx);
81  BinLNode* PullBest(UPInt idx, UPInt blocks, UPInt shift, UPInt alignMask);
82 
83  BinLNode* FindAligned(BinLNode* root, UPInt blocks, UPInt shift, UPInt alignMask);
84 
85  static UByte* GetAlignedPtr(UByte* start, UPInt alignMask);
86  static bool AlignmentIsOK(const BinLNode* node, UPInt blocks,
87  UPInt shift, UPInt alignMask);
88 
89  //--------------------------------------------------------------------
90  UPInt Mask;
91  BinLNode* Roots[BinSize];
92 };
93 
94 
95 //------------------------------------------------------------------------
96 struct TreeBin
97 {
98  enum
99  {
100  BinSize = ListBin::BinSize,
101  SizeShift = (sizeof(void*) > 4) ? 6 : 5, // Must correspond to sizeof(void*)
102  SizeLimit = (sizeof(void*) > 4) ? 0xFFFFFFFFU : 0xFFFFU
103  };
104 
105  TreeBin();
106  void Reset();
107 
108  //--------------------------------------------------------------------
109  static UPInt ShiftForTreeIndex(UPInt i);
110  static UPInt ComputeTreeIndex(UPInt blocks);
111 
112  void PushNode(BinTNode* node);
113  void PullNode(BinTNode* node);
114  BinTNode* FindBest(UPInt size);
115  BinTNode* PullBest(UPInt size);
116 
117  const BinTNode* FindExactSize(UPInt size) const;
118 
119  //--------------------------------------------------------------------
120  UPInt Mask;
121  BinTNode* Roots[BinSize];
122 };
123 
124 
125 
126 //------------------------------------------------------------------------
127 class FreeBin
128 {
129 public:
130  enum { BinSize = ListBin::BinSize };
131 
132  FreeBin();
133  void Reset();
134 
135  //--------------------------------------------------------------------
136  KY_INLINE static
137  UInt32* GetBitSet(const HeapSegment* seg)
138  {
139  return (UInt32*)(((UByte*)seg) + sizeof(HeapSegment));
140  }
141 
142  //--------------------------------------------------------------------
143  KY_INLINE static
144  UPInt GetSize(const void* node)
145  {
146  UPInt size = ((const BinLNode*)node)->ShortSize;
147  if (size < BinSize+1)
148  {
149  return size;
150  }
151  return *(const UPInt*)((const UByte*)node + sizeof(BinLNode));
152  }
153 
154  //--------------------------------------------------------------------
155  KY_INLINE static
156  UPInt GetBytes(const void* node, UPInt shift)
157  {
158  return GetSize(node) << shift;
159  }
160 
161  //--------------------------------------------------------------------
162  KY_INLINE static
163  void SetSize(UByte* node, UPInt blocks, UPInt shift)
164  {
165  UPInt bytes = blocks << shift;
166  BinLNode* listNode = (BinLNode*)node;
167  if (blocks < BinSize+1)
168  {
169  listNode->ShortSize =
170  *(UPIntHalf*)(node + bytes - sizeof(UPIntHalf)) = UPIntHalf(blocks);
171  }
172  else
173  {
174  listNode->ShortSize =
175  *(UPIntHalf*)(node + bytes - sizeof(UPIntHalf)) = UPIntHalf(BinSize+1);
176 
177  *(UPInt*)(node + sizeof(BinLNode)) =
178  *(UPInt*)(node + bytes - 2*sizeof(UPInt)) = blocks;
179  }
180  }
181 
182  //--------------------------------------------------------------------
183  KY_INLINE static void
184  MakeNode(HeapSegment* seg, UByte* data, UPInt blocks, UPInt shift)
185  {
186  SetSize(data, blocks, shift);
187  ((BinLNode*)data)->pSegment = seg;
188 #ifdef KY_MEMORY_CHECK_CORRUPTION
189  MemsetNode((BinLNode*)data, shift);
190 #endif
191  }
192 
193  //--------------------------------------------------------------------
194  UByte* PullBest(UPInt blocks);
195  UByte* PullBest(UPInt blocks, UPInt shift, UPInt alignMask);
196 
197  //--------------------------------------------------------------------
198  void Push(UByte* node); // Node must be initialized!
199  KY_INLINE void Push(HeapSegment* seg, UByte* node,
200  UPInt blocks, UPInt shift)
201  {
202  MakeNode(seg, node, blocks, shift);
203  Push(node);
204  }
205 
206  //--------------------------------------------------------------------
207  void Pull(UByte* node);
208  void Merge(UByte* node, UPInt shift, bool left, bool right);
209 
210  UPInt GetTotalFreeSpace(UPInt shift) const
211  {
212  return FreeBlocks << shift;
213  }
214 
215  //--------------------------------------------------------------------
216  void VisitMem(MemVisitor* visitor, UPInt shift,
217  MemVisitor::Category cat) const;
218 
219  void VisitUnused(SegVisitor* visitor, UPInt shift, unsigned cat) const;
220 
221  void CheckIntegrity(UPInt shift) const;
222 
223 #ifdef KY_MEMORY_CHECK_CORRUPTION
224  static void CheckArea(const void* area, UPInt bytes);
225  static void MemsetNode(BinLNode* node, UPInt shift);
226  static void CheckNode(const BinLNode* node, UPInt shift);
227 #endif
228 
229 
230 private:
231  static void compilerAsserts(); // A fake function used for GCOMPILER_ASSERTS only
232 
233  static BinLNode* getPrevAdjacent(UByte* node, UPInt shift);
234  static BinLNode* getNextAdjacent(UByte* node, UPInt shift);
235 
236  void visitTree(const BinTNode* root, MemVisitor* visitor,
237  UPInt shift, MemVisitor::Category cat) const;
238 
239  void visitUnusedNode(const BinLNode* node,
240  SegVisitor* visitor,
241  UPInt shift, unsigned cat) const;
242 
243  void visitUnusedInTree(const BinTNode* root,
244  SegVisitor* visitor,
245  UPInt shift, unsigned cat) const;
246 
247  void checkBlockIntegrity(const BinLNode* node, UPInt shift) const;
248  void checkTreeIntegrity(const BinTNode* root, UPInt shift) const;
249 
250  ListBin ListBin1;
251  ListBin ListBin2;
252  TreeBin TreeBin1;
253  UPInt FreeBlocks;
254 };
255 
256 }} // Kaim::Heap
257 
258 #endif
Definition: gamekitcrowddispersion.h:20