gwnavruntime/kernel/SF_SysAlloc.h Source File

SF_SysAlloc.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 PublicHeader: Kernel
10 Filename : KY_SysAlloc.h
11 Content : System Allocator Interface
12 Created : 2009
13 Authors : Maxim Shemanarev, Michael Antonov
14 
15 Notes : Interface to the system allocator.
16 
17 **************************************************************************/
18 
19 #ifndef INC_KY_Kernel_SysAlloc_H
20 #define INC_KY_Kernel_SysAlloc_H
21 
23 
24 namespace Kaim {
25 
26 namespace Heap { class MemVisitor; class SegVisitor; }
27 
28 // ***** SysAllocBase
29 
30 // SysAllocBase is a base class for SysAllocPaged and SysAllocBase.
31 // This class is used to provide link-independent initialization for
32 // different memory heap engines in System class and has no public APIs.
34 {
35  friend class System;
36 protected:
37  virtual ~SysAllocBase() { }
38 
39  // Initializes heap system, creating and initializing GlobalHeap.
40  virtual bool initHeapEngine(const void* heapDesc) { KY_UNUSED(heapDesc); return false; }
41  // Shuts down heap system, clearing out global heap.
42  virtual void shutdownHeapEngine() { }
43 };
44 
45 
46 //------------------------------------------------------------------------
47 // ***** SysAlloc
48 
49 // SysAlloc defines a memory allocation interface that developers can override
50 // to to provide memory for GFx; an instance of this class is typically created on
51 // application startup and passed into System or Intrnl::System constructor.
52 //
53 // This new "malloc-friendly" interface is introduced with GFx 3.3 and replaces
54 // older SysAlloc implementation (now renamed to SysAllocPaged). SysAlloc
55 // is more memory efficient when delegating to malloc/dlmalloc based implementation,
56 // as it doesn't require large alignment and will return more memory blocks
57 // to the application once content is unloaded.
58 //
59 // Users implementing this interface must provide three functions: Alloc, Free,
60 // and Realloc. Implementations of these functions must honor the requested alignment.
61 // Although arbitrary alignment requests are possible, requested alignment will
62 // typically be small, such as 16 bytes or less.
63 //
64 // SysAlloc links to the MemoryHeapMH implementation, which groups small
65 // allocations into 4K-sized blocks belonging to the heap. Allocations larger
66 // then 512 bytes will delegated directly to SysAlloc and released immediately
67 // once no longer used, making more memory available to the application.
68 
69 class SysAlloc : public SysAllocBase
70 {
71 public:
72  SysAlloc() {}
73  virtual ~SysAlloc() {}
74 
75  virtual void* Alloc(UPInt size, UPInt align) = 0;
76  virtual void Free(void* ptr, UPInt size, UPInt align) = 0;
77  virtual void* Realloc(void* oldPtr, UPInt oldSize, UPInt newSize, UPInt align) = 0;
78 
79 protected:
80  // Implementation of SysAllocBase based on MemoryHeapMH.
81  virtual bool initHeapEngine(const void* heapDesc);
82  virtual void shutdownHeapEngine();
83 };
84 
85 
86 
87 //------------------------------------------------------------------------
88 // ***** SysAllocPaged
89 
90 // SysAllocPaged is an abstract interface used to provide allocations to page
91 // based MemoryHeapPT memory system, first introduced with GFx 3.0. Unlike
92 // SysAlloc, this system will requires 4K page alignment on allocations and
93 // will in general keep larger blocks allocated. This system is best for OS-direct
94 // allocations, being able to take advantage of HW paging, and is also used
95 // to implement SysAllocStatic. If you plan to implement this interface
96 // by delegating to malloc/dlmalloc based API, SysAlloc is a better choice.
97 //
98 // users can implement it to delegate allocations to their own memory allocator.
99 // Developers implementing SysAllocPaged need to define at least three
100 // functions: GetInfo, Alloc and Free.
101 //
102 // When running, GFx will allocate and free large blocks through this interface,
103 // managing all of the smaller allocations internally. As GFx uses 4K alignment
104 // for large blocks internally, it is best if this interface maps directly to OS
105 // implementation. When that is not the case, it is best to use 64K+ granularity
106 // to make sure that minimal memory is wasted on alignment.
107 //
108 // Scaleform provides several default SysAllocPaged implementations:
109 // 1. Memory Range Based: SysAllocStatic.
110 // - Accepts a memory range in constructor, forcing GFx to work within
111 // a block of memory.
112 // 2. System Specific: SysAllocWin32, etc.
113 // - Uses OS specific implementation such as VirtualAlloc, mmap, etc
114 // to allocate memory pages. This implementation is most efficient for
115 // the target platform. This heap is used by default in GFxSystem if
116 // you don't specify a different allocator.
117 // 3. Malloc version: SysAllocPagedMalloc.
118 // - Uses standard library functions such as memalign() and free(). You can
119 // use the source code to these as a reference for your own implementation.
120 // - It is better to use SysAlloc derived implementation insead.
121 
122 class SysAllocPaged : public SysAllocBase
123 {
124 public:
125  struct Info
126  {
127  // MinAlign is the minimum alignment that system allocator will always
128  // to apply all of the allocations, independent of whether it is requested
129  // or not. For OS allocators, this will often be equal to the page size
130  // of the system.
131  UPInt MinAlign;
132 
133  // MaxAlign is the maximum supported alignment that will be honored
134  // by the allocator. For larger alignment requests, external granulator
135  // wrapper will fake alignment by making larger allocations.
136  // Set this value to 0 if you allocator supports any alignment request;
137  // set this to 1 byte if it doesn't support any alignment.
138  UPInt MaxAlign;
139 
140  // Granularity is the allocation granularity that the system can handle
141  // efficiently. On Win32 it's at least 64K and must be a multiple of 64K.
142  UPInt Granularity;
143 
144  // When not null SysDirectThreshold defines the global size threshold.
145  // If the allocation size is greater or equal this threshold it's being
146  // redirected to the system, ignoring the granulator layer.
147  UPInt SysDirectThreshold;
148 
149  // If not null it MaxHeapGranularity restricts the maximal possible
150  // heap granularity. In most cases it can reduce the system memory
151  // footprint for the price of more frequent segment alloc/free operations,
152  // which slows down the allocator.
153  // MaxHeapGranularity must be at least 4096 and a multiple of 4096.
154  UPInt MaxHeapGranularity;
155 
156  // HasRealloc flag tells the allocator whether or not ReallocInPlace is
157  // implemented. This is just an optimization that allows the allocator to
158  // eliminate some unnecessary operations. If ReallocInPlace is not
159  // implemented the allocator is still capable to reallocate memory but
160  // moving of the data will occur more frequently.
161  bool HasRealloc;
162  };
163  SysAllocPaged() {}
164 
165  // Fills in information about capabilities of this SysAllocPaged implementation.
166  // MemoryHeap implementation will take these values into account when making
167  // allocation calls.
168  virtual void GetInfo(Info* i) const = 0;
169  virtual void* Alloc(UPInt size, UPInt align) = 0;
170  virtual bool Free(void* ptr, UPInt size, UPInt align) = 0;
171 
172  // ReallocInPlace attempts to reallocate memory to a new size without moving it.
173  // If such reallocation succeeds 'true' is returned, otherwise 'false' is returned and the
174  // previous allocation remains unchanged. This function is provided as an optimization
175  // for internal Realloc implementation for large blocks; it does not need to be implemented.
176  virtual bool ReallocInPlace(void* oldPtr, UPInt oldSize, UPInt newSize, UPInt align)
177  {
178  KY_UNUSED4(oldPtr, oldSize, newSize, align);
179  return false;
180  }
181 
182  // Not mandatory for overriding. May do nothing.
183  virtual void* AllocSysDirect(UPInt, UPInt, UPInt*, UPInt*) { return 0; }
184  virtual bool FreeSysDirect(void*, UPInt, UPInt) { return false; }
185 
186  virtual UPInt GetBase() const { return 0; } // DBG
187  virtual UPInt GetSize() const { return 0; } // DBG
188 
189  virtual UPInt GetFootprint() const { return 0; }
190  virtual UPInt GetUsedSpace() const { return 0; }
191  virtual void VisitMem(Heap::MemVisitor*) const {}
192  virtual void VisitSegments(Heap::SegVisitor*, unsigned, unsigned) const {}
193 
194  virtual ~SysAllocPaged() { }
195 
196 
197 protected:
198  // Implementation of SysAllocBase based on MemoryHeapPT.
199  virtual bool initHeapEngine(const void* heapDesc);
200  virtual void shutdownHeapEngine();
201 };
202 
203 
204 //------------------------------------------------------------------------
205 // ***** SysAllocStatic
206 //
207 // System allocator that works entirely in a single block of memory.
208 namespace HeapPT { class AllocLite; }
209 namespace Heap { class MemVisitor; }
210 
211 class SysAllocStatic : public SysAllocPaged
212 {
213 public:
214  enum { MaxSegments = 4 };
215 
216  KY_EXPORT SysAllocStatic(void* mem1=0, UPInt size1=0,
217  void* mem2=0, UPInt size2=0,
218  void* mem3=0, UPInt size3=0,
219  void* mem4=0, UPInt size4=0);
220 
221  KY_EXPORT SysAllocStatic(UPInt minSize);
222 
223  KY_EXPORT void AddMemSegment(void* mem, UPInt size);
224 
225  virtual void GetInfo(Info* i) const;
226  virtual void* Alloc(UPInt size, UPInt align);
227  virtual bool ReallocInPlace(void* oldPtr, UPInt oldSize, UPInt newSize, UPInt align);
228  virtual bool Free(void* ptr, UPInt size, UPInt align);
229 
230  virtual void VisitMem(Heap::MemVisitor* visitor) const;
231 
232  virtual UPInt GetFootprint() const;
233  virtual UPInt GetUsedSpace() const;
234 
235  virtual UPInt GetBase() const; // DBG
236  virtual UPInt GetSize() const; // DBG
237 
238 private:
239  UPInt MinSize;
240  UPInt NumSegments;
241  HeapPT::AllocLite* pAllocator;
242  UPInt PrivateData[8];
243  UPInt Segments[MaxSegments][8];
244  UPInt TotalSpace;
245 };
246 
247 
248 
249 //------------------------------------------------------------------------
250 // ***** SysAllocBase_SingletonSupport
251 
252 // SysAllocBase_SingletonSupport is a SysAllocBase class wrapper that implements
253 // the InitSystemSingleton static function, used to create a global singleton
254 // used for the GFxSystem default argument initialization.
255 //
256 // End users implementing custom SysAlloc/Paged interface don't need to make use of this base
257 // class; they can just create an instance of their own class on stack and pass it to System.
258 
259 template<class A, class B>
260 class SysAllocBase_SingletonSupport : public B
261 {
262  struct SysAllocContainer
263  {
264  UPInt Data[(sizeof(A) + sizeof(UPInt)-1) / sizeof(UPInt)];
265  bool Initialized;
266  SysAllocContainer() : Initialized(0) { }
267  };
268 
269  SysAllocContainer* pContainer;
270 
271 public:
272  SysAllocBase_SingletonSupport() : pContainer(0) { }
273 
274  // Creates a singleton instance of this SysAllocPaged class used
275  // on KY_SYSALLOC_DEFAULT_CLASS during GFxSystem initialization.
276  static B* InitSystemSingleton()
277  {
278  static SysAllocContainer Container;
279  KY_ASSERT(Container.Initialized == false);
280 
281  #undef new
282 
283  SysAllocBase_SingletonSupport<A,B> *presult = ::new((void*)Container.Data) A;
284 
285  // Redefine operator 'new' if necessary.
286  #if defined(KY_DEFINE_NEW)
287  #define new KY_DEFINE_NEW
288  #endif
289 
290  presult->pContainer = &Container;
291  Container.Initialized = true;
292  return presult;
293  }
294 
295 protected:
296  virtual void shutdownHeapEngine()
297  {
298  B::shutdownHeapEngine();
299  if (pContainer)
300  {
301  pContainer->Initialized = false;
302  ((B*)this)->~B();
303  pContainer = 0;
304  }
305  }
306 };
307 
308 
309 //------------------------------------------------------------------------
310 // ***** SysMemMapper
311 //
312 // SysMemMap is an abstract interface to the system memory mapping such as
313 // WinAPI VirtualAlloc/VirtualFree or posix mmap/munmap. It's used with
314 // SysAllocMemoryMap that takes a full advantage of the system memory mapping
315 // interface.
316 class SysMemMapper
317 {
318 public:
319  virtual UPInt GetPageSize() const = 0;
320 
321  // Reserve and release address space. The functions must not allocate
322  // any actual memory. The size is typically very large, such as 128
323  // megabytes. ReserveAddrSpace() returns a pointer to the reserved
324  // space; there is no usable memory is allocated.
325  //--------------------------------------------------------------------
326  virtual void* ReserveAddrSpace(UPInt size) = 0;
327  virtual bool ReleaseAddrSpace(void* ptr, UPInt size) = 0;
328 
329  // Map and unmap memory pages to allocate actual memory. The caller
330  // guarantees the integrity of the calls. That is, the the size is
331  // always a multiple of GetPageSize() and the ptr...ptr+size is always
332  // within the reserved address space. Also it's guaranteed that there
333  // will be no MapPages call for already mapped memory and no UnmapPages
334  // for not mapped memory.
335  //--------------------------------------------------------------------
336  virtual void* MapPages(void* ptr, UPInt size) = 0;
337  virtual bool UnmapPages(void* ptr, UPInt size) = 0;
338 
339  virtual ~SysMemMapper() {}
340 };
341 
342 } // Scaleform
343 
344 #endif
A base class for an object that manages memory allocations and de-allocations.
Definition: SF_SysAlloc.h:33
The SysAlloc class specifies an interface for allocating and freeing memory.
Definition: SF_SysAlloc.h:70
Adds to the SysAlloc class support for restricting instantiation to a single object.
Definition: SF_SysAlloc.h:267
virtual void * Realloc(void *oldPtr, UPInt oldSize, UPInt newSize, UPInt align)=0
Re-allocates a buffer to a new size.
Definition: gamekitcrowddispersion.h:20
virtual void * Alloc(UPInt size, UPInt align)=0
Allocates a buffer of the specified size, with the specified alignment.
virtual void Free(void *ptr, UPInt size, UPInt align)=0
Frees the specified memory buffer.