1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // UNSUPPORTED: libcpp-has-no-threads
11 // UNSUPPORTED: c++98, c++03
12
13 // There's currently no release of OS X whose dylib contains the patch for
14 // PR38682. Since the fix for future<void> is in the dylib, this test may fail.
15 // UNSUPPORTED: with_system_cxx_lib=macosx10.14
16 // UNSUPPORTED: with_system_cxx_lib=macosx10.13
17 // UNSUPPORTED: with_system_cxx_lib=macosx10.12
18 // UNSUPPORTED: with_system_cxx_lib=macosx10.11
19 // UNSUPPORTED: with_system_cxx_lib=macosx10.10
20 // UNSUPPORTED: with_system_cxx_lib=macosx10.9
21 // UNSUPPORTED: with_system_cxx_lib=macosx10.8
22 // UNSUPPORTED: with_system_cxx_lib=macosx10.7
23
24 // This test is designed to cause and allow TSAN to detect a race condition
25 // in std::async, as reported in https://bugs.llvm.org/show_bug.cgi?id=38682.
26
27 #include <cassert>
28 #include <functional>
29 #include <future>
30 #include <numeric>
31 #include <vector>
32
33
worker(std::vector<int> const & data)34 static int worker(std::vector<int> const& data) {
35 return std::accumulate(data.begin(), data.end(), 0);
36 }
37
worker_ref(int & i)38 static int& worker_ref(int& i) { return i; }
39
worker_void()40 static void worker_void() { }
41
main()42 int main() {
43 // future<T>
44 {
45 std::vector<int> const v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
46 for (int i = 0; i != 20; ++i) {
47 std::future<int> fut = std::async(std::launch::async, worker, v);
48 int answer = fut.get();
49 assert(answer == 55);
50 }
51 }
52
53 // future<T&>
54 {
55 for (int i = 0; i != 20; ++i) {
56 std::future<int&> fut = std::async(std::launch::async, worker_ref, std::ref(i));
57 int& answer = fut.get();
58 assert(answer == i);
59 }
60 }
61
62 // future<void>
63 {
64 for (int i = 0; i != 20; ++i) {
65 std::future<void> fut = std::async(std::launch::async, worker_void);
66 fut.get();
67 }
68 }
69 }
70