async_race.pass.cpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. // <future>
  13. // template <class F, class... Args>
  14. // future<typename result_of<F(Args...)>::type>
  15. // async(F&& f, Args&&... args);
  16. // template <class F, class... Args>
  17. // future<typename result_of<F(Args...)>::type>
  18. // async(launch policy, F&& f, Args&&... args);
  19. // This test is designed to cause and allow TSAN to detect the race condition
  20. // reported in PR23293: https://bugs.llvm.org/show_bug.cgi?id=23293
  21. #include <future>
  22. #include <chrono>
  23. #include <thread>
  24. #include <memory>
  25. #include <cassert>
  26. int f_async() {
  27. typedef std::chrono::milliseconds ms;
  28. std::this_thread::sleep_for(ms(200));
  29. return 42;
  30. }
  31. bool ran = false;
  32. int f_deferred() {
  33. ran = true;
  34. return 42;
  35. }
  36. void test_each() {
  37. {
  38. std::future<int> f = std::async(f_async);
  39. int const result = f.get();
  40. assert(result == 42);
  41. }
  42. {
  43. std::future<int> f = std::async(std::launch::async, f_async);
  44. int const result = f.get();
  45. assert(result == 42);
  46. }
  47. {
  48. ran = false;
  49. std::future<int> f = std::async(std::launch::deferred, f_deferred);
  50. assert(ran == false);
  51. int const result = f.get();
  52. assert(ran == true);
  53. assert(result == 42);
  54. }
  55. }
  56. int main() {
  57. for (int i=0; i < 25; ++i) test_each();
  58. }