brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · 904735f Raw
129 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// UNSUPPORTED: no-threads10// UNSUPPORTED: c++0311 12// <future>13 14// class shared_future<R>15 16// template <class Clock, class Duration>17//   future_status18//   wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;19 20#include <atomic>21#include <cassert>22#include <chrono>23#include <future>24 25#include "make_test_thread.h"26#include "test_macros.h"27 28enum class WorkerThreadState { Uninitialized, AllowedToRun, Exiting };29typedef std::chrono::milliseconds ms;30 31std::atomic<WorkerThreadState> thread_state(WorkerThreadState::Uninitialized);32 33void set_worker_thread_state(WorkerThreadState state)34{35  thread_state.store(state, std::memory_order_relaxed);36}37 38void wait_for_worker_thread_state(WorkerThreadState state)39{40  while (thread_state.load(std::memory_order_relaxed) != state)41    std::this_thread::yield();42}43 44void func1(std::promise<int> p)45{46  wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);47  p.set_value(3);48  set_worker_thread_state(WorkerThreadState::Exiting);49}50 51int j = 0;52 53void func3(std::promise<int&> p)54{55  wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);56  j = 5;57  p.set_value(j);58  set_worker_thread_state(WorkerThreadState::Exiting);59}60 61void func5(std::promise<void> p)62{63  wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);64  p.set_value();65  set_worker_thread_state(WorkerThreadState::Exiting);66}67 68int main(int, char**)69{70  typedef std::chrono::high_resolution_clock Clock;71 72  {73    typedef int T;74    std::promise<T> p;75    std::shared_future<T> f = p.get_future();76    support::make_test_thread(func1, std::move(p)).detach();77    assert(f.valid());78    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);79    assert(f.valid());80 81    // allow the worker thread to produce the result and wait until the worker is done82    set_worker_thread_state(WorkerThreadState::AllowedToRun);83    wait_for_worker_thread_state(WorkerThreadState::Exiting);84 85    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);86    assert(f.valid());87    f.wait();88    assert(f.valid());89  }90  {91    typedef int& T;92    std::promise<T> p;93    std::shared_future<T> f = p.get_future();94    support::make_test_thread(func3, std::move(p)).detach();95    assert(f.valid());96    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);97    assert(f.valid());98 99    // allow the worker thread to produce the result and wait until the worker is done100    set_worker_thread_state(WorkerThreadState::AllowedToRun);101    wait_for_worker_thread_state(WorkerThreadState::Exiting);102 103    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);104    assert(f.valid());105    f.wait();106    assert(f.valid());107  }108  {109    typedef void T;110    std::promise<T> p;111    std::shared_future<T> f = p.get_future();112    support::make_test_thread(func5, std::move(p)).detach();113    assert(f.valid());114    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);115    assert(f.valid());116 117    // allow the worker thread to produce the result and wait until the worker is done118    set_worker_thread_state(WorkerThreadState::AllowedToRun);119    wait_for_worker_thread_state(WorkerThreadState::Exiting);120 121    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);122    assert(f.valid());123    f.wait();124    assert(f.valid());125  }126 127  return 0;128}129