]> 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-2020 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 }
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 <future>
26 #include <testsuite_allocator.h>
27 #include <testsuite_hooks.h>
28
29 void
30 test01()
31 {
32 __gnu_test::memory_resource test_mr;
33 std::pmr::synchronized_pool_resource smr(&test_mr);
34
35 const std::size_t largest_pool = smr.options().largest_required_pool_block;
36
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);
41 p2 = smr.allocate(n);
42 p = smr.allocate(n);
43 smr.deallocate(p2, n);
44 };
45 auto do_dealloc = [&smr](void* p, size_t n) { smr.deallocate(p, n); };
46
47 void* p1;
48 void* p2;
49 void* p3;
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),
53 largest_pool* 2);
54
55 f1.get();
56 f2.get();
57 f3.get();
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 );
63
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);
67 f1.get();
68 f2.get();
69 // No additional memory is allocated by deallocating on new threads:
70 VERIFY( test_mr.number_of_active_allocations() == nallocs );
71
72 // Deallocate large unpooled allocation:
73 f3 = std::async(std::launch::async, do_dealloc, p3, largest_pool * 2);
74 f3.get();
75 // The large allocation should have been returned upstream:
76 VERIFY( test_mr.number_of_active_allocations() == nallocs - 1 );
77
78 smr.release();
79 VERIFY( test_mr.number_of_active_allocations() == 0 );
80 }
81
82 int
83 main()
84 {
85 test01();
86 }