-
Notifications
You must be signed in to change notification settings - Fork 320
/
Copy pathbslma_mallocfreeallocator.h
242 lines (215 loc) · 9.37 KB
/
bslma_mallocfreeallocator.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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// bslma_mallocfreeallocator.h -*-C++-*-
#ifndef INCLUDED_BSLMA_MALLOCFREEALLOCATOR
#define INCLUDED_BSLMA_MALLOCFREEALLOCATOR
#include <bsls_ident.h>
BSLS_IDENT("$Id: $")
//@PURPOSE: Provide malloc/free adaptor to 'bslma::Allocator' protocol.
//
//@CLASSES:
// bslma::MallocFreeAllocator: support malloc/free style allocate/deallocate
//
//@SEE_ALSO: bslma_newdeleteallocator, bslma_allocator
//
//@DESCRIPTION: This component provides an allocator,
// 'bslma::MallocFreeAllocator', that implements the 'bslma::Allocator'
// protocol and supplies memory using the system-supplied (native)
// 'std::malloc' and 'std::free' operators.
//..
// ,--------------------------.
// ( bslma::MallocFreeAllocator )
// `--------------------------'
// | ctor/dtor
// | singleton
// V
// ,----------------.
// ( bslma::Allocator )
// `----------------'
// allocate
// deallocate
//..
// The key purpose of this component is to facilitate the use of 'malloc' and
// 'free' when the default 'bslma::NewDeleteAllocator' is not desirable (such
// as the case of 'bslma::TestAllocator'). To accomplish this goal, 'malloc'
// and 'free' are wrapped in a singleton object whose lifetime is guaranteed to
// exceed any possibility of its use.
//
///Thread Safety
///-------------
// A single object of 'bslma::MallocFreeAllocator' is safe for concurrent
// access by multiple threads. The underlying implementation of 'malloc' and
// 'free' will ensure that heap corruption does not occur. Note that this
// allocator therefore has a stronger thread safety guarantee than is required
// by the base-class contract or than is provided by other allocators.
//
///Usage
///-----
// This component is intended to be used when the use of 'new' and 'delete' are
// not desirable, such as the case of 'bslma::TestAllocator'. Instead of using
// 'bslma::Default' which uses the 'bslma::NewDeleteAllocator', this component
// can be used to bypass the use of 'new' and 'delete'.
//
// The following example demonstrates the use of this component for a user
// defined allocator instead of using the default allocator:
//..
// // my_allocator.h
// // ...
//
// class my_Allocator : public bslma::Allocator {
// // This class provides a mechanism for allocation and deallocation.
//
// // DATA
// bslma::Allocator *d_allocator_p; // allocator (held, not owned)
//
// public:
// // CREATORS
// my_Allocator(bslma::Allocator *basicAllocator = 0);
// // Create a 'my_Allcoator'. Optionally specify 'basicAllocator' to
// // supply memory. If 'basicAllocator' is 0, the
// // 'bslma::MallocFreeAllocator' will be used.
//
// ~my_Allocator();
// // Destroy this allocator. Note that the behavior of destroying an
// // allocator while memory is allocated from it is not specified.
// // (Unless you *know* that it is valid to do so, don't!)
//
// // MANIPULATORS
// void *allocate(size_type size);
// // Return a newly allocated block of memory of (at least) the
// // specified positive 'size' (bytes). If 'size' is 0, a null
// // pointer is returned with no effect. Note that the alignment of
// // the address returned is the maximum alignment for any
// // fundamental type defined for this platform.
//
// void deallocate(void *address);
// // Return the memory at the specified 'address' back to this
// // allocator. If 'address' is 0, this function has no effect. The
// // behavior is undefined if 'address' was not allocated using this
// // allocator, or has already been deallocated.
// };
//..
// The constructor is implemented using 'bslma::MallocFreeAllocator'.
//..
// // my_allocator.cpp
// // ...
//
// // CREATORS
// my_Allocator::my_Allocator(bslma::Allocator *basicAllocator)
// : d_allocator_p(basicAllocator
// ? basicAllocator
// : &bslma::MallocFreeAllocator::singleton())
// {
// }
//
// // ...
//..
// When the 'basicAllocator' is not specified, the 'bslma::MallocFreeAllocator'
// will be used. That allocator then then calls 'std::malloc' and 'std::free'
// for allocating and deallocating memory.
#include <bslscm_version.h>
#include <bslma_allocator.h>
#include <cstdlib> // 'std::malloc', 'std::free'
namespace BloombergLP {
namespace bslma {
// =========================
// class MallocFreeAllocator
// =========================
class MallocFreeAllocator : public Allocator {
// This class provides direct access to the system-supplied (native) global
// 'std::malloc' and 'std::free'. A 'static' method is provided for
// obtaining a unique, process wide object of this class, which is valid
// from the time the method is called until after the program (not just
// 'main') exits.
private:
// NOT IMPLEMENTED
MallocFreeAllocator(const MallocFreeAllocator&);
MallocFreeAllocator& operator=(const MallocFreeAllocator&);
public:
// CLASS METHODS
static MallocFreeAllocator& singleton();
// Return a reference to a valid object of this class. Note that this
// object is guaranteed to be valid from the time of this call onward
// (i.e., not just until exiting 'main').
// CREATORS
MallocFreeAllocator();
// Create an allocator that uses 'std::malloc' and 'std::free' to
// supply memory. Note that all objects of this class share the same
// underlying resource.
virtual ~MallocFreeAllocator();
// Destroy this allocator. Note that the behavior of destroying an
// allocator while memory is allocated from it is not specified.
// (Unless you *know* that it is valid to do so, don't!)
//
// For this concrete implementation, destroying this allocator object
// has no effect on allocated memory.
// MANIPULATORS
virtual void *allocate(size_type size);
// Return a newly allocated block of memory of (at least) the specified
// positive 'size' (in bytes). If 'size' is 0, a null pointer is
// returned with no other effect. If this allocator cannot return the
// requested number of bytes, then it will return a null pointer. The
// behavior is undefined unless '0 <= size'. Note that the alignment
// of the address returned is the maximum alignment for any type
// defined on this platform. Also note that 'std::malloc' is *not*
// called when 'size' is 0 (in order to avoid having to acquire a lock,
// and potential contention in multi-treaded programs).
virtual void deallocate(void *address);
// Return the memory block at the specified 'address' back to this
// allocator. If 'address' is 0, this function has no effect. The
// behavior is undefined unless 'address' was allocated using this
// allocator object and has not already been deallocated. Note that
// 'std::free' is *not* called when 'address' is 0 (in order to avoid
// having to acquire a lock, and potential contention in multi-treaded
// programs).
};
// ============================================================================
// INLINE DEFINITIONS
// ============================================================================
// -------------------------
// class MallocFreeAllocator
// -------------------------
// CREATORS
inline
MallocFreeAllocator::MallocFreeAllocator()
{
}
inline
MallocFreeAllocator::~MallocFreeAllocator()
{
}
// MANIPULATORS
inline
void MallocFreeAllocator::deallocate(void *address)
{
// While the C and C++ standard guarantees that calling free(0) is safe
// (3.7.3.2 paragraph 3), some libc implementations take out a lock to deal
// with the free(0) case, so this check can improve efficiency of threaded
// programs.
if (address) {
std::free(address);
}
}
} // close package namespace
#ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY
// ============================================================================
// BACKWARD COMPATIBILITY
// ============================================================================
typedef bslma::MallocFreeAllocator bslma_MallocFreeAllocator;
// This alias is defined for backward compatibility.
#endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY
} // close enterprise namespace
#endif
// ----------------------------------------------------------------------------
// Copyright 2013 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------