action: record last fence release from the current thread
[c11tester.git] / mymemory.h
1 /** @file mymemory.h
2  *  @brief Memory allocation functions.
3  */
4
5 #ifndef _MY_MEMORY_H
6 #define _MY_MEMORY_H
7 #include <stdlib.h>
8 #include <limits>
9
10 #include "config.h"
11
12 /** MEMALLOC declares the allocators for a class to allocate
13  *      memory in the non-snapshotting heap. */
14 #define MEMALLOC \
15         void * operator new(size_t size) { \
16                 return model_malloc(size); \
17         } \
18         void operator delete(void *p, size_t size) { \
19                 model_free(p); \
20         } \
21         void * operator new[](size_t size) { \
22                 return model_malloc(size); \
23         } \
24         void operator delete[](void *p, size_t size) { \
25                 model_free(p); \
26         }
27
28 /** SNAPSHOTALLOC declares the allocators for a class to allocate
29  *      memory in the snapshotting heap. */
30 #define SNAPSHOTALLOC \
31         void * operator new(size_t size) { \
32                 return snapshot_malloc(size); \
33         } \
34         void operator delete(void *p, size_t size) { \
35                 snapshot_free(p); \
36         } \
37         void * operator new[](size_t size) { \
38                 return snapshot_malloc(size); \
39         } \
40         void operator delete[](void *p, size_t size) { \
41                 snapshot_free(p); \
42         }
43
44 void *model_malloc(size_t size);
45 void *model_calloc(size_t count, size_t size);
46 void model_free(void *ptr);
47
48 void * snapshot_malloc(size_t size);
49 void * snapshot_calloc(size_t count, size_t size);
50 void * snapshot_realloc(void *ptr, size_t size);
51 void snapshot_free(void *ptr);
52
53 /** @brief Provides a non-snapshotting allocator for use in STL classes.
54  *
55  * The code was adapted from a code example from the book The C++
56  * Standard Library - A Tutorial and Reference by Nicolai M. Josuttis,
57  * Addison-Wesley, 1999 © Copyright Nicolai M. Josuttis 1999
58  * Permission to copy, use, modify, sell and distribute this software
59  * is granted provided this copyright notice appears in all copies.
60  * This software is provided "as is" without express or implied
61  * warranty, and with no claim as to its suitability for any purpose.
62  */
63 template <class T>
64 class ModelAlloc {
65  public:
66         // type definitions
67         typedef T        value_type;
68         typedef T*       pointer;
69         typedef const T* const_pointer;
70         typedef T&       reference;
71         typedef const T& const_reference;
72         typedef size_t   size_type;
73         typedef size_t   difference_type;
74
75         // rebind allocator to type U
76         template <class U>
77         struct rebind {
78                 typedef ModelAlloc<U> other;
79         };
80
81         // return address of values
82         pointer address(reference value) const {
83                 return &value;
84         }
85         const_pointer address(const_reference value) const {
86                 return &value;
87         }
88
89         /* constructors and destructor
90          * - nothing to do because the allocator has no state
91          */
92         ModelAlloc() throw() {
93         }
94         ModelAlloc(const ModelAlloc&) throw() {
95         }
96         template <class U>
97         ModelAlloc(const ModelAlloc<U>&) throw() {
98         }
99         ~ModelAlloc() throw() {
100         }
101
102         // return maximum number of elements that can be allocated
103         size_type max_size() const throw() {
104                 return std::numeric_limits<size_t>::max() / sizeof(T);
105         }
106
107         // allocate but don't initialize num elements of type T
108         pointer allocate(size_type num, const void * = 0) {
109                 pointer p = (pointer)model_malloc(num * sizeof(T));
110                 return p;
111         }
112
113         // initialize elements of allocated storage p with value value
114         void construct(pointer p, const T& value) {
115                 // initialize memory with placement new
116                 new((void*)p)T(value);
117         }
118
119         // destroy elements of initialized storage p
120         void destroy(pointer p) {
121                 // destroy objects by calling their destructor
122                 p->~T();
123         }
124
125         // deallocate storage p of deleted elements
126         void deallocate(pointer p, size_type num) {
127                 model_free((void*)p);
128         }
129 };
130
131 /** Return that all specializations of this allocator are interchangeable. */
132 template <class T1, class T2>
133 bool operator ==(const ModelAlloc<T1>&,
134                 const ModelAlloc<T2>&) throw() {
135         return true;
136 }
137
138 /** Return that all specializations of this allocator are interchangeable. */
139 template <class T1, class T2>
140 bool operator!= (const ModelAlloc<T1>&,
141                 const ModelAlloc<T2>&) throw() {
142         return false;
143 }
144
145 /** @brief Provides a snapshotting allocator for use in STL classes.
146  *
147  * The code was adapted from a code example from the book The C++
148  * Standard Library - A Tutorial and Reference by Nicolai M. Josuttis,
149  * Addison-Wesley, 1999 © Copyright Nicolai M. Josuttis 1999
150  * Permission to copy, use, modify, sell and distribute this software
151  * is granted provided this copyright notice appears in all copies.
152  * This software is provided "as is" without express or implied
153  * warranty, and with no claim as to its suitability for any purpose.
154  */
155 template <class T>
156 class SnapshotAlloc {
157  public:
158         // type definitions
159         typedef T        value_type;
160         typedef T*       pointer;
161         typedef const T* const_pointer;
162         typedef T&       reference;
163         typedef const T& const_reference;
164         typedef size_t   size_type;
165         typedef size_t   difference_type;
166
167         // rebind allocator to type U
168         template <class U>
169         struct rebind {
170                 typedef SnapshotAlloc<U> other;
171         };
172
173         // return address of values
174         pointer address(reference value) const {
175                 return &value;
176         }
177         const_pointer address(const_reference value) const {
178                 return &value;
179         }
180
181         /* constructors and destructor
182          * - nothing to do because the allocator has no state
183          */
184         SnapshotAlloc() throw() {
185         }
186         SnapshotAlloc(const SnapshotAlloc&) throw() {
187         }
188         template <class U>
189         SnapshotAlloc(const SnapshotAlloc<U>&) throw() {
190         }
191         ~SnapshotAlloc() throw() {
192         }
193
194         // return maximum number of elements that can be allocated
195         size_type max_size() const throw() {
196                 return std::numeric_limits<size_t>::max() / sizeof(T);
197         }
198
199         // allocate but don't initialize num elements of type T
200         pointer allocate(size_type num, const void * = 0) {
201                 pointer p = (pointer)snapshot_malloc(num * sizeof(T));
202                 return p;
203         }
204
205         // initialize elements of allocated storage p with value value
206         void construct(pointer p, const T& value) {
207                 // initialize memory with placement new
208                 new((void*)p)T(value);
209         }
210
211         // destroy elements of initialized storage p
212         void destroy(pointer p) {
213                 // destroy objects by calling their destructor
214                 p->~T();
215         }
216
217         // deallocate storage p of deleted elements
218         void deallocate(pointer p, size_type num) {
219                 snapshot_free((void*)p);
220         }
221 };
222
223 /** Return that all specializations of this allocator are interchangeable. */
224 template <class T1, class T2>
225 bool operator ==(const SnapshotAlloc<T1>&,
226                 const SnapshotAlloc<T2>&) throw() {
227         return true;
228 }
229
230 /** Return that all specializations of this allocator are interchangeable. */
231 template <class T1, class T2>
232 bool operator!= (const SnapshotAlloc<T1>&,
233                 const SnapshotAlloc<T2>&) throw() {
234         return false;
235 }
236
237 #ifdef __cplusplus
238 extern "C" {
239 #endif
240         typedef void * mspace;
241         extern void * mspace_malloc(mspace msp, size_t bytes);
242         extern void mspace_free(mspace msp, void* mem);
243         extern void * mspace_realloc(mspace msp, void* mem, size_t newsize);
244         extern void * mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
245         extern mspace create_mspace_with_base(void* base, size_t capacity, int locked);
246         extern mspace create_mspace(size_t capacity, int locked);
247
248 #if USE_MPROTECT_SNAPSHOT
249         extern mspace user_snapshot_space;
250 #endif
251
252         extern mspace model_snapshot_space;
253
254 #ifdef __cplusplus
255 };  /* end of extern "C" */
256 #endif
257
258 #endif /* _MY_MEMORY_H */