Nebula
Loading...
Searching...
No Matches
posixmemory.h
Go to the documentation of this file.
1#pragma once
2#include <algorithm>
3#include <type_traits>
4#ifndef MEMORY_POSIXMEMORY_H
5#define MEMORY_POSIXMEMORY_H
6//------------------------------------------------------------------------------
15#include "core/config.h"
16#include "core/debug.h"
19#include <malloc.h>
20#include <string.h>
21#include <sys/mman.h>
22
23namespace Memory
24{
25#if NEBULA_MEMORY_STATS
26extern int volatile TotalAllocCount;
27extern int volatile TotalAllocSize;
28extern int volatile HeapTypeAllocCount[NumHeapTypes];
29extern int volatile HeapTypeAllocSize[NumHeapTypes];
30#endif
31
32#define StackAlloc(size) alloca(size);
33#define StackFree(ptr)
34
35//------------------------------------------------------------------------------
39__forceinline void*
40Alloc(HeapType heapType, size_t size, size_t align = 16)
41{
42 n_assert(heapType < NumHeapTypes);
43 void* allocPtr = 0;
44 {
45 int err = posix_memalign(&allocPtr, align, size);
46 n_assert(err == 0);
47 #if NEBULA_DEBUG
48 explicit_bzero(allocPtr,size);
49 #endif
50 }
51 #if NEBULA_MEMORY_STATS
52 SIZE_T s = HeapSize(Heaps[heapType], 0, allocPtr);
57 #endif
58 return allocPtr;
59}
60
61//------------------------------------------------------------------------------
65__forceinline void*
66Realloc(HeapType heapType, void* ptr, size_t size)
67{
68 n_assert(heapType < NumHeapTypes);
69 #if NEBULA_MEMORY_STATS
70 SIZE_T oldSize = HeapSize(Heaps[heapType], 0, ptr);
71 #endif
72 void* allocPtr = realloc(ptr, size);
73 #if NEBULA_MEMORY_STATS
74 SIZE_T newSize = HeapSize(Heaps[heapType], 0, allocPtr);
75 Threading::Interlocked::Add(TotalAllocSize, int(newSize - oldSize));
76 Threading::Interlocked::Add(HeapTypeAllocSize[heapType], int(newSize - oldSize));
77 #endif
78 return allocPtr;
79}
80
81//------------------------------------------------------------------------------
85__forceinline void
86Free(HeapType heapType, void* ptr)
87{
88 // D3DX on the 360 likes to call the delete operator with a 0 pointer
89 if (0 != ptr)
90 {
91 n_assert(heapType < NumHeapTypes);
92 #if NEBULA_MEMORY_STATS
93 SIZE_T size = 0;
94 #endif
95 {
96 #if NEBULA_MEMORY_STATS
97 size = HeapSize(Heaps[heapType], 0, ptr);
98 #endif
99 free(ptr);
100 }
101 #if NEBULA_MEMORY_STATS
104 Threading::Interlocked::Add(HeapTypeAllocSize[heapType], -int(size));
106 #endif
107 }
108}
109
110//------------------------------------------------------------------------------
113__forceinline void*
114AllocVirtual(size_t size)
115{
116 void* ret = mmap(nullptr, size, PROT_NONE, MAP_ANON | MAP_PRIVATE, 0, 0);
117 n_assert(ret != nullptr);
118 return ret;
119}
120
121//------------------------------------------------------------------------------
124__forceinline void
125DecommitVirtual(void* ptr, size_t size)
126{
127 auto ret = madvise(ptr, size, MADV_DONTNEED);
128 n_assert(ret == 0);
129 ret = mprotect(ptr, size, PROT_NONE);
130 n_assert(ret == 0);
131}
132
133//------------------------------------------------------------------------------
136__forceinline void
137CommitVirtual(void* ptr, size_t size)
138{
139 auto ret = mprotect(ptr, size, PROT_READ | PROT_WRITE);
140 explicit_bzero(ptr, size);
141 n_assert(ret == 0);
142}
143
144//------------------------------------------------------------------------------
147__forceinline void
148FreeVirtual(void* ptr, size_t size)
149{
150 auto ret = madvise(ptr, size, MADV_DONTNEED);
151 n_assert(ret == 0);
152 ret = munmap(ptr, size);
153 n_assert(ret == 0);
154}
155
156//------------------------------------------------------------------------------
160__forceinline void
161Copy(const void* from, void* to, size_t numBytes)
162{
163 if (numBytes > 0)
164 {
165 n_assert(0 != from);
166 n_assert(0 != to);
167 n_assert(from != to);
168 memcpy(to, from, numBytes);
169 }
170}
171
172//------------------------------------------------------------------------------
176__forceinline void
177Move(const void* from, void* to, size_t numBytes)
178{
179 if (numBytes > 0)
180 {
181 n_assert(0 != from);
182 n_assert(0 != to);
183 n_assert(from != to);
184 memmove(to, from, numBytes);
185 }
186}
187
188//------------------------------------------------------------------------------
192template <typename T>
193__forceinline void
194MoveElements(const T* from, T* to, size_t numElements)
195{
196 if (numElements > 0)
197 {
198 n_assert(0 != from);
199 n_assert(0 != to);
200 n_assert(from != to);
201 if constexpr (std::is_trivially_move_assignable<T>::value && std::is_trivially_move_constructible<T>::value)
202 {
203 memmove((void*)to, (const void*)from, numElements * sizeof(T));
204 }
205 else
206 {
207 std::move(from, from + numElements, to);
208 }
209 }
210}
211
212//------------------------------------------------------------------------------
216template <typename T>
217__forceinline void
218CopyElements(const T* from, T* to, size_t numElements)
219{
220 if (numElements > 0)
221 {
222 n_assert(0 != from);
223 n_assert(0 != to);
224 n_assert(from != to);
225 if constexpr (std::is_trivially_copyable<T>::value)
226 {
227 memcpy(to, from, numElements * sizeof(T));
228 }
229 else
230 {
231 std::copy(from, from + numElements, to);
232 }
233 }
234}
235
236//------------------------------------------------------------------------------
241__forceinline void
242CopyToGraphicsMemory(const void* from, void* to, size_t numBytes)
243{
244 // no special handling on the Win32 platform
245 Memory::Copy(from, to, numBytes);
246}
247
248//------------------------------------------------------------------------------
252__forceinline void
253Clear(void* ptr, size_t numBytes)
254{
255 memset(ptr, 0, numBytes);
256}
257
258//------------------------------------------------------------------------------
262__forceinline void
263Fill(void* ptr, size_t numBytes, unsigned char value)
264{
265 memset(ptr, value, numBytes);
266}
267
268//------------------------------------------------------------------------------
273__forceinline char*
274DuplicateCString(const char* from)
275{
276 n_assert(0 != from);
277 size_t len = (unsigned int) strlen(from) + 1;
278 char* to = (char*) Memory::Alloc(Memory::StringDataHeap, len);
279 Memory::Copy((void*)from, to, len);
280 return to;
281}
282
283//------------------------------------------------------------------------------
287inline bool
288IsOverlapping(const unsigned char* srcPtr, size_t srcSize, const unsigned char* dstPtr, size_t dstSize)
289{
290 if (srcPtr == dstPtr)
291 {
292 return true;
293 }
294 else if (srcPtr > dstPtr)
295 {
296 return (srcPtr + srcSize) > dstPtr;
297 }
298 else
299 {
300 return (dstPtr + dstSize) > srcPtr;
301 }
302}
303
304//------------------------------------------------------------------------------
310{
311 unsigned int totalPhysical;
312 unsigned int availPhysical;
313 unsigned int totalVirtual;
314 unsigned int availVirtual;
315};
316
319{
320#if 0
321 MEMORYSTATUS stats = { NULL };
322 GlobalMemoryStatus(&stats);
323 TotalMemoryStatus result;
324 result.totalPhysical = (unsigned int) stats.dwTotalPhys;
325 result.availPhysical = (unsigned int) stats.dwAvailPhys;
326 result.totalVirtual = (unsigned int) stats.dwTotalVirtual;
327 result.availVirtual = (unsigned int) stats.dwAvailVirtual;
328 return result;
329#else
330 TotalMemoryStatus result;
331 return result;
332#endif
333}
334
335//------------------------------------------------------------------------------
341#if NEBULA_MEMORY_STATS
342extern bool Validate();
343#endif
344
345} // namespace Memory
346//------------------------------------------------------------------------------
347#endif
348
Nebula debug macros.
#define n_assert(exp)
Definition debug.h:50
Nebula compiler specific defines and configuration.
Definition arenaallocator.h:31
TotalMemoryStatus GetTotalMemoryStatus()
Get the system's total memory status.
Definition osxmemory.cc:201
__forceinline void Move(const void *from, void *to, size_t numBytes)
Move a chunk of memory, can handle overlapping regions.
Definition posixmemory.h:177
__forceinline void FreeVirtual(void *ptr, size_t size)
free virtual memory
Definition posixmemory.h:148
int volatile TotalAllocSize
Definition win32memory.cc:17
void Copy(const void *from, void *to, size_t numBytes)
Copy a chunk of memory (note the argument order is different from memcpy()!
Definition osxmemory.cc:213
int volatile TotalAllocCount
Definition win32memory.cc:16
void * Alloc(HeapType heapType, size_t size, size_t alignment)
Allocate a block of memory from one of the global heaps.
Definition osxmemory.cc:56
__forceinline void CommitVirtual(void *ptr, size_t size)
commit virtual memory
Definition posixmemory.h:137
__forceinline void CopyElements(const T *from, T *to, size_t numElements)
Copy a chunk of memory (note the argument order is different from memcpy()!
Definition posixmemory.h:218
int volatile HeapTypeAllocCount[NumHeapTypes]
Definition win32memory.cc:18
void Fill(void *ptr, size_t numBytes, unsigned char value)
Fill memory with a specific byte.
Definition osxmemory.cc:239
int volatile HeapTypeAllocSize[NumHeapTypes]
Definition win32memory.cc:19
void Free(HeapType heapType, void *ptr)
Free a block of memory.
Definition osxmemory.cc:136
void * Realloc(HeapType heapType, void *ptr, size_t size)
Re-Allocate a block of memory from one of the global heaps.
Definition osxmemory.cc:99
__forceinline void * AllocVirtual(size_t size)
allocate a range of virtual memory space
Definition posixmemory.h:114
char * DuplicateCString(const char *from)
Duplicate a 0-terminated string, this method should no longer be used!
Definition osxmemory.cc:166
HeapType
Heap types are defined here.
Definition osxmemoryconfig.h:25
@ NumHeapTypes
Definition osxmemoryconfig.h:36
@ StringDataHeap
Definition osxmemoryconfig.h:31
__forceinline void MoveElements(const T *from, T *to, size_t numElements)
Move a chunk of memory, can handle overlapping regions.
Definition posixmemory.h:194
bool IsOverlapping(const unsigned char *srcPtr, size_t srcSize, const unsigned char *dstPtr, size_t dstSize)
Test if 2 areas of memory areas are overlapping.
Definition osxmemory.cc:180
__forceinline void DecommitVirtual(void *ptr, size_t size)
decommit virtual memory
Definition posixmemory.h:125
__forceinline void CopyToGraphicsMemory(const void *from, void *to, size_t numBytes)
Copy data from a system memory buffer to graphics resource memory.
Definition posixmemory.h:242
void Clear(void *ptr, size_t numBytes)
Overwrite a chunk of memory with 0's.
Definition osxmemory.cc:229
malloc_zone_t * Heaps[NumHeapTypes]
Heap pointers are defined here.
Definition osxmemoryconfig.cc:12
Math::float2 size
Definition histogramcontext.cc:36
int Decrement(int volatile *var)
interlocked decrement, return result
Definition gccinterlocked.cc:157
int Add(int volatile *var, int add)
interlocked add
Definition gccinterlocked.cc:22
int Increment(int volatile *var)
interlocked increment, return result
Definition gccinterlocked.cc:148
Central config file for memory setup on the Posix platform.
Get the system's total current memory, this does not only include Nebula's memory allocations but the...
Definition osxmemory.h:52
unsigned int totalVirtual
Definition osxmemory.h:55
unsigned int totalPhysical
Definition osxmemory.h:53
unsigned int availVirtual
Definition osxmemory.h:56
unsigned int availPhysical
Definition osxmemory.h:54