]>
Commit | Line | Data |
---|---|---|
99dee823 | 1 | // Copyright (C) 2020-2021 Free Software Foundation, Inc. |
6bcbcea0 TR |
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 | ||
58f71a34 | 18 | // { dg-options "-std=gnu++2a" } |
6bcbcea0 | 19 | // { dg-do run { target c++2a } } |
6bcbcea0 TR |
20 | // { dg-require-effective-target cxx11-abi } |
21 | // { dg-require-gthreads "" } | |
58f71a34 JW |
22 | // { dg-add-options libatomic } |
23 | // { dg-additional-options "-pthread" { target pthread } } | |
6bcbcea0 TR |
24 | |
25 | #include <algorithm> | |
26 | #include <atomic> | |
27 | #include <chrono> | |
28 | #include <sstream> | |
29 | #include <string> | |
30 | #include <string_view> | |
31 | #include <syncstream> | |
32 | #include <thread> | |
33 | #include <vector> | |
34 | #include <unordered_map> | |
35 | #include <utility> | |
36 | ||
37 | #include <testsuite_hooks.h> | |
38 | ||
39 | int | |
40 | main() | |
41 | { | |
42 | using namespace std::chrono_literals; | |
43 | ||
44 | std::stringbuf b; | |
45 | std::atomic<unsigned> running(0); | |
46 | ||
47 | auto const cstr = "This is a test"; | |
48 | ||
49 | constexpr int ct = 1000; | |
50 | auto const body = [&]{ | |
51 | ++running; | |
52 | auto tid = std::this_thread::get_id(); | |
53 | std::syncbuf s(&b); | |
54 | for (auto i = 0; i < ct; ++i) | |
55 | { | |
56 | std::stringstream stm; | |
57 | stm << tid << ' ' << cstr << ' ' << i << std::endl; | |
58 | auto sv = stm.view(); | |
59 | s.sputn(sv.data(), sv.size()); | |
60 | VERIFY( s.emit() ); | |
61 | } | |
62 | }; | |
63 | ||
64 | const auto tct = 8; | |
65 | std::vector<std::thread> ts; | |
66 | ts.reserve(tct); | |
67 | ||
68 | for (auto i = 0; i < tct; ++i) | |
69 | ts.emplace_back(std::thread(body)); | |
70 | ||
71 | do | |
72 | { | |
73 | std::this_thread::sleep_for(100ms); | |
74 | } | |
75 | while (running.load() < tct); | |
76 | ||
77 | std::unordered_map<std::string, int> tids; | |
78 | for (auto&& t : ts) | |
79 | { | |
80 | std::stringstream stm; | |
81 | stm << t.get_id(); | |
82 | tids.emplace(std::make_pair(stm.str(), 0)); | |
83 | }; | |
84 | ||
85 | for (auto&& t : ts) | |
86 | t.join(); | |
87 | ||
88 | std::vector<std::string_view> lines; | |
89 | const auto lct = ct * ts.size(); | |
90 | lines.reserve(lct); | |
91 | ||
92 | std::size_t last = 0; | |
93 | auto sv = b.view(); | |
94 | auto p = sv.find('\n'); | |
95 | while (p != std::string_view::npos) | |
96 | { | |
97 | lines.emplace_back(sv.substr(last, p - last)); | |
98 | last = p+1; | |
99 | p = sv.find('\n', last); | |
100 | } | |
101 | VERIFY( lines.size() == lct ); | |
102 | ||
103 | auto sep = ""; | |
104 | auto i = 0; | |
105 | sv = std::string_view(cstr); | |
106 | ||
107 | for (auto&& l : lines) | |
108 | { | |
109 | auto p = l.find(' '); | |
110 | VERIFY( p != std::string_view::npos ); | |
111 | std::string tid(l.substr(0, p)); | |
112 | ++p; | |
113 | ||
114 | VERIFY( l.substr(p, sv.size()) == sv ); | |
115 | std::string s(l.substr(++p + sv.size())); | |
116 | std::stringstream stm(s); | |
117 | int n; | |
118 | stm >> n; | |
119 | VERIFY( stm.eof() ); | |
120 | VERIFY( n >= 0 && n < ct ); | |
121 | auto it = tids.find(tid); | |
122 | VERIFY( it != std::end(tids) ); | |
123 | ++(it->second); | |
124 | } | |
125 | ||
126 | for (auto const& t : tids) | |
127 | { | |
128 | VERIFY( t.second == ct ); | |
129 | } | |
130 | return 0; | |
131 | } |