1 // Copyright (C) 2018-2020 Free Software Foundation, Inc.
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)
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.
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/>.
18 // { dg-options "-std=gnu++17" }
19 // { dg-do run { target c++17 } }
21 #include <memory_resource>
22 #include <testsuite_hooks.h>
24 struct custom_mr
: std::pmr::memory_resource
26 custom_mr(std::size_t max
) : max(max
) { }
28 bool reached_max
= false;
32 std::size_t count
= 0;
34 void* do_allocate(std::size_t b
, std::size_t a
)
39 if (count
> (18 * 1024 * 1024))
40 // Something went wrong, should not need to allocate this much.
41 throw std::bad_alloc();
42 return std::pmr::new_delete_resource()->allocate(b
, a
);
45 void do_deallocate(void* p
, std::size_t b
, std::size_t a
)
46 { std::pmr::new_delete_resource()->deallocate(p
, b
, a
); }
48 bool do_is_equal(const memory_resource
& r
) const noexcept
55 // Only going to allocate blocks of this size:
56 const std::size_t block_size
= 8;
57 std::pmr::pool_options opts
{};
58 // Use maximum allowed number of blocks per chunk:
59 opts
.max_blocks_per_chunk
= (std::size_t)-1;
60 opts
.largest_required_pool_block
= block_size
;
62 std::pmr::unsynchronized_pool_resource
r(opts
);
63 // Get the real max_blocks_per_chunk that will be used:
65 // Sanity test in case chunk::max_blocks_per_chunk() changes,
66 // as that could make this test take much longer to run:
67 VERIFY( opts
.max_blocks_per_chunk
<= (1 << 19) );
69 custom_mr
c(block_size
* opts
.max_blocks_per_chunk
);
70 std::pmr::unsynchronized_pool_resource
r(opts
, &c
);
71 // Keep allocating from the pool until reaching the maximum chunk size:
72 while (!c
.reached_max
)
73 (void) r
.allocate(block_size
, 1);
74 c
.reached_max
= false;
75 // Now fill that maximally-sized chunk
76 // (this used to go into an infinite loop ):
77 for (std::size_t i
= 0; i
< opts
.max_blocks_per_chunk
; ++i
)
78 (void) r
.allocate(block_size
, 1);
79 // Should have filled the maximally-sized chunk and allocated another
80 // maximally-sized chunk from upstream:
81 VERIFY( c
.reached_max
);