Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * Portions of this file are copyright Rebirth contributors and licensed as
3
 * described in COPYING.txt.
4
 * Portions of this file are copyright Parallax Software and licensed
5
 * according to the Parallax license below.
6
 * See COPYING.txt for license details.
7
 
8
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
9
SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
10
END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
11
ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
12
IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
13
SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
14
FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
15
CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
16
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
17
COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
18
*/
19
 
20
#pragma once
21
 
22
#include <stdlib.h>
23
#include <type_traits>
24
 
25
#ifdef __cplusplus
26
#include <memory>
27
#include "dxxsconf.h"
28
#include "dsx-ns.h"
29
#include <utility>
30
 
31
#define MEM_K 1.5       // Dynamic array growth factor
32
 
33
#ifdef DEBUG_BIAS_MEMORY_ALLOCATIONS
34
#include <array>
35
#define DXX_DEBUG_BIAS_MEMORY_ALLOCATION (sizeof(std::array<double, 2>))
36
#else
37
#define DXX_DEBUG_BIAS_MEMORY_ALLOCATION (0)
38
#endif
39
 
40
namespace dcx {
41
 
42
#ifdef DEBUG_MEMORY_ALLOCATIONS
43
void mem_init(void);
44
 
45
void mem_display_blocks();
46
__attribute_alloc_size(1)
47
__attribute_malloc()
48
void *mem_malloc(size_t size, const char *var, const char *file, unsigned line);
49
void * mem_calloc( size_t nmemb, size_t size, const char * var, const char * filename, unsigned line) __attribute_alloc_size(1,2) __attribute_malloc();
50
__attribute_alloc_size(2)
51
void *mem_realloc(void *buffer, size_t size, const char *var, const char *file, unsigned line);
52
extern void mem_free( void * buffer );
53
 
54
/* DPH: Changed malloc, etc. to d_malloc. Overloading system calls is very evil and error prone */
55
 
56
// Checks to see if any blocks are overwritten
57
void mem_validate_heap();
58
 
59
#define mem_calloc(nmemb,size,var,file,line)    ((mem_calloc)((size) ? (nmemb) : 0, (size), (var), (file), (line)))
60
 
61
#else
62
 
63
#ifdef DEBUG_BIAS_MEMORY_ALLOCATIONS
64
#define bias_malloc(SIZE)       ({      \
65
                auto p = malloc((SIZE) + DXX_DEBUG_BIAS_MEMORY_ALLOCATION);     \
66
                p ? p + DXX_DEBUG_BIAS_MEMORY_ALLOCATION : p;   \
67
        })
68
/* Bias calloc wastes a bit extra to keep the math simple */
69
#define bias_calloc(NMEMB,SIZE) ({      \
70
                auto p = calloc((NMEMB), (SIZE) + DXX_DEBUG_BIAS_MEMORY_ALLOCATION);    \
71
                p ? p + DXX_DEBUG_BIAS_MEMORY_ALLOCATION : p;   \
72
        })
73
#define bias_realloc(PTR,SIZE)  ({      \
74
                auto p = realloc(reinterpret_cast<char *>(PTR) - DXX_DEBUG_BIAS_MEMORY_ALLOCATION, (SIZE) + DXX_DEBUG_BIAS_MEMORY_ALLOCATION);  \
75
                p ? p + DXX_DEBUG_BIAS_MEMORY_ALLOCATION : p;   \
76
        })
77
#define bias_free(PTR)  free(reinterpret_cast<char *>(PTR) - DXX_DEBUG_BIAS_MEMORY_ALLOCATION)
78
#else
79
#define bias_malloc     malloc
80
#define bias_calloc calloc
81
#define bias_realloc realloc
82
#define bias_free free
83
#endif
84
 
85
#define mem_malloc(size,var,file,line)  ((void)var,(void)file,(void)line,bias_malloc((size)))
86
#define mem_calloc(nmemb,size,var,file,line)    ((void)var,(void)file,(void)line,bias_calloc((nmemb),(size)))
87
#define mem_realloc(ptr,size,var,file,line)     ((void)var,(void)file,(void)line,bias_realloc((ptr),(size)))
88
#define mem_free        bias_free
89
 
