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 <string.h>
20#include <sys/mman.h>
21
22namespace Memory
23{
24#if NEBULA_MEMORY_STATS
25extern int volatile TotalAllocCount;
26extern int volatile TotalAllocSize;
27extern int volatile HeapTypeAllocCount[NumHeapTypes];
28extern int volatile HeapTypeAllocSize[NumHeapTypes];
29#endif
30
31#define StackAlloc(size) alloca(size);
32#define StackFree(ptr)
33
34#if __APPLE__
35#define explicit_bzero bzero;
36#endif
37
38//------------------------------------------------------------------------------
42__forceinline void*
43Alloc(HeapType heapType, size_t size, size_t align = 16)
44{
45 n_assert(heapType < NumHeapTypes);
46 void* allocPtr = 0;
47 {
48 int err = posix_memalign(&allocPtr, align, size);
49 n_assert(err == 0);
50 #if NEBULA_DEBUG
51 explicit_bzero(allocPtr,size);
52 #endif
53 }
54 #if NEBULA_MEMORY_STATS
55 SIZE_T s = HeapSize(Heaps[heapType], 0, allocPtr);
60 #endif
61 return allocPtr;
62}
63
64//------------------------------------------------------------------------------
68__forceinline void*
69Realloc(HeapType heapType, void* ptr, size_t size)
70{
71 n_assert(heapType < NumHeapTypes);
72 #if NEBULA_MEMORY_STATS
73 SIZE_T oldSize = HeapSize(Heaps[heapType], 0, ptr);
74 #endif
75 void* allocPtr = realloc(ptr, size);
76 #if NEBULA_MEMORY_STATS
77 SIZE_T newSize = HeapSize(Heaps[heapType], 0, allocPtr);
78 Threading::Interlocked::Add(TotalAllocSize, int(newSize - oldSize));
79 Threading::Interlocked::Add(HeapTypeAllocSize[heapType], int(newSize - oldSize));
80 #endif
81 return allocPtr;
82}
83
84//------------------------------------------------------------------------------
88__forceinline void
89Free(HeapType heapType, void* ptr)
90{
91 // D3DX on the 360 likes to call the delete operator with a 0 pointer
92 if (0 != ptr)
93 {
94 n_assert(heapType < NumHeapTypes);
95 #if NEBULA_MEMORY_STATS
96 SIZE_T size = 0;
97 #endif
98 {
99 #if NEBULA_MEMORY_STATS
100 size = HeapSize(Heaps[heapType], 0, ptr);
101 #endif
102 free(ptr);
103 }
104 #if NEBULA_MEMORY_STATS
107 Threading::Interlocked::Add(HeapTypeAllocSize[heapType], -int(size));
109 #endif
110 }
111}
112
113//------------------------------------------------------------------------------
116__forceinline void*
117AllocVirtual(size_t size)
118{
119 void* ret = mmap(nullptr, size, PROT_NONE, MAP_ANON | MAP_PRIVATE, 0, 0);
120 n_assert(ret != nullptr);
121 return ret;
122}
123
124//------------------------------------------------------------------------------
127__forceinline void
128DecommitVirtual(void* ptr, size_t size)
129{
130 auto ret = madvise(ptr, size, MADV_DONTNEED);
131 n_assert(ret == 0);
132 ret = mprotect(ptr, size, PROT_NONE);
133 n_assert(ret == 0);
134}
135
136//------------------------------------------------------------------------------
139__forceinline void
140CommitVirtual(void* ptr, size_t size)
141{
142 auto ret = mprotect(ptr, size, PROT_READ | PROT_WRITE);
143 explicit_bzero(ptr, size);
144 n_assert(ret == 0);
145}
146
147//------------------------------------------------------------------------------
150__forceinline void
151FreeVirtual(void* ptr, size_t size)
152{
153 auto ret = madvise(ptr, size, MADV_DONTNEED);
154 n_assert(ret == 0);
155 ret = munmap(ptr, size);
156 n_assert(ret == 0);
157}
158
159//------------------------------------------------------------------------------
163__forceinline void
164Copy(const void* from, void* to, size_t numBytes)
165{
166 if (numBytes > 0)
167 {
168 n_assert(0 != from);
169 n_assert(0 != to);
170 n_assert(from != to);
171 memcpy(to, from, numBytes);
172 }
173}
174
175//------------------------------------------------------------------------------
179__forceinline void
180Move(const void* from, void* to, size_t numBytes)
181{
182 if (numBytes > 0)
183 {
184 n_assert(0 != from);
185 n_assert(0 != to);
186 n_assert(from != to);
187 memmove(to, from, numBytes);
188 }
189}
190
191//------------------------------------------------------------------------------
195template <typename T>
196__forceinline void
197MoveElements(const T* from, T* to, size_t numElements)
198{
199 if (numElements > 0)
200 {
201 n_assert(0 != from);
202 n_assert(0 != to);
203 n_assert(from != to);
204 if constexpr (std::is_trivially_move_assignable<T>::value && std::is_trivially_move_constructible<T>::value)
205 {
206 memmove((void*)to, (const void*)from, numElements * sizeof(T));
207 }
208 else
209 {
210 std::move(from, from + numElements, to);
211 }
212 }
213}
214
215//------------------------------------------------------------------------------
219template <typename T>
220__forceinline void
221CopyElements(const T* from, T* to, size_t numElements)
222{
223 if (numElements > 0)
224 {
225 n_assert(0 != from);
226 n_assert(0 != to);
227 n_assert(from != to);
228 if constexpr (std::is_trivially_copyable<T>::value)
229 {
230 memcpy(to, from, numElements * sizeof(T));
231 }
232 else
233 {
234 std::copy(from, from + numElements, to);
235 }
236 }
237}
238
239//------------------------------------------------------------------------------
244__forceinline void
245CopyToGraphicsMemory(const void* from, void* to, size_t numBytes)
246{
247 // no special handling on the Win32 platform
248 Memory::Copy(from, to, numBytes);
249}
250
251//------------------------------------------------------------------------------
255__forceinline void
256Clear(void* ptr, size_t numBytes)
257{
258 memset(ptr, 0, numBytes);
259}
260
261//------------------------------------------------------------------------------
265__forceinline void
266Fill(void* ptr, size_t numBytes, unsigned char value)
267{
268 memset(ptr, value, numBytes);
269}
270
271//------------------------------------------------------------------------------
276__forceinline char*
277DuplicateCString(const char* from)
278{
279 n_assert(0 != from);
280 size_t len = (unsigned int) strlen(from) + 1;
281 char* to = (char*) Memory::Alloc(Memory::StringDataHeap, len);
282 Memory::Copy((void*)from, to, len);
283 return to;
284}
285
286//------------------------------------------------------------------------------
290inline bool
291IsOverlapping(const unsigned char* srcPtr, size_t srcSize, const unsigned char* dstPtr, size_t dstSize)
292{
293 if (srcPtr == dstPtr)
294 {
295 return true;
296 }
297 else if (srcPtr > dstPtr)
298 {
299 return (srcPtr + srcSize) > dstPtr;
300 }
301 else
302 {
303 return (dstPtr + dstSize) > srcPtr;
304 }
305}
306
307//------------------------------------------------------------------------------
313{
314 unsigned int totalPhysical;
315 unsigned int availPhysical;
316 unsigned int totalVirtual;
317 unsigned int availVirtual;
318};
319
322{
323#if 0
324 MEMORYSTATUS stats = { NULL };
325 GlobalMemoryStatus(&stats);
326 TotalMemoryStatus result;
327 result.totalPhysical = (unsigned int) stats.dwTotalPhys;
328 result.availPhysical = (unsigned int) stats.dwAvailPhys;
329 result.totalVirtual = (unsigned int) stats.dwTotalVirtual;
330 result.availVirtual = (unsigned int) stats.dwAvailVirtual;
331 return result;
332#else
333 TotalMemoryStatus result;
334 return result;
335#endif
336}
337
338//------------------------------------------------------------------------------
344#if NEBULA_MEMORY_STATS
345extern bool Validate();
346#endif
347
348} // namespace Memory
349//------------------------------------------------------------------------------
350#endif
351
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:180
__forceinline void FreeVirtual(void *ptr, size_t size)
free virtual memory
Definition posixmemory.h:151
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:140
__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:221
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:117
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:197
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:128
__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:245
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:35
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