summaryrefslogtreecommitdiff
path: root/boost/fiber
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:11:01 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:11:01 +0900
commit3fdc3e5ee96dca5b11d1694975a65200787eab86 (patch)
tree5c1733853892b8397d67706fa453a9bd978d2102 /boost/fiber
parent88e602c57797660ebe0f9e15dbd64c1ff16dead3 (diff)
downloadboost-3fdc3e5ee96dca5b11d1694975a65200787eab86.tar.gz
boost-3fdc3e5ee96dca5b11d1694975a65200787eab86.tar.bz2
boost-3fdc3e5ee96dca5b11d1694975a65200787eab86.zip
Imported Upstream version 1.66.0upstream/1.66.0
Diffstat (limited to 'boost/fiber')
-rw-r--r--boost/fiber/context.hpp3
-rw-r--r--boost/fiber/cuda/waitfor.hpp139
-rw-r--r--boost/fiber/detail/is_all_same.hpp44
-rw-r--r--boost/fiber/future/detail/task_object.hpp4
-rw-r--r--boost/fiber/future/packaged_task.hpp2
-rw-r--r--boost/fiber/future/promise.hpp2
-rw-r--r--boost/fiber/hip/waitfor.hpp139
-rw-r--r--boost/fiber/unbuffered_channel.hpp3
8 files changed, 330 insertions, 6 deletions
diff --git a/boost/fiber/context.hpp b/boost/fiber/context.hpp
index ff6560ae9e..ce094ddcc2 100644
--- a/boost/fiber/context.hpp
+++ b/boost/fiber/context.hpp
@@ -187,13 +187,14 @@ private:
detail::terminated_hook terminated_hook_{};
detail::worker_hook worker_hook_{};
fiber_properties * properties_{ nullptr };
- std::chrono::steady_clock::time_point tp_{ (std::chrono::steady_clock::time_point::max)() };
boost::context::continuation c_{};
+ std::chrono::steady_clock::time_point tp_;
type type_;
launch policy_;
context( std::size_t initial_count, type t, launch policy) noexcept :
use_count_{ initial_count },
+ tp_{ (std::chrono::steady_clock::time_point::max)() },
type_{ t },
policy_{ policy } {
}
diff --git a/boost/fiber/cuda/waitfor.hpp b/boost/fiber/cuda/waitfor.hpp
new file mode 100644
index 0000000000..262efd9a8c
--- /dev/null
+++ b/boost/fiber/cuda/waitfor.hpp
@@ -0,0 +1,139 @@
+
+// Copyright Oliver Kowalke 2017.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_CUDA_WAITFOR_H
+#define BOOST_FIBERS_CUDA_WAITFOR_H
+
+#include <initializer_list>
+#include <mutex>
+#include <iostream>
+#include <set>
+#include <tuple>
+#include <vector>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+#include <cuda.h>
+
+#include <boost/fiber/detail/config.hpp>
+#include <boost/fiber/detail/is_all_same.hpp>
+#include <boost/fiber/condition_variable.hpp>
+#include <boost/fiber/mutex.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace fibers {
+namespace cuda {
+namespace detail {
+
+template< typename Rendezvous >
+static void trampoline( cudaStream_t st, cudaError_t status, void * vp) {
+ Rendezvous * data = static_cast< Rendezvous * >( vp);
+ data->notify( st, status);
+}
+
+class single_stream_rendezvous {
+public:
+ single_stream_rendezvous( cudaStream_t st) {
+ unsigned int flags = 0;
+ cudaError_t status = ::cudaStreamAddCallback( st, trampoline< single_stream_rendezvous >, this, flags);
+ if ( cudaSuccess != status) {
+ st_ = st;
+ status_ = status;
+ done_ = true;
+ }
+ }
+
+ void notify( cudaStream_t st, cudaError_t status) noexcept {
+ std::unique_lock< mutex > lk{ mtx_ };
+ st_ = st;
+ status_ = status;
+ done_ = true;
+ lk.unlock();
+ cv_.notify_one();
+ }
+
+ std::tuple< cudaStream_t, cudaError_t > wait() {
+ std::unique_lock< mutex > lk{ mtx_ };
+ cv_.wait( lk, [this]{ return done_; });
+ return std::make_tuple( st_, status_);
+ }
+
+private:
+ mutex mtx_{};
+ condition_variable cv_{};
+ cudaStream_t st_{};
+ cudaError_t status_{ cudaErrorUnknown };
+ bool done_{ false };
+};
+
+class many_streams_rendezvous {
+public:
+ many_streams_rendezvous( std::initializer_list< cudaStream_t > l) :
+ stx_{ l } {
+ results_.reserve( stx_.size() );
+ for ( cudaStream_t st : stx_) {
+ unsigned int flags = 0;
+ cudaError_t status = ::cudaStreamAddCallback( st, trampoline< many_streams_rendezvous >, this, flags);
+ if ( cudaSuccess != status) {
+ std::unique_lock< mutex > lk{ mtx_ };
+ stx_.erase( st);
+ results_.push_back( std::make_tuple( st, status) );
+ }
+ }
+ }
+
+ void notify( cudaStream_t st, cudaError_t status) noexcept {
+ std::unique_lock< mutex > lk{ mtx_ };
+ stx_.erase( st);
+ results_.push_back( std::make_tuple( st, status) );
+ if ( stx_.empty() ) {
+ lk.unlock();
+ cv_.notify_one();
+ }
+ }
+
+ std::vector< std::tuple< cudaStream_t, cudaError_t > > wait() {
+ std::unique_lock< mutex > lk{ mtx_ };
+ cv_.wait( lk, [this]{ return stx_.empty(); });
+ return results_;
+ }
+
+private:
+ mutex mtx_{};
+ condition_variable cv_{};
+ std::set< cudaStream_t > stx_;
+ std::vector< std::tuple< cudaStream_t, cudaError_t > > results_;
+};
+
+}
+
+void waitfor_all();
+
+inline
+std::tuple< cudaStream_t, cudaError_t > waitfor_all( cudaStream_t st) {
+ detail::single_stream_rendezvous rendezvous( st);
+ return rendezvous.wait();
+}
+
+template< typename ... STP >
+std::vector< std::tuple< cudaStream_t, cudaError_t > > waitfor_all( cudaStream_t st0, STP ... stx) {
+ static_assert( boost::fibers::detail::is_all_same< cudaStream_t, STP ...>::value, "all arguments must be of type `CUstream*`.");
+ detail::many_streams_rendezvous rendezvous{ st0, stx ... };
+ return rendezvous.wait();
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_FIBERS_CUDA_WAITFOR_H
diff --git a/boost/fiber/detail/is_all_same.hpp b/boost/fiber/detail/is_all_same.hpp
new file mode 100644
index 0000000000..b72fa7910a
--- /dev/null
+++ b/boost/fiber/detail/is_all_same.hpp
@@ -0,0 +1,44 @@
+
+// Copyright Oliver Kowalke 2017.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_DETAIL_IS_ALL_SAME_H
+#define BOOST_FIBERS_DETAIL_IS_ALL_SAME_H
+
+#include <type_traits>
+
+#include <boost/config.hpp>
+
+#include <boost/fiber/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace fibers {
+namespace detail {
+
+template< typename X, typename ... Y >
+struct is_all_same;
+
+template< typename X, typename Y0, typename ... Y >
+struct is_all_same< X, Y0, Y ... > {
+ static constexpr bool value =
+ std::is_same< X, Y0 >::value && is_all_same< X, Y ... >::value;
+};
+
+template< typename X, typename Y0 >
+struct is_all_same< X, Y0 > {
+ static constexpr bool value = std::is_same< X, Y0 >::value;
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_FIBERS_DETAIL_IS_ALL_SAME_H
diff --git a/boost/fiber/future/detail/task_object.hpp b/boost/fiber/future/detail/task_object.hpp
index abb4c8d877..8cd4dbc96a 100644
--- a/boost/fiber/future/detail/task_object.hpp
+++ b/boost/fiber/future/detail/task_object.hpp
@@ -72,7 +72,7 @@ public:
typedef pointer_traits< typename traity_type::pointer> ptrait_type;
typename traity_type::pointer ptr{ traity_type::allocate( alloc_, 1) };
- typename ptrait_type::element_type* p = ptrait_type::to_address(ptr);
+ typename ptrait_type::element_type* p = boost::to_address(ptr);
try {
traity_type::construct( alloc_, p, alloc_, std::move( fn_) );
} catch (...) {
@@ -140,7 +140,7 @@ public:
typedef pointer_traits< typename traity_type::pointer> ptrait_type;
typename traity_type::pointer ptr{ traity_type::allocate( alloc_, 1) };
- typename ptrait_type::element_type* p = ptrait_type::to_address(ptr);
+ typename ptrait_type::element_type* p = boost::to_address(ptr);
try {
traity_type::construct( alloc_, p, alloc_, std::move( fn_) );
} catch (...) {
diff --git a/boost/fiber/future/packaged_task.hpp b/boost/fiber/future/packaged_task.hpp
index c8b10d43e0..22e934285c 100644
--- a/boost/fiber/future/packaged_task.hpp
+++ b/boost/fiber/future/packaged_task.hpp
@@ -60,7 +60,7 @@ public:
typename object_type::allocator_type a{ alloc };
typename traits_type::pointer ptr{ traits_type::allocate( a, 1) };
- typename ptrait_type::element_type* p = ptrait_type::to_address(ptr);
+ typename ptrait_type::element_type* p = boost::to_address(ptr);
try {
traits_type::construct( a, p, a, std::forward< Fn >( fn) );
} catch (...) {
diff --git a/boost/fiber/future/promise.hpp b/boost/fiber/future/promise.hpp
index 661c8b0480..1e6e285c77 100644
--- a/boost/fiber/future/promise.hpp
+++ b/boost/fiber/future/promise.hpp
@@ -41,7 +41,7 @@ struct promise_base {
typedef pointer_traits< typename traits_type::pointer > ptrait_type;
typename object_type::allocator_type a{ alloc };
typename traits_type::pointer ptr{ traits_type::allocate( a, 1) };
- typename ptrait_type::element_type* p = ptrait_type::to_address(ptr);
+ typename ptrait_type::element_type* p = boost::to_address(ptr);
try {
traits_type::construct( a, p, a);
diff --git a/boost/fiber/hip/waitfor.hpp b/boost/fiber/hip/waitfor.hpp
new file mode 100644
index 0000000000..e05099ef48
--- /dev/null
+++ b/boost/fiber/hip/waitfor.hpp
@@ -0,0 +1,139 @@
+
+// Copyright Oliver Kowalke 2017.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIBERS_CUDA_WAITFOR_H
+#define BOOST_FIBERS_CUDA_WAITFOR_H
+
+#include <initializer_list>
+#include <mutex>
+#include <iostream>
+#include <set>
+#include <tuple>
+#include <vector>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+#include <hip/hip_runtime.h>
+
+#include <boost/fiber/detail/config.hpp>
+#include <boost/fiber/detail/is_all_same.hpp>
+#include <boost/fiber/condition_variable.hpp>
+#include <boost/fiber/mutex.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace fibers {
+namespace cuda {
+namespace detail {
+
+template< typename Rendezvous >
+static void trampoline( hipStream_t st, hipError_t status, void * vp) {
+ Rendezvous * data = static_cast< Rendezvous * >( vp);
+ data->notify( st, status);
+}
+
+class single_stream_rendezvous {
+public:
+ single_stream_rendezvous( hipStream_t st) {
+ unsigned int flags = 0;
+ hipError_t status = ::hipStreamAddCallback( st, trampoline< single_stream_rendezvous >, this, flags);
+ if ( hipSuccess != status) {
+ st_ = st;
+ status_ = status;
+ done_ = true;
+ }
+ }
+
+ void notify( hipStream_t st, hipError_t status) noexcept {
+ std::unique_lock< mutex > lk{ mtx_ };
+ st_ = st;
+ status_ = status;
+ done_ = true;
+ lk.unlock();
+ cv_.notify_one();
+ }
+
+ std::tuple< hipStream_t, hipError_t > wait() {
+ std::unique_lock< mutex > lk{ mtx_ };
+ cv_.wait( lk, [this]{ return done_; });
+ return std::make_tuple( st_, status_);
+ }
+
+private:
+ mutex mtx_{};
+ condition_variable cv_{};
+ hipStream_t st_{};
+ hipError_t status_{ hipErrorUnknown };
+ bool done_{ false };
+};
+
+class many_streams_rendezvous {
+public:
+ many_streams_rendezvous( std::initializer_list< hipStream_t > l) :
+ stx_{ l } {
+ results_.reserve( stx_.size() );
+ for ( hipStream_t st : stx_) {
+ unsigned int flags = 0;
+ hipError_t status = ::hipStreamAddCallback( st, trampoline< many_streams_rendezvous >, this, flags);
+ if ( hipSuccess != status) {
+ std::unique_lock< mutex > lk{ mtx_ };
+ stx_.erase( st);
+ results_.push_back( std::make_tuple( st, status) );
+ }
+ }
+ }
+
+ void notify( hipStream_t st, hipError_t status) noexcept {
+ std::unique_lock< mutex > lk{ mtx_ };
+ stx_.erase( st);
+ results_.push_back( std::make_tuple( st, status) );
+ if ( stx_.empty() ) {
+ lk.unlock();
+ cv_.notify_one();
+ }
+ }
+
+ std::vector< std::tuple< hipStream_t, hipError_t > > wait() {
+ std::unique_lock< mutex > lk{ mtx_ };
+ cv_.wait( lk, [this]{ return stx_.empty(); });
+ return results_;
+ }
+
+private:
+ mutex mtx_{};
+ condition_variable cv_{};
+ std::set< hipStream_t > stx_;
+ std::vector< std::tuple< hipStream_t, hipError_t > > results_;
+};
+
+}
+
+void waitfor_all();
+
+inline
+std::tuple< hipStream_t, hipError_t > waitfor_all( hipStream_t st) {
+ detail::single_stream_rendezvous rendezvous( st);
+ return rendezvous.wait();
+}
+
+template< typename ... STP >
+std::vector< std::tuple< hipStream_t, hipError_t > > waitfor_all( hipStream_t st0, STP ... stx) {
+ static_assert( boost::fibers::detail::is_all_same< hipStream_t, STP ...>::value, "all arguments must be of type `CUstream*`.");
+ detail::many_streams_rendezvous rendezvous{ st0, stx ... };
+ return rendezvous.wait();
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_FIBERS_CUDA_WAITFOR_H
diff --git a/boost/fiber/unbuffered_channel.hpp b/boost/fiber/unbuffered_channel.hpp
index 1474299ded..b2717b0068 100644
--- a/boost/fiber/unbuffered_channel.hpp
+++ b/boost/fiber/unbuffered_channel.hpp
@@ -94,7 +94,8 @@ private:
}
public:
- unbuffered_channel() = default;
+ unbuffered_channel() {
+ }
~unbuffered_channel() {
close();