]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/20_util/synchronized_pool_resource/allocate.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / synchronized_pool_resource / allocate.cc
CommitLineData
99dee823 1// Copyright (C) 2018-2021 Free Software Foundation, Inc.
c5be6481
JW
2//
3// This file is part of the GNU ISO C++ Library. This library is free
4// software; you can redistribute it and/or modify it under the
5// terms of the GNU General Public License as published by the
6// Free Software Foundation; either version 3, or (at your option)
7// any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License along
15// with this library; see the file COPYING3. If not see
16// <http://www.gnu.org/licenses/>.
17
18// { dg-do run }
19// { dg-options "-std=gnu++17 -pthread" }
20// { dg-require-effective-target c++17 }
21// { dg-require-effective-target pthread }
22// { dg-require-gthreads "" }
23
24#include <memory_resource>
25#include <cstring>
26#include <testsuite_allocator.h>
27#include <testsuite_hooks.h>
28
29void
30test01()
31{
32 __gnu_test::memory_resource test_mr;
33 {
34 std::pmr::synchronized_pool_resource r(&test_mr);
35 void* p1 = r.allocate(1, 1);
36 VERIFY( p1 != nullptr );
37 auto n = test_mr.number_of_active_allocations();
38 VERIFY( n > 0 );
39 // Ensure memory region can be written to (without corrupting heap!)
40 std::memset(p1, 0xff, 1);
41 void* p2 = r.allocate(1, 1);
42 VERIFY( p2 != nullptr );
43 VERIFY( p2 != p1 );
44 VERIFY( test_mr.number_of_active_allocations() == n );
45 std::memset(p1, 0xff, 1);
46 r.deallocate(p1, 1, 1);
47 // Returning single blocks to the pool doesn't return them upstream:
48 VERIFY( test_mr.number_of_active_allocations() == n );
49 r.deallocate(p2, 1, 1);
50 VERIFY( test_mr.number_of_active_allocations() == n );
51 }
52 VERIFY( test_mr.number_of_active_allocations() == 0 );
53}
54
55void
56test02()
57{
58 struct nullable_memory_resource : public std::pmr::memory_resource
59 {
60 void*
61 do_allocate(std::size_t bytes, std::size_t alignment) override
62 { return upstream->allocate(bytes, alignment); }
63
64 void
65 do_deallocate(void* p, std::size_t bytes, std::size_t alignment) override
66 { upstream->deallocate(p, bytes, alignment); }
67
68 bool
69 do_is_equal(const memory_resource& r) const noexcept override
70 { return &r == this; }
71
72 std::pmr::memory_resource* upstream = std::pmr::get_default_resource();
73 };
74
75 nullable_memory_resource test_mr;
76 std::pmr::synchronized_pool_resource r(&test_mr);
77 void* p1 = r.allocate(8, 1);
78 VERIFY( p1 != nullptr );
79 std::memset(p1, 0xff, 8);
80 test_mr.upstream = nullptr;
81 void* p2 = r.allocate(8, 1); //should not need to replenish
82 VERIFY( p2 != nullptr );
83 VERIFY( p2 != p1 );
84 std::memset(p1, 0xff, 8);
85 r.deallocate(p1, 8, 1); // should not use upstream
86 r.deallocate(p2, 8, 1); // should not use upstream
87
88 // Destructor will return memory upstream, so restore the upstream resource:
89 test_mr.upstream = std::pmr::get_default_resource();
90}
91
92void
93test03()
94{
95 __gnu_test::memory_resource test_mr;
96 {
97 std::pmr::synchronized_pool_resource r({10, 16}, &test_mr);
98 std::size_t largest_pool = r.options().largest_required_pool_block;
99 void* p1 = r.allocate(2 * largest_pool);
100 VERIFY( p1 != nullptr );
101 const std::size_t n = test_mr.number_of_active_allocations();
102 // Allocation of pools + allocation of pmr::vector + oversize allocation:
103 VERIFY( n >= 1 );
104 std::memset(p1, 0xff, 2 * largest_pool);
105 void* p2 = r.allocate(3 * largest_pool);
106 VERIFY( p2 != nullptr );
107 VERIFY( p2 != p1 );
108 VERIFY( test_mr.number_of_active_allocations() == n + 1 );
109 std::memset(p2, 0xff, 3 * largest_pool);
110 r.deallocate(p1, 2 * largest_pool);
111 VERIFY( test_mr.number_of_active_allocations() == n );
112 r.deallocate(p2, 3 * largest_pool);
113 VERIFY( test_mr.number_of_active_allocations() == n - 1 );
114 }
115 VERIFY( test_mr.number_of_active_allocations() == 0 );
116 {
117 std::pmr::synchronized_pool_resource r({16, 16}, &test_mr);
118 (void) r.allocate(2);
119 (void) r.allocate(8);
120 (void) r.allocate(16);
121 (void) r.allocate(2);
122 (void) r.allocate(8);
123 (void) r.allocate(16);
124 (void) r.allocate(2 * r.options().largest_required_pool_block);
125 VERIFY( test_mr.number_of_active_allocations() != 0 );
126 // Destructor calls release()
127 }
128 VERIFY( test_mr.number_of_active_allocations() == 0 );
129}
130
131void
132test04()
133{
134 __gnu_test::memory_resource test_mr;
135 std::pmr::synchronized_pool_resource r({256, 256}, &test_mr);
136 // Check alignment
137 void* p1 = r.allocate(2, 64);
138 VERIFY( (std::uintptr_t)p1 % 64 == 0 );
139 void* p2 = r.allocate(2, 128);
140 VERIFY( (std::uintptr_t)p2 % 128 == 0 );
141 void* p3 = r.allocate(2, 256);
142 VERIFY( (std::uintptr_t)p3 % 256 == 0 );
143 const std::size_t largest_pool = r.options().largest_required_pool_block;
144 void* p4 = r.allocate(2 * largest_pool, 1024);
145 VERIFY( (std::uintptr_t)p4 % 1024 == 0 );
146 r.deallocate(p1, 2, 64);
147 r.deallocate(p2, 2, 128);
148 r.deallocate(p3, 2, 256);
149 r.deallocate(p4, 2 * largest_pool, 1024);
150}
151
152int
153main()
154{
155 test01();
156 test02();
157 test03();
158 test04();
159}