]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/20_util/synchronized_pool_resource/multithreaded.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / synchronized_pool_resource / multithreaded.cc
1 // Copyright (C) 2018-2024 Free Software Foundation, Inc.
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 { target c++17 } }
19 // { dg-additional-options "-pthread" { target pthread } }
20 // { dg-require-gthreads "" }
21
22 #include <memory_resource>
23 #include <future>
24 #include <testsuite_allocator.h>
25 #include <testsuite_hooks.h>
26
27 void
28 test01()
29 {
30 __gnu_test::memory_resource test_mr;
31 std::pmr::synchronized_pool_resource smr(&test_mr);
32
33 const std::size_t largest_pool = smr.options().largest_required_pool_block;
34
35 auto do_alloc = [&smr](void*& p, size_t n) {
36 // perform some other allocations and deallocations on the same thread:
37 void* p2 = smr.allocate(n);
38 smr.deallocate(p2, n);
39 p2 = smr.allocate(n);
40 p = smr.allocate(n);
41 smr.deallocate(p2, n);
42 };
43 auto do_dealloc = [&smr](void* p, size_t n) { smr.deallocate(p, n); };
44
45 void* p1;
46 void* p2;
47 void* p3;
48 auto f1 = std::async(std::launch::async, do_alloc, std::ref(p1), 8);
49 auto f2 = std::async(std::launch::async, do_alloc, std::ref(p2), 64);
50 auto f3 = std::async(std::launch::async, do_alloc, std::ref(p3),
51 largest_pool* 2);
52
53 f1.get();
54 f2.get();
55 f3.get();
56 VERIFY( p1 != nullptr );
57 VERIFY( p2 != nullptr );
58 VERIFY( p3 != nullptr );
59 size_t nallocs = test_mr.number_of_active_allocations();
60 VERIFY( nallocs >= 4 );
61
62 // deallocate on different threads from allocation:
63 f1 = std::async(std::launch::async, do_dealloc, p1, 8);
64 f2 = std::async(std::launch::async, do_dealloc, p2, 64);
65 f1.get();
66 f2.get();
67 // No additional memory is allocated by deallocating on new threads:
68 VERIFY( test_mr.number_of_active_allocations() == nallocs );
69
70 // Deallocate large unpooled allocation:
71 f3 = std::async(std::launch::async, do_dealloc, p3, largest_pool * 2);
72 f3.get();
73 // The large allocation should have been returned upstream:
74 VERIFY( test_mr.number_of_active_allocations() == nallocs - 1 );
75
76 smr.release();
77 VERIFY( test_mr.number_of_active_allocations() == 0 );
78 }
79
80 int
81 main()
82 {
83 test01();
84 }