]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/unordered/test/helpers/memory.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / unordered / test / helpers / memory.hpp
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
9 #include <memory>
10 #include <map>
11 #include <boost/assert.hpp>
12 #include <boost/unordered/detail/allocate.hpp>
13 #include "../helpers/test.hpp"
14
15 namespace test
16 {
17 namespace detail
18 {
19 struct memory_area {
20 void const* start;
21 void const* end;
22
23 memory_area(void const* s, void const* e)
24 : start(s), end(e)
25 {
26 BOOST_ASSERT(start != end);
27 }
28 };
29
30 struct memory_track {
31 explicit memory_track(int tag = -1) :
32 constructed_(0),
33 tag_(tag) {}
34
35 int constructed_;
36 int tag_;
37 };
38
39 // This is a bit dodgy as it defines overlapping
40 // areas as 'equal', so this isn't a total ordering.
41 // But it is for non-overlapping memory regions - which
42 // is what'll be stored.
43 //
44 // All searches will be for areas entirely contained by
45 // a member of the set - so it should find the area that contains
46 // the region that is searched for.
47
48 struct memory_area_compare {
49 bool operator()(memory_area const& x, memory_area const& y) const {
50 return x.end <= y.start;
51 }
52 };
53
54 struct memory_tracker {
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
64 memory_tracker() :
65 count_allocators(0), count_allocations(0),
66 count_constructions(0)
67 {}
68
69 void allocator_ref()
70 {
71 if(count_allocators == 0) {
72 count_allocations = 0;
73 count_constructions = 0;
74 allocated_memory.clear();
75 }
76 ++count_allocators;
77 }
78
79 void allocator_unref()
80 {
81 BOOST_TEST(count_allocators > 0);
82 if(count_allocators > 0) {
83 --count_allocators;
84 if(count_allocators == 0) {
85 bool no_allocations_left = (count_allocations == 0);
86 bool no_constructions_left = (count_constructions == 0);
87 bool allocated_memory_empty = allocated_memory.empty();
88
89 // Clearing the data before the checks terminate the
90 // tests.
91 count_allocations = 0;
92 count_constructions = 0;
93 allocated_memory.clear();
94
95 BOOST_TEST(no_allocations_left);
96 BOOST_TEST(no_constructions_left);
97 BOOST_TEST(allocated_memory_empty);
98 }
99 }
100 }
101
102 void track_allocate(void *ptr, std::size_t n, std::size_t size,
103 int tag)
104 {
105 if(n == 0) {
106 BOOST_ERROR("Allocating 0 length array.");
107 }
108 else {
109 ++count_allocations;
110 allocated_memory.insert(
111 std::pair<memory_area const, memory_track>(
112 memory_area(ptr, (char*) ptr + n * size),
113 memory_track(tag)));
114 }
115 }
116
117 void track_deallocate(void* ptr, std::size_t n, std::size_t size,
118 int tag, bool check_tag_ = true)
119 {
120 allocated_memory_type::iterator pos =
121 allocated_memory.find(
122 memory_area(ptr, (char*) ptr + n * size));
123 if(pos == allocated_memory.end()) {
124 BOOST_ERROR("Deallocating unknown pointer.");
125 } else {
126 BOOST_TEST(pos->first.start == ptr);
127 BOOST_TEST(pos->first.end == (char*) ptr + n * size);
128 if (check_tag_) BOOST_TEST(pos->second.tag_ == tag);
129 allocated_memory.erase(pos);
130 }
131 BOOST_TEST(count_allocations > 0);
132 if(count_allocations > 0) --count_allocations;
133 }
134
135 void track_construct(void* /*ptr*/, std::size_t /*size*/,
136 int /*tag*/)
137 {
138 ++count_constructions;
139 }
140
141 void track_destroy(void* /*ptr*/, std::size_t /*size*/,
142 int /*tag*/)
143 {
144 BOOST_TEST(count_constructions > 0);
145 if(count_constructions > 0) --count_constructions;
146 }
147 };
148 }
149
150 namespace detail
151 {
152 // This won't be a problem as I'm only using a single compile unit
153 // in each test (this is actually required by the minimal test
154 // framework).
155 //
156 // boostinspect:nounnamed
157 namespace {
158 test::detail::memory_tracker tracker;
159 }
160 }
161 }
162
163 #endif