1 // Copyright (C) 2018-2022 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/>.
19 // { dg-options "-pthread" }
20 // { dg-require-effective-target c++17 }
21 // { dg-require-effective-target pthread }
22 // { dg-require-gthreads "" }
24 #include <memory_resource>
26 #include <testsuite_allocator.h>
27 #include <testsuite_hooks.h>
32 __gnu_test::memory_resource test_mr
;
33 std::pmr::synchronized_pool_resource
smr(&test_mr
);
35 const std::size_t largest_pool
= smr
.options().largest_required_pool_block
;
37 auto do_alloc
= [&smr
](void*& p
, size_t n
) {
38 // perform some other allocations and deallocations on the same thread:
39 void* p2
= smr
.allocate(n
);
40 smr
.deallocate(p2
, n
);
43 smr
.deallocate(p2
, n
);
45 auto do_dealloc
= [&smr
](void* p
, size_t n
) { smr
.deallocate(p
, n
); };
50 auto f1
= std::async(std::launch::async
, do_alloc
, std::ref(p1
), 8);
51 auto f2
= std::async(std::launch::async
, do_alloc
, std::ref(p2
), 64);
52 auto f3
= std::async(std::launch::async
, do_alloc
, std::ref(p3
),
58 VERIFY( p1
!= nullptr );
59 VERIFY( p2
!= nullptr );
60 VERIFY( p3
!= nullptr );
61 size_t nallocs
= test_mr
.number_of_active_allocations();
62 VERIFY( nallocs
>= 4 );
64 // deallocate on different threads from allocation:
65 f1
= std::async(std::launch::async
, do_dealloc
, p1
, 8);
66 f2
= std::async(std::launch::async
, do_dealloc
, p2
, 64);
69 // No additional memory is allocated by deallocating on new threads:
70 VERIFY( test_mr
.number_of_active_allocations() == nallocs
);
72 // Deallocate large unpooled allocation:
73 f3
= std::async(std::launch::async
, do_dealloc
, p3
, largest_pool
* 2);
75 // The large allocation should have been returned upstream:
76 VERIFY( test_mr
.number_of_active_allocations() == nallocs
- 1 );
79 VERIFY( test_mr
.number_of_active_allocations() == 0 );