aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/thekla_atlas/nvcore/Memory.cpp
blob: 302a2d84cb422c9a8890334336bc9070406996da (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// This code is in the public domain -- Ignacio Castaño <castano@gmail.com>

#include "Memory.h"
#include "Debug.h"
#include "Utils.h"

#include <stdlib.h>

#ifdef NV_OS_LINUX
#include <malloc.h>
#endif

#define USE_EFENCE 0

#if USE_EFENCE
extern "C" void *EF_malloc(size_t size);
extern "C" void *EF_realloc(void * oldBuffer, size_t newSize);
extern "C" void EF_free(void * address);
#endif

using namespace nv;

#if NV_OVERRIDE_ALLOC

void * malloc(size_t size)
{
#if USE_EFENCE
    return EF_malloc(size);
#else
    return ::malloc(size);
#endif
}

void * debug_malloc(size_t size, const char * file, int line)
{
    NV_UNUSED(file);
    NV_UNUSED(line);
#if USE_EFENCE
    return EF_malloc(size);
#else
    return ::malloc(size);
#endif
}

void free(void * ptr)
{
#if USE_EFENCE
    return EF_free(const_cast<void *>(ptr));
#else
    ::free(const_cast<void *>(ptr));
#endif
}

void * realloc(void * ptr, size_t size)
{
    nvDebugCheck(ptr != NULL || size != 0); // undefined realloc behavior.
#if USE_EFENCE
    return EF_realloc(ptr, size);
#else
    return ::realloc(ptr, size);
#endif
}


/* No need to override this unless we want line info.
void * operator new (size_t size) throw()
{
    return malloc(size);
}

void operator delete (void *p) throw()
{
    free(p);
}

void * operator new [] (size_t size) throw()
{
    return malloc(size);
}

void operator delete [] (void * p) throw()
{
    free(p);
}
*/

#if 0 // Code from Apple:
void* operator new(std::size_t sz) throw (std::bad_alloc)
{
        void *result = std::malloc (sz == 0 ? 1 : sz);
        if (result == NULL)
                throw std::bad_alloc();
        gNewCounter++;
        return result;
}
void operator delete(void* p) throw()
{
        if (p == NULL)
                return;
        std::free (p);
        gDeleteCounter++;
}

/* These are the 'nothrow' versions of the above operators.
   The system version will try to call a std::new_handler if they
   fail, but your overriding versions are not required to do this.  */
void* operator new(std::size_t sz, const std::nothrow_t&) throw()
{
        try {
                void * result = ::operator new (sz);  // calls our overridden operator new
                return result;
        } catch (std::bad_alloc &) {
          return NULL;
        }
}
void operator delete(void* p, const std::nothrow_t&) throw()
{
        ::operator delete (p);
}

#endif // 0

#endif // NV_OVERRIDE_ALLOC

void * nv::aligned_malloc(size_t size, size_t alignment)
{
    // alignment must be a power of two, multiple of sizeof(void*)
    nvDebugCheck(isPowerOfTwo(alignment));
    nvDebugCheck((alignment & (sizeof(void*) - 1)) == 0);

#if NV_OS_WIN32 || NV_OS_DURANGO
    return _aligned_malloc(size, alignment);
#elif NV_OS_DARWIN && !NV_OS_IOS
    void * ptr = NULL;
    posix_memalign(&ptr, alignment, size);
    return ptr;
#elif NV_OS_LINUX
    return memalign(alignment, size);
#else // NV_OS_ORBIS || NV_OS_IOS
    // @@ IC: iOS appears to be 16 byte aligned, should we check alignment and assert if we request a higher alignment factor?
    return ::malloc(size);
#endif
}

void nv::aligned_free(void * ptr)
{
#if NV_OS_WIN32 || NV_OS_DURANGO
    _aligned_free(ptr);
#else
    ::free(ptr);
#endif
}