gwnavruntime/kernel/HeapPT/HeapPT_Root.h Source File

HeapPT_Root.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_Root.h
10 Content : Heap root used for bootstrapping and bookkeeping.
11  :
12 Created : 2009
13 Authors : Maxim Shemanarev
14 
15 **************************************************************************/
16 
17 #ifndef INC_KY_Kernel_HeapPT_Root_H
18 #define INC_KY_Kernel_HeapPT_Root_H
19 
23 
24 namespace Kaim { namespace HeapPT {
25 
26 using namespace Heap;
27 
28 // ***** SysAllocGranulator
29 //
30 // An intermediate system allocator that allows to have as large system
31 // granularity as wanted. The granulator requests the system allocator for
32 // large memory blocks and granulates them as necessary, providing smaller
33 // granularity to the allocation engine.
34 //
35 // If the system provides an advanced allocation mechanism, the granulator
36 // typically isn't necessary. However, it may speed up some cases, when
37 // the system calls are expensive (like VirtualAlloc on Win platforms).
38 //
39 // The granulator is really useful when the allocation system calls are
40 // "alignment unfriendly". A typical case of it is regular malloc/free
41 // (or dlmalloc as well).
42 //
43 // The allocator may request the system for small blocks of memory, but not
44 // less than Heap_PageSize, which is 4KB on 32-bit systems. The allocation
45 // data must be aligned to the "alignment" parameter, which is in most
46 // cases equals to Heap_PageSize. The alignment requirement can be less
47 // in some rare cases, when the allocator requests for small blocks of
48 // for the initial bootstrapping.
49 // But for the user payload the alignment is at least Heap_PageSize. It
50 // can be bigger than that only in cases of direct system allocations with
51 // bigger than 4K alignment requirements.
52 //
53 // If you create a heap with a very small granularity, like 4K, it's very
54 // likely that there will be many requests for those 4KB, aligned to 4KB
55 // too. With regular malloc/free it may result in up to 2x memory overhead.
56 // SysAllocGranulator can smooth this "injustice of nature." It
57 // requests the system for large blocks, (64K by default), aligned to 4K,
58 // and handles all the smaller requests from the allocator. Obviously, in
59 // case of 64K granularity and Heap_PageSize = 4K, the memory overhead
60 // for the alignment will be in the worst case 1/16, or 6.25%. In average
61 // it will be about two times less.
62 //------------------------------------------------------------------------
63 class SysAllocGranulator : public SysAllocPaged
64 {
65 public:
66  SysAllocGranulator();
67  SysAllocGranulator(SysAllocPaged* sysAlloc);
68 
69  void Init(SysAllocPaged* sysAlloc);
70 
71  virtual void GetInfo(Info* i) const;
72  virtual void* Alloc(UPInt size, UPInt alignment);
73  virtual bool ReallocInPlace(void* oldPtr, UPInt oldSize, UPInt newSize, UPInt alignment);
74  virtual bool Free(void* ptr, UPInt size, UPInt alignment);
75 
76  virtual void* AllocSysDirect(UPInt size, UPInt alignment, UPInt* actualSize, UPInt* actualAlign);
77  virtual bool FreeSysDirect(void* ptr, UPInt size, UPInt alignment);
78 
79  virtual UPInt GetFootprint() const;
80  virtual UPInt GetUsedSpace() const;
81 
82  virtual void VisitMem(MemVisitor* visitor) const;
83  virtual void VisitSegments(SegVisitor* visitor, unsigned catSeg, unsigned catUnused) const;
84 
85  virtual UPInt GetBase() const; // DBG
86  virtual UPInt GetSize() const; // DBG
87 
88 private:
89  Granulator* pGranulator;
90  UPInt SysDirectThreshold;
91  UPInt MaxHeapGranularity;
92  UPInt MinAlign;
93  UPInt MaxAlign;
94  UPInt SysDirectFootprint;
95  UPInt PrivateData[32];
96 };
97 
98 
99 //------------------------------------------------------------------------
100 class SysAllocWrapper : public SysAllocPaged
101 {
102 public:
103  SysAllocWrapper(SysAllocPaged* sysAlloc);
104 
105  virtual void GetInfo(Info* i) const;
106  virtual void* Alloc(UPInt size, UPInt align);
107  virtual bool Free(void* ptr, UPInt size, UPInt align);
108  virtual bool ReallocInPlace(void* oldPtr, UPInt oldSize, UPInt newSize, UPInt align);
109 
110  virtual void* AllocSysDirect(UPInt size, UPInt alignment, UPInt* actualSize, UPInt* actualAlign);
111  virtual bool FreeSysDirect(void* ptr, UPInt size, UPInt alignment);
112 
113  virtual void VisitMem(MemVisitor*) const;
114  virtual void VisitSegments(Heap::SegVisitor* visitor, unsigned catSeg, unsigned catUnused) const;
115 
116  virtual UPInt GetFootprint() const;
117  virtual UPInt GetUsedSpace() const;
118 
119  void* AllocSysDirect(UPInt size);
120  void FreeSysDirect(void* ptr, UPInt size);
121 
122 private:
123  SysAllocGranulator Allocator;
124  SysAllocPaged* pSrcAlloc;
125  SysAllocPaged* pSysAlloc;
126  UPInt SysGranularity; // For AllocSysDirect
127  UPInt MinAlign; // For AllocSysDirect
128  UPInt UsedSpace;
129 };
130 
131 //------------------------------------------------------------------------
132 class HeapRoot
133 {
134 public:
135  HeapRoot(SysAllocPaged* sysAlloc);
136  ~HeapRoot();
137 
138  void CreateArena(UPInt arena, SysAllocPaged* sysAlloc);
139  int DestroyArena(UPInt arena);
140  void DestroyAllArenas();
141  bool ArenaIsEmpty(UPInt arena);
142  SysAllocPaged* GetSysAlloc(UPInt arena);
143 
144  Starter* GetStarter() { return &AllocStarter; }
145  Bookkeeper* GetBookkeeper() { return &AllocBookkeeper; }
146 
147  MemoryHeapPT* CreateHeap(const char* name,
148  MemoryHeapPT* parent,
149  const MemoryHeap::HeapDesc& desc);
150 
151  void DestroyHeap(MemoryHeapPT* heap);
152 
153  LockSafe* GetLock() { return &RootLock; }
154 
155  void VisitSegments(Heap::SegVisitor* visitor) const;
156 
157  void* AllocSysDirect(UPInt size);
158  void FreeSysDirect(void* ptr, UPInt size);
159 
160  void GetStats(MemoryHeap::RootStats* stats) const;
161 
162 #ifdef KY_MEMORY_ENABLE_DEBUG_INFO
163  Granulator* GetDebugAlloc() { return &DebugAlloc; }
164 #endif
165 
166 #ifdef KY_MEMORY_TRACE_ALL
167  void OnAlloc(const MemoryHeap* heap, UPInt size, UPInt align, unsigned sid, const void* ptr);
168  void OnRealloc(const MemoryHeap* heap, const void* oldPtr, UPInt newSize, const void* newPtr);
169  void OnFree(const MemoryHeap* heap, const void* ptr);
170 
171  static MemoryHeap::HeapTracer* pTracer;
172 #endif
173 
174 
175 private:
176  SysAllocWrapper AllocWrapper;
177  Starter AllocStarter;
178  Bookkeeper AllocBookkeeper;
179 #ifdef KY_MEMORY_ENABLE_DEBUG_INFO
180  Granulator DebugAlloc;
181 #endif
182  mutable LockSafe RootLock;
183  SysAllocPaged** pArenas;
184  UPInt NumArenas;
185 };
186 
187 extern HeapRoot* GlobalRoot;
188 
189 }} // Kaim::HeapPT
190 
191 #endif
Definition: gamekitcrowddispersion.h:20