-
-
Notifications
You must be signed in to change notification settings - Fork 231
/
Copy pathmem.h
193 lines (162 loc) · 4.97 KB
/
mem.h
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*
* Copyright 2006-2022 René Ferdinand Rivera Morell
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE.txt or copy at
* https://www.bfgroup.xyz/b2/LICENSE.txt)
*/
#ifndef BJAM_MEM_H
#define BJAM_MEM_H
#include "config.h"
#include <cstdlib>
#include <memory>
#define bjam_malloc_x(s) std::malloc(s)
#define bjam_calloc_x(n, s) std::calloc(n, s)
#define bjam_realloc_x(p, s) std::realloc(p, s)
#define bjam_free_x(p) std::free(p)
#ifndef bjam_malloc_atomic_x
#define bjam_malloc_atomic_x(s) bjam_malloc_x(s)
#endif
#ifndef bjam_calloc_atomic_x
#define bjam_calloc_atomic_x(n, s) bjam_calloc_x(n, s)
#endif
#ifndef bjam_mem_init_x
#define bjam_mem_init_x()
#endif
#ifndef bjam_mem_close_x
#define bjam_mem_close_x()
#endif
#ifndef bjam_malloc_raw_x
#define bjam_malloc_raw_x(s) bjam_malloc_x(s)
#endif
#ifndef bjam_calloc_raw_x
#define bjam_calloc_raw_x(n, s) bjam_calloc_x(n, s)
#endif
#ifndef bjam_realloc_raw_x
#define bjam_realloc_raw_x(p, s) bjam_realloc_x(p, s)
#endif
#ifndef bjam_free_raw_x
#define bjam_free_raw_x(p) bjam_free_x(p)
#endif
#ifdef OPT_DEBUG_PROFILE
/* Profile tracing of memory allocations. */
#include "debug.h"
#define BJAM_MALLOC(s) (profile_memory(s), bjam_malloc_x(s))
#define BJAM_MALLOC_ATOMIC(s) (profile_memory(s), bjam_malloc_atomic_x(s))
#define BJAM_CALLOC(n, s) (profile_memory(n * s), bjam_calloc_x(n, s))
#define BJAM_CALLOC_ATOMIC(n, s) \
(profile_memory(n * s), bjam_calloc_atomic_x(n, s))
#define BJAM_REALLOC(p, s) (profile_memory(s), bjam_realloc_x(p, s))
#define BJAM_MALLOC_RAW(s) (profile_memory(s), bjam_malloc_raw_x(s))
#define BJAM_CALLOC_RAW(n, s) (profile_memory(n * s), bjam_calloc_raw_x(n, s))
#define BJAM_REALLOC_RAW(p, s) (profile_memory(s), bjam_realloc_raw_x(p, s))
#else
/* No mem tracing. */
#define BJAM_MALLOC(s) bjam_malloc_x(s)
#define BJAM_MALLOC_ATOMIC(s) bjam_malloc_atomic_x(s)
#define BJAM_CALLOC(n, s) bjam_calloc_x(n, s)
#define BJAM_CALLOC_ATOMIC(n, s) bjam_calloc_atomic_x(n, s)
#define BJAM_REALLOC(p, s) bjam_realloc_x(p, s)
#define BJAM_MALLOC_RAW(s) bjam_malloc_raw_x(s)
#define BJAM_CALLOC_RAW(n, s) bjam_calloc_raw_x(n, s)
#define BJAM_REALLOC_RAW(p, s) bjam_realloc_raw_x(p, s)
#endif
#define BJAM_MEM_INIT() bjam_mem_init_x()
#define BJAM_MEM_CLOSE() bjam_mem_close_x()
#define BJAM_FREE(p) bjam_free_x(p)
#define BJAM_FREE_RAW(p) bjam_free_raw_x(p)
namespace b2 { namespace jam {
// Zero-init and call constructor at the given pre-allocated memory.
template <typename T, typename... Args>
T * ctor_ptr(void * p, Args &&... args)
{
std::memset(p, 0, sizeof(T));
return new (p) T(std::forward<Args>(args)...);
}
// Call destructor at the given memory.
template <typename T>
void dtor_ptr(T * p)
{
p->~T();
}
// Allocate memory and construct a type with args.
template <typename T, typename... Args>
T * make_ptr(Args &&... args)
{
return ctor_ptr<T>(BJAM_MALLOC(sizeof(T)), std::forward<Args>(args)...);
}
// Allocate memory, with tail padding, and construct a type with args.
template <typename T, typename... Args>
T * make_ptr_extra(std::size_t padding, Args &&... args)
{
return ctor_ptr<T>(
BJAM_MALLOC(sizeof(T) + padding), std::forward<Args>(args)...);
}
// Destructs and deallocates an object.
template <typename T>
void free_ptr(T * p)
{
dtor_ptr(p);
BJAM_FREE(p);
}
// Unique ptr deleter that destructs and frees the memory.
template <typename T>
struct unique_jptr_deleter
{
void operator()(T * p) const
{
p->~T();
BJAM_FREE(p);
}
};
// Unique ptr that will delete and free using the jam memory functions.
template <typename T>
using unique_jptr = std::unique_ptr<T, unique_jptr_deleter<T>>;
// Allocate and construct an object with args using the jam memory functions.
template <typename T, typename... Args>
unique_jptr<T> make_unique_jptr(Args &&... args)
{
return unique_jptr<T>(make_ptr<T>(std::forward<Args>(args)...));
}
// Allocate, with tail padding, and construct an object with args using the jam
// memory functions.
template <typename T, typename... Args>
unique_jptr<T> make_unique_jptr_extra(std::size_t padding, Args &&... args)
{
return unique_jptr<T>(
make_ptr_extra<T>(padding, std::forward<Args>(args)...));
}
template <typename T>
struct unique_jptr_free
{
using free_f = void (*)(T *);
explicit unique_jptr_free(free_f f)
: free_function(f)
{}
unique_jptr_free(unique_jptr_free && p)
: free_function(std::move(p.free_function))
{
p.free_function = nullptr;
}
void operator()(T * p) const
{
// if (free_function)
if (p) (*free_function)(p);
}
private:
free_f free_function = nullptr;
};
template <typename T>
using unique_bare_jptr = std::unique_ptr<T, unique_jptr_free<T>>;
template <typename T, typename F>
unique_bare_jptr<T> make_unique_bare_jptr(T * p, F exit_f)
{
return unique_bare_jptr<T>(p, unique_jptr_free<T>(exit_f));
}
template <typename T, typename F, typename G>
unique_bare_jptr<T> make_unique_bare_jptr(T * p, F enter_f, G exit_f)
{
enter_f(p);
return unique_bare_jptr<T>(p, unique_jptr_free<T>(exit_f));
}
}} // namespace b2::jam
#endif