-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathtest_resource.cpp
123 lines (100 loc) · 3.31 KB
/
test_resource.cpp
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
/* test_resource.cpp -*-C++-*-
*
* Copyright 2017 Pablo Halpern.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
#include "test_resource.h"
#include <algorithm>
#include <cassert>
// Keep track of number of bytes that would be leaked by
// allocator destructor.
size_t test_resource::s_leaked_bytes = 0;
// Keep track of number of blocks that would be leaked by
// allocator destructor.
size_t test_resource::s_leaked_blocks = 0;
test_resource::test_resource(pmr::memory_resource *parent)
: m_parent(parent)
, m_bytes_allocated(0)
, m_bytes_outstanding(0)
, m_bytes_highwater(0)
, m_blocks(parent) // Vector memory comes from parent, too
{
}
test_resource::~test_resource() {
// If any blocks have not been released, report them as leaked.
s_leaked_blocks += blocks_outstanding();
// Reclaim blocks that would have been leaked.
for (auto& alloc_rec : m_blocks) {
s_leaked_bytes += alloc_rec.m_bytes;
m_parent->deallocate(alloc_rec.m_ptr, alloc_rec.m_bytes,
alloc_rec.m_alignment);
}
}
pmr::memory_resource *test_resource::parent() const {
return m_parent;
}
size_t test_resource::bytes_allocated() const {
return m_bytes_allocated;
}
size_t test_resource::bytes_deallocated() const {
return m_bytes_allocated - m_bytes_outstanding;
}
size_t test_resource::bytes_outstanding() const {
return m_bytes_outstanding;
}
size_t test_resource::bytes_highwater() const {
return m_bytes_highwater;
}
size_t test_resource::blocks_outstanding() const {
return m_blocks.size();
}
size_t test_resource::leaked_bytes() {
return s_leaked_bytes;
}
size_t test_resource::leaked_blocks() {
return s_leaked_blocks;
}
void test_resource::clear_leaked() {
s_leaked_bytes = 0;
s_leaked_blocks = 0;
}
void *test_resource::do_allocate(size_t bytes,
size_t alignment) {
void *ret = m_parent->allocate(bytes, alignment);
m_blocks.push_back(allocation_rec{ret, bytes, alignment});
m_bytes_allocated += bytes;
m_bytes_outstanding += bytes;
if (m_bytes_outstanding > m_bytes_highwater)
m_bytes_highwater = m_bytes_outstanding;
return ret;
}
void test_resource::do_deallocate(void *p, size_t bytes,
size_t alignment) {
// Check that deallocation args exactly match allocation args.
auto i = std::find_if(m_blocks.begin(), m_blocks.end(),
[p](allocation_rec& r){
return r.m_ptr == p; });
if (i == m_blocks.end())
throw std::invalid_argument("deallocate: Invalid pointer");
else if (i->m_bytes != bytes)
throw std::invalid_argument("deallocate: Size mismatch");
else if (i->m_alignment != alignment)
throw std::invalid_argument("deallocate: Alignment mismatch");
m_parent->deallocate(p, i->m_bytes, i->m_alignment);
m_blocks.erase(i);
m_bytes_outstanding -= bytes;
}
bool test_resource::do_is_equal(const pmr::memory_resource& other)
const noexcept {
return this == &other;
}
/* End test_resource.cpp */
// For best result when pasting into PowerPoint, set indent to 2
// and right-most column to 64.
//
// Local Variables:
// c-basic-offset: 2
// fill-column: 64
// End: