diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:11:01 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:11:01 +0900 |
commit | 3fdc3e5ee96dca5b11d1694975a65200787eab86 (patch) | |
tree | 5c1733853892b8397d67706fa453a9bd978d2102 /boost/fiber | |
parent | 88e602c57797660ebe0f9e15dbd64c1ff16dead3 (diff) | |
download | boost-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.hpp | 3 | ||||
-rw-r--r-- | boost/fiber/cuda/waitfor.hpp | 139 | ||||
-rw-r--r-- | boost/fiber/detail/is_all_same.hpp | 44 | ||||
-rw-r--r-- | boost/fiber/future/detail/task_object.hpp | 4 | ||||
-rw-r--r-- | boost/fiber/future/packaged_task.hpp | 2 | ||||
-rw-r--r-- | boost/fiber/future/promise.hpp | 2 | ||||
-rw-r--r-- | boost/fiber/hip/waitfor.hpp | 139 | ||||
-rw-r--r-- | boost/fiber/unbuffered_channel.hpp | 3 |
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(); |