90
static inline void mem_init(void)
91
{
92
}
93
#endif
94
 
95
template <typename T>
96
T *MALLOC(T *&r, std::size_t count, const char *var, const char *file, unsigned line)
97
{
98
        static_assert(std::is_pod<T>::value, "MALLOC cannot allocate non-POD");
99
        return r = reinterpret_cast<T *>(mem_malloc(count * sizeof(T), var, file, line));
100
}
101
 
102
template <typename T>
103
T *CALLOC(T *&r, std::size_t count, const char *var, const char *file, unsigned line)
104
{
105
        static_assert(std::is_pod<T>::value, "CALLOC cannot allocate non-POD");
106
        return r = reinterpret_cast<T *>(mem_calloc(count, sizeof(T), var, file, line));
107
}
108
 
109
#define d_malloc(size)      mem_malloc((size),"Unknown", __FILE__,__LINE__ )
110
#define d_realloc(ptr,size) mem_realloc((ptr),(size),"Unknown", __FILE__,__LINE__ )
111
template <typename T>
112
static inline void d_free(T *&ptr)
113
{
114
        static_assert((std::is_same<T, void>::value || std::is_pod<T>::value), "d_free cannot free non-POD");
115
        mem_free(std::exchange(ptr, nullptr));
116
}
117
 
118
template <typename T>
119
class RAIIdmem_deleter
120
{
121
public:
122
        void operator()(T *v) const
123
        {
124
                d_free(v);
125
        }
126
};
127
 
128
template <typename T>
129
class RAIIdmem_deleter<T[]> : public RAIIdmem_deleter<T>
130
{
131
public:
132
        typedef T *pointer;
133
};
134
 
135
template <typename T>
136
class RAIIdmem : public std::unique_ptr<T, RAIIdmem_deleter<T>>
137
{
138
        typedef std::unique_ptr<T, RAIIdmem_deleter<T>> base_ptr;
139
public:
140
        static_assert(std::is_pod<typename base_ptr::element_type>::value, "RAIIdmem cannot manage non-POD");
141
        DXX_INHERIT_CONSTRUCTORS(RAIIdmem, base_ptr);
142
};
143
 
144
/* Disallow C-style arrays of known bound.  Use RAIIdmem<std::array<T, N>>
145
 * for this case.
146
 */
147
template <typename T, std::size_t N>
148
class RAIIdmem<T[N]>
149
{
150
public:
151
        RAIIdmem() = delete;
152
};
153
 
154
template <typename T>
155
RAIIdmem<T> &MALLOC(RAIIdmem<T> &r, std::size_t count, const char *var, const char *file, unsigned line)
156
{
157
        typename RAIIdmem<T>::pointer p;
158
        return r.reset(MALLOC<typename RAIIdmem<T>::element_type>(p, count, var, file, line)), r;
159
}
160
 
161
template <typename T>
162
RAIIdmem<T[]> &MALLOC(RAIIdmem<T[]> &r, const std::size_t count, const char *const var, const char *const file, const unsigned line)
163
{
164
        return MALLOC<T[]>(r, count, var, file, line);
165
}
166
 
167
template <typename T>
168
void CALLOC(RAIIdmem<T> &r, std::size_t count, const char *var, const char *file, unsigned line)
169
{
170
        typename RAIIdmem<T>::pointer p;
171
        r.reset(CALLOC<typename RAIIdmem<T>::element_type>(p, count, var, file, line));
172
}
173
 
174
#define MALLOC( var, type, count )      (MALLOC<type>(var, (count),#var, __FILE__,__LINE__ ))
175
#define CALLOC( var, type, count )      (CALLOC<type>(var, (count),#var, __FILE__,__LINE__ ))
176
 
177
}
178
 
179
#endif