]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/unordered/test/helpers/memory.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / unordered / test / helpers / memory.hpp
CommitLineData
7c673cae
FG
1
2// Copyright 2006-2009 Daniel James.
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#if !defined(BOOST_UNORDERED_TEST_MEMORY_HEADER)
7#define BOOST_UNORDERED_TEST_MEMORY_HEADER
8
7c673cae 9#include "../helpers/test.hpp"
b32b8144
FG
10#include <boost/assert.hpp>
11#include <boost/unordered/detail/implementation.hpp>
12#include <map>
13#include <memory>
7c673cae 14
b32b8144
FG
15namespace test {
16 namespace detail {
17 struct memory_area
7c673cae 18 {
b32b8144
FG
19 void const* start;
20 void const* end;
21
22 memory_area(void const* s, void const* e) : start(s), end(e)
23 {
24 BOOST_ASSERT(start != end);
25 }
26 };
27
28 struct memory_track
29 {
30 explicit memory_track(int tag = -1) : constructed_(0), tag_(tag) {}
31
32 int constructed_;
33 int tag_;
34 };
35
36 // This is a bit dodgy as it defines overlapping
37 // areas as 'equal', so this isn't a total ordering.
38 // But it is for non-overlapping memory regions - which
39 // is what'll be stored.
40 //
41 // All searches will be for areas entirely contained by
42 // a member of the set - so it should find the area that contains
43 // the region that is searched for.
44
45 struct memory_area_compare
46 {
47 bool operator()(memory_area const& x, memory_area const& y) const
48 {
49 return x.end <= y.start;
50 }
51 };
7c673cae 52
b32b8144 53 struct memory_tracker
7c673cae 54 {
b32b8144
FG
55 typedef std::map<memory_area, memory_track, memory_area_compare,
56 std::allocator<std::pair<memory_area const, memory_track> > >
57 allocated_memory_type;
58
59 allocated_memory_type allocated_memory;
60 unsigned int count_allocators;
61 unsigned int count_allocations;
62 unsigned int count_constructions;
63 bool tracking_constructions;
64
65 memory_tracker()
66 : count_allocators(0), count_allocations(0), count_constructions(0),
67 tracking_constructions(true)
68 {
69 }
70
71 ~memory_tracker() { BOOST_TEST(count_allocators == 0); }
72
73 void allocator_ref()
74 {
75 if (count_allocators == 0) {
76 count_allocations = 0;
77 count_constructions = 0;
78 allocated_memory.clear();
79 }
80 ++count_allocators;
81 }
82
83 void allocator_unref()
84 {
85 BOOST_TEST(count_allocators > 0);
86 if (count_allocators > 0) {
87 --count_allocators;
88 if (count_allocators == 0) {
89 bool no_allocations_left = (count_allocations == 0);
90 bool no_constructions_left = (count_constructions == 0);
91 bool allocated_memory_empty = allocated_memory.empty();
92
93 // Clearing the data before the checks terminate the
94 // tests.
95 count_allocations = 0;
96 count_constructions = 0;
97 allocated_memory.clear();
98
99 BOOST_TEST(no_allocations_left);
100 BOOST_TEST(no_constructions_left);
101 BOOST_TEST(allocated_memory_empty);
102 }
103 }
104 }
105
106 void track_allocate(void* ptr, std::size_t n, std::size_t size, int tag)
107 {
108 if (n == 0) {
109 BOOST_ERROR("Allocating 0 length array.");
110 } else {
111 ++count_allocations;
112 allocated_memory.insert(std::pair<memory_area const, memory_track>(
113 memory_area(ptr, (char*)ptr + n * size), memory_track(tag)));
114 }
115 }
116
117 void track_deallocate(void* ptr, std::size_t n, std::size_t size, int tag,
118 bool check_tag_ = true)
119 {
120 allocated_memory_type::iterator pos =
121 allocated_memory.find(memory_area(ptr, (char*)ptr + n * size));
122 if (pos == allocated_memory.end()) {
123 BOOST_ERROR("Deallocating unknown pointer.");
124 } else {
125 BOOST_TEST(pos->first.start == ptr);
126 BOOST_TEST(pos->first.end == (char*)ptr + n * size);
127 if (check_tag_)
128 BOOST_TEST(pos->second.tag_ == tag);
129 allocated_memory.erase(pos);
7c673cae 130 }
b32b8144
FG
131 BOOST_TEST(count_allocations > 0);
132 if (count_allocations > 0)
133 --count_allocations;
134 }
135
136 void track_construct(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
137 {
138 if (tracking_constructions) {
139 ++count_constructions;
140 }
141 }
142
143 void track_destroy(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
144 {
145 if (tracking_constructions) {
146 BOOST_TEST(count_constructions > 0);
147 if (count_constructions > 0)
148 --count_constructions;
149 }
150 }
151 };
152 }
153
154 namespace detail {
155 // This won't be a problem as I'm only using a single compile unit
156 // in each test (this is actually required by the minimal test
157 // framework).
158 //
159 // boostinspect:nounnamed
160 namespace {
161 test::detail::memory_tracker tracker;
7c673cae 162 }
b32b8144
FG
163 }
164
165 namespace detail {
166 struct disable_construction_tracking
167 {
168 bool old_value;
169
170 disable_construction_tracking()
171 : old_value(detail::tracker.tracking_constructions)
172 {
173 test::detail::tracker.tracking_constructions = false;
174 }
175
176 ~disable_construction_tracking()
177 {
178 test::detail::tracker.tracking_constructions = old_value;
179 }
180
181 private:
182 disable_construction_tracking(disable_construction_tracking const&);
183 disable_construction_tracking& operator=(
184 disable_construction_tracking const&);
185 };
186 }
7c673cae
FG
187}
188
189#endif