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 size_t volatile TotalAllocSize;
27extern int volatile HeapTypeAllocCount[NumHeapTypes];
28extern size_t 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 n_assert(align != 0);
47 void* allocPtr = 0;
48 {
49 align = std::max(align, sizeof(void*));
50
51 #if NEBULA_DEBUG
52 // Posix requirements state that alignment must be a
53 // multiple of sizeof(void*).
54 n_assert((align & (align - 1)) == 0);
55 #endif
56 int err = posix_memalign(&allocPtr, align, size);
57 n_assert(err == 0);
58 #if NEBULA_DEBUG
59 explicit_bzero(allocPtr,size);
60 #endif
61 }
62 #if NEBULA_MEMORY_STATS
63 SIZE_T s = HeapSize(Heaps[heapType], 0, allocPtr);
68 #endif
69 return allocPtr;
70}
71
72//------------------------------------------------------------------------------
76__forceinline void*
77Realloc(HeapType heapType, void* ptr, size_t size)
78{
79 n_assert(heapType < NumHeapTypes);
80 #if NEBULA_MEMORY_STATS
81 SIZE_T oldSize = HeapSize(Heaps[heapType], 0, ptr);
82 #endif
83 void* allocPtr = realloc(ptr, size);
84 #if NEBULA_MEMORY_STATS
85 SIZE_T newSize = HeapSize(Heaps[heapType], 0, allocPtr);
86 Threading::Interlocked::Add(TotalAllocSize, int(newSize - oldSize));
87 Threading::Interlocked::Add(HeapTypeAllocSize[heapType], int(newSize - oldSize));
88 #endif
89 return allocPtr;
90}
91
92//------------------------------------------------------------------------------
96__forceinline void
97Free(HeapType heapType, void* ptr)
98{
99 // D3DX on the 360 likes to call the delete operator with a 0 pointer
100 if (0 != ptr)
101 {
102 n_assert(heapType < NumHeapTypes);
103 #if NEBULA_MEMORY_STATS
104 SIZE_T size = 0;
105 #endif
106 {
107 #if NEBULA_MEMORY_STATS
108 size = HeapSize(Heaps[heapType], 0, ptr);
109 #endif
110 free(ptr);
111 }
112 #if NEBULA_MEMORY_STATS
115 Threading::Interlocked::Add(HeapTypeAllocSize[heapType], -int(size));
117 #endif
118 }
119}
120
121//------------------------------------------------------------------------------
124__forceinline void*
125AllocVirtual(size_t size)
126{
127 void* ret = mmap(nullptr, size, PROT_NONE, MAP_ANON | MAP_PRIVATE, 0, 0);
128 n_assert(ret != nullptr);
129 return ret;
130}
131
132//------------------------------------------------------------------------------
135__forceinline void
136DecommitVirtual(void* ptr, size_t size)
137{
138 auto ret = madvise(ptr, size, MADV_DONTNEED);
139 n_assert(ret == 0);
140 ret = mprotect(ptr, size, PROT_NONE);
141 n_assert(ret == 0);
142}
143
144//------------------------------------------------------------------------------
147__forceinline void
148CommitVirtual(void* ptr, size_t size)
149{
150 auto ret = mprotect(ptr, size, PROT_READ | PROT_WRITE);
151 explicit_bzero(ptr, size);
152 n_assert(ret == 0);
153}
154
155//------------------------------------------------------------------------------
158__forceinline void
159FreeVirtual(void* ptr, size_t size)
160{
161 auto ret = madvise(ptr, size, MADV_DONTNEED);
162 n_assert(ret == 0);
163 ret = munmap(ptr, size);
164 n_assert(ret == 0);
165}
166
167//------------------------------------------------------------------------------
171__forceinline void
172Copy(const void* from, void* to, size_t numBytes)
173{
174 if (numBytes > 0)
175 {
176 n_assert(0 != from);
177 n_assert(0 != to);
178 n_assert(from != to);
179 memcpy(to, from, numBytes);
180 }
181}
182
183//------------------------------------------------------------------------------
187__forceinline void
188Move(const void* from, void* to, size_t numBytes)
189{
190 if (numBytes > 0)
191 {
192 n_assert(0 != from);
193 n_assert(0 != to);
194 n_assert(from != to);
195 memmove(to, from, numBytes);
196 }
197}
198
199//------------------------------------------------------------------------------
203template <typename T>
204__forceinline void
205MoveElements(const T* from, T* to, size_t numElements)
206{
207 if (numElements > 0)
208 {
209 n_assert(0 != from);
210 n_assert(0 != to);
211 n_assert(from != to);
212 if constexpr (std::is_trivially_move_assignable<T>::value && std::is_trivially_move_constructible<T>::value)
213 {
214 memmove((void*)to, (const void*)from, numElements * sizeof(T));
215 }
216 else
217 {
218 std::move(from, from + numElements, to);
219 }
220 }
221}
222
223//------------------------------------------------------------------------------
227template <typename T>
228__forceinline void
229CopyElements(const T* from, T* to, size_t numElements)
230{
231 if (numElements > 0)
232 {
233 n_assert(0 != from);
234 n_assert(0 != to);
235 n_assert(from != to);
236 if constexpr (std::is_trivially_copyable<T>::value)
237 {
238 memcpy(to, from, numElements * sizeof(T));
239 }
240 else
241 {
242 std::copy(from, from + numElements, to);
243 }
244 }
245}
246
247//------------------------------------------------------------------------------
252__forceinline void
253CopyToGraphicsMemory(const void* from, void* to, size_t numBytes)
254{
255 // no special handling on the Win32 platform
256 Memory::Copy(from, to, numBytes);
257}
258
259//------------------------------------------------------------------------------
263__forceinline void
264Clear(void* ptr, size_t numBytes)
265{
266 memset(ptr, 0, numBytes);
267}
268
269//------------------------------------------------------------------------------
273__forceinline void
274Fill(void* ptr, size_t numBytes, unsigned char value)
275{
276 memset(ptr, value, numBytes);
277}
278
279//------------------------------------------------------------------------------
284__forceinline char*
285DuplicateCString(const char* from)
286{
287 n_assert(0 != from);
288 size_t len = (unsigned int) strlen(from) + 1;
289 char* to = (char*) Memory::Alloc(Memory::StringDataHeap, len);
290 Memory::Copy((void*)from, to, len);
291 return to;
292}
293
294//------------------------------------------------------------------------------
298inline bool
299IsOverlapping(const unsigned char* srcPtr, size_t srcSize, const unsigned char* dstPtr, size_t dstSize)
300{
301 if (srcPtr == dstPtr)
302 {
303 return true;
304 }
305 else if (srcPtr > dstPtr)
306 {
307 return (srcPtr + srcSize) > dstPtr;
308 }
309 else
310 {
311 return (dstPtr + dstSize) > srcPtr;
312 }
313}
314
315//------------------------------------------------------------------------------
321{
322 unsigned int totalPhysical;
323 unsigned int availPhysical;
324 unsigned int totalVirtual;
325 unsigned int availVirtual;
326};
327
330{
331#if 0
332 MEMORYSTATUS stats = { NULL };
333 GlobalMemoryStatus(&stats);
334 TotalMemoryStatus result;
335 result.totalPhysical = (unsigned int) stats.dwTotalPhys;
336 result.availPhysical = (unsigned int) stats.dwAvailPhys;
337 result.totalVirtual = (unsigned int) stats.dwTotalVirtual;
338 result.availVirtual = (unsigned int) stats.dwAvailVirtual;
339 return result;
340#else
341 TotalMemoryStatus result;
342 return result;
343#endif
344}
345
346//------------------------------------------------------------------------------
352#if NEBULA_MEMORY_STATS
353extern bool Validate();
354#endif
355
356} // namespace Memory
357//------------------------------------------------------------------------------
358#endif
359
Nebula debug macros.
#define n_assert(exp)
Definition debug.h:50
Nebula compiler specific defines and configuration.
Definition arenaallocator.h:31
__forceinline unsigned int align(unsigned int alignant, unsigned int alignment)
Definition memory.h:21
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:188
__forceinline void FreeVirtual(void *ptr, size_t size)
free virtual memory
Definition posixmemory.h:159
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 TotalAllocSize
Definition win32memory.cc:17
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:148
__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:229
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
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:125
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:205
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:136
__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:253
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
int volatile HeapTypeAllocSize[NumHeapTypes]
Definition win32memory.cc:19
Math::float2 size
Definition histogramcontext.cc:43
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