]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/27_io/basic_syncbuf/sync_ops/1.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 27_io / basic_syncbuf / sync_ops / 1.cc
CommitLineData
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
39int
40main()
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}