1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // UNSUPPORTED: libcpp-has-no-threads 10 // UNSUPPORTED: c++03 11 12 // There's currently no release of OS X whose dylib contains the patch for 13 // PR38682. Since the fix for future<void> is in the dylib, this test may fail. 14 // UNSUPPORTED: use_system_cxx_lib && x86_64-apple-macosx10.14 15 // UNSUPPORTED: use_system_cxx_lib && x86_64-apple-macosx10.13 16 // UNSUPPORTED: use_system_cxx_lib && x86_64-apple-macosx10.12 17 // UNSUPPORTED: use_system_cxx_lib && x86_64-apple-macosx10.11 18 // UNSUPPORTED: use_system_cxx_lib && x86_64-apple-macosx10.10 19 // UNSUPPORTED: use_system_cxx_lib && x86_64-apple-macosx10.9 20 21 // This test is designed to cause and allow TSAN to detect a race condition 22 // in std::async, as reported in https://llvm.org/PR38682. 23 24 #include <cassert> 25 #include <functional> 26 #include <future> 27 #include <numeric> 28 #include <vector> 29 30 #include "test_macros.h" 31 32 33 static int worker(std::vector<int> const& data) { 34 return std::accumulate(data.begin(), data.end(), 0); 35 } 36 37 static int& worker_ref(int& i) { return i; } 38 39 static void worker_void() { } 40 41 int main(int, char**) { 42 // future<T> 43 { 44 std::vector<int> const v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 45 for (int i = 0; i != 20; ++i) { 46 std::future<int> fut = std::async(std::launch::async, worker, v); 47 int answer = fut.get(); 48 assert(answer == 55); 49 } 50 } 51 52 // future<T&> 53 { 54 for (int i = 0; i != 20; ++i) { 55 std::future<int&> fut = std::async(std::launch::async, worker_ref, std::ref(i)); 56 int& answer = fut.get(); 57 assert(answer == i); 58 } 59 } 60 61 // future<void> 62 { 63 for (int i = 0; i != 20; ++i) { 64 std::future<void> fut = std::async(std::launch::async, worker_void); 65 fut.get(); 66 } 67 } 68 69 return 0; 70 } 71