libs/capy/src/ex/recycling_memory_resource.cpp

86.1% Lines (31/36) 100.0% Functions (6/6) 75.0% Branches (18/24)
libs/capy/src/ex/recycling_memory_resource.cpp
Line Branch Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/capy
8 //
9
10 #include <boost/capy/ex/recycling_memory_resource.hpp>
11
12 namespace boost {
13 namespace capy {
14
15 recycling_memory_resource::pool&
16 7585 recycling_memory_resource::local() noexcept
17 {
18
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 7559 times.
7585 static thread_local pool p;
19 7585 return p;
20 }
21
22 recycling_memory_resource::pool&
23 97 recycling_memory_resource::global() noexcept
24 {
25
3/4
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 72 times.
✓ Branch 3 taken 25 times.
✗ Branch 4 not taken.
97 static pool p;
26 97 return p;
27 }
28
29 std::mutex&
30 97 recycling_memory_resource::global_mutex() noexcept
31 {
32 static std::mutex mtx;
33 97 return mtx;
34 }
35
36 void*
37 3746 recycling_memory_resource::do_allocate(std::size_t bytes, std::size_t)
38 {
39 3746 std::size_t rounded = round_up_pow2(bytes);
40 3746 std::size_t idx = get_class_index(rounded);
41
42
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3746 times.
3746 if(idx >= num_classes)
43 return ::operator new(bytes);
44
45
2/2
✓ Branch 2 taken 3653 times.
✓ Branch 3 taken 93 times.
3746 if(auto* p = local().buckets[idx].pop())
46 3653 return p;
47
48 {
49
1/1
✓ Branch 2 taken 93 times.
93 std::lock_guard<std::mutex> lock(global_mutex());
50
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 93 times.
93 if(auto* p = global().buckets[idx].pop(local().buckets[idx]))
51 return p;
52 93 }
53
54 93 return ::operator new(rounded);
55 }
56
57 void
58 3746 recycling_memory_resource::do_deallocate(void* p, std::size_t bytes, std::size_t)
59 {
60 3746 std::size_t rounded = round_up_pow2(bytes);
61 3746 std::size_t idx = get_class_index(rounded);
62
63
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3746 times.
3746 if(idx >= num_classes)
64 {
65 ::operator delete(p);
66 return;
67 }
68
69
2/2
✓ Branch 2 taken 3742 times.
✓ Branch 3 taken 4 times.
3746 if(local().buckets[idx].push(p))
70 3742 return;
71
72 {
73
1/1
✓ Branch 2 taken 4 times.
4 std::lock_guard<std::mutex> lock(global_mutex());
74
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(global().buckets[idx].push(p))
75 4 return;
76 4 }
77
78 ::operator delete(p);
79 }
80
81 std::pmr::memory_resource*
82 1953 get_recycling_memory_resource() noexcept
83 {
84
3/4
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 1919 times.
✓ Branch 3 taken 34 times.
✗ Branch 4 not taken.
1953 static recycling_memory_resource instance;
85 1953 return &instance;
86 }
87
88 } // namespace capy
89 } // namespace boost
90