brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · 00c1b8d Raw
128 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 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    typedef int T;73    std::promise<T> p;74    std::future<T> f = p.get_future();75    support::make_test_thread(func1, std::move(p)).detach();76    assert(f.valid());77    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);78    assert(f.valid());79 80    // allow the worker thread to produce the result and wait until the worker is done81    set_worker_thread_state(WorkerThreadState::AllowedToRun);82    wait_for_worker_thread_state(WorkerThreadState::Exiting);83 84    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);85    assert(f.valid());86    f.wait();87    assert(f.valid());88  }89  {90    typedef int& T;91    std::promise<T> p;92    std::future<T> f = p.get_future();93    support::make_test_thread(func3, std::move(p)).detach();94    assert(f.valid());95    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);96    assert(f.valid());97 98    // allow the worker thread to produce the result and wait until the worker is done99    set_worker_thread_state(WorkerThreadState::AllowedToRun);100    wait_for_worker_thread_state(WorkerThreadState::Exiting);101 102    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);103    assert(f.valid());104    f.wait();105    assert(f.valid());106  }107  {108    typedef void T;109    std::promise<T> p;110    std::future<T> f = p.get_future();111    support::make_test_thread(func5, std::move(p)).detach();112    assert(f.valid());113    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);114    assert(f.valid());115 116    // allow the worker thread to produce the result and wait until the worker is done117    set_worker_thread_state(WorkerThreadState::AllowedToRun);118    wait_for_worker_thread_state(WorkerThreadState::Exiting);119 120    assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);121    assert(f.valid());122    f.wait();123    assert(f.valid());124  }125 126  return 0;127}128