1 // Copyright (C) 2018-2019 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_allocator.h>
24 struct resource
: __gnu_test::memory_resource
26 int allocate_calls
= 0;
27 int deallocate_calls
= 0;
30 do_allocate(std::size_t bytes
, std::size_t align
) override
33 return __gnu_test::memory_resource::do_allocate(bytes
, align
);
37 do_deallocate(void* p
, std::size_t bytes
, std::size_t align
) override
40 __gnu_test::memory_resource::do_deallocate(p
, bytes
, align
);
48 std::pmr::monotonic_buffer_resource
mbr(&r
);
49 auto p
= mbr
.allocate(10, 16);
50 mbr
.deallocate(p
, 1, 2);
51 VERIFY( r
.deallocate_calls
== 0 );
52 p
= mbr
.allocate(10, 16);
53 p
= mbr
.allocate(10, 16);
54 p
= mbr
.allocate(10, 16);
55 p
= mbr
.allocate(1024, 64);
56 p
= mbr
.allocate(1024, 64);
57 p
= mbr
.allocate(128, 8);
58 p
= mbr
.allocate(128, 8);
59 p
= mbr
.allocate(128, 8);
60 p
= mbr
.allocate(128, 8);
61 p
= mbr
.allocate(128, 8);
62 p
= mbr
.allocate(128, 8);
63 p
= mbr
.allocate(128, 8);
64 mbr
.deallocate(p
, 1, 2);
65 p
= mbr
.allocate(1024, 16);
66 p
= mbr
.allocate(1024, 16);
67 mbr
.deallocate(p
, 1, 2);
68 VERIFY( r
.deallocate_calls
== 0 );
70 VERIFY( r
.deallocate_calls
!= 0 );
71 VERIFY( r
.deallocate_calls
== r
.allocate_calls
);
72 VERIFY( mbr
.upstream_resource() == &r
);
73 VERIFY( r
.number_of_active_allocations() == 0 );
79 std::pmr::monotonic_buffer_resource mbr
; // uses get_default_resource()
80 auto* const upstream
= mbr
.upstream_resource();
82 __gnu_test::default_resource_mgr
_(&r
); // calls set_default_resource(&r)
84 // release() doesn't change upstream resource:
85 VERIFY( mbr
.upstream_resource() == upstream
);
92 __gnu_test::default_resource_mgr
_(&r
);
93 std::pmr::monotonic_buffer_resource
mbr(16);
94 for (int i
= 0; i
< 100; ++i
)
95 (void) mbr
.allocate(4, 1);
96 const int allocations
= r
.allocate_calls
;
97 VERIFY( allocations
!= 0 );
99 VERIFY( r
.allocate_calls
== r
.deallocate_calls
);
100 VERIFY( r
.number_of_active_allocations() == 0 );
102 // next_buffer_size should have been reset to the initial value,
103 // so the allocations from upstream should be the same as before.
104 r
.allocate_calls
= 0;
105 r
.deallocate_calls
= 0;
106 for (int i
= 0; i
< 100; ++i
)
107 (void) mbr
.allocate(4,1);
108 VERIFY( allocations
== r
.allocate_calls
);
115 unsigned char buffer
[1024];
116 std::pmr::monotonic_buffer_resource
mbr(buffer
, sizeof(buffer
), &r
);
117 void* p
= mbr
.allocate(800, 16);
118 VERIFY( p
>= buffer
&& p
< (buffer
+ 16) );
119 void* const p_in_buffer
= p
;
120 VERIFY( r
.allocate_calls
== 0 );
121 p
= mbr
.allocate(300, 1);
122 VERIFY( p
!= buffer
);
123 VERIFY( p
!= buffer
);
124 VERIFY( r
.allocate_calls
== 1 );
126 VERIFY( r
.deallocate_calls
== 1 );
127 VERIFY( mbr
.upstream_resource() == &r
);
128 VERIFY( r
.number_of_active_allocations() == 0 );
129 // initial buffer should be used again now:
130 p
= mbr
.allocate(1000, 16);
131 VERIFY( p
== p_in_buffer
);
132 VERIFY( r
.allocate_calls
== 1 );
140 std::pmr::monotonic_buffer_resource
mr(buffer
, sizeof(buffer
),
141 std::pmr::null_memory_resource());
143 (void) mr
.allocate(60);
147 std::pmr::monotonic_buffer_resource
mr(buffer
, sizeof(buffer
),
148 std::pmr::null_memory_resource());
149 (void) mr
.allocate(60);
151 (void) mr
.allocate(60);
156 std::pmr::monotonic_buffer_resource
mr(&r
);
157 for (int i
= 0; i
< 100; ++i
)
159 (void) mr
.allocate(1);
162 VERIFY( r
.number_of_active_allocations() == 0 );