1 // Copyright (c) 2016 Thomas Heller 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #ifndef HPX_LCOS_DETAIL_BARRIER_NODE_HPP 7 #define HPX_LCOS_DETAIL_BARRIER_NODE_HPP 8 9 #include <hpx/config.hpp> 10 #include <hpx/lcos/base_lco.hpp> 11 #include <hpx/lcos/future.hpp> 12 #include <hpx/lcos/local/barrier.hpp> 13 #include <hpx/lcos/local/promise.hpp> 14 #include <hpx/lcos/local/spinlock.hpp> 15 #include <hpx/runtime/components/server/managed_component_base.hpp> 16 #include <hpx/runtime/naming/id_type.hpp> 17 #include <hpx/traits/managed_component_policies.hpp> 18 #include <hpx/util/assert.hpp> 19 #include <hpx/util/atomic_count.hpp> 20 21 #include <cstddef> 22 #include <string> 23 #include <vector> 24 25 #include <hpx/config/warnings_prefix.hpp> 26 27 namespace hpx { namespace lcos { namespace detail { 28 struct HPX_EXPORT barrier_node; 29 }}} 30 31 /////////////////////////////////////////////////////////////////////////////// 32 namespace hpx { 33 namespace traits { 34 template <> 35 struct managed_component_dtor_policy< 36 lcos::detail::barrier_node> 37 { 38 typedef managed_object_is_lifetime_controlled type; 39 }; 40 } 41 } 42 43 namespace hpx { namespace lcos { namespace detail { 44 struct barrier_node : base_lco 45 { 46 typedef components::managed_component<barrier_node> wrapping_type; 47 typedef hpx::lcos::local::spinlock mutex_type; 48 49 barrier_node(); 50 barrier_node(std::string base_name, std::size_t num, std::size_t rank); 51 void set_event(); 52 hpx::future<void> gather(); 53 54 hpx::future<void> wait(bool async); 55 56 HPX_DEFINE_COMPONENT_DIRECT_ACTION(barrier_node, gather); 57 58 private: 59 hpx::util::atomic_count count_; 60 61 std::vector<naming::id_type> children_; 62 63 public: 64 std::string base_name_; 65 std::size_t rank_; 66 std::size_t num_; 67 std::size_t arity_; 68 std::size_t cut_off_; 69 private: 70 hpx::lcos::local::promise<void> gather_promise_; 71 hpx::lcos::local::promise<void> broadcast_promise_; 72 hpx::lcos::local::barrier local_barrier_; 73 74 template <typename This> 75 hpx::future<void> do_wait(This this_, hpx::future<void> future); 76 77 template <typename> 78 friend struct components::detail_adl_barrier::init; 79 set_back_ptrhpx::lcos::detail::barrier_node80 void set_back_ptr(components::managed_component<barrier_node>* bp) 81 { 82 HPX_ASSERT(bp); 83 } 84 85 // intrusive reference counting intrusive_ptr_add_ref(barrier_node * p)86 friend void intrusive_ptr_add_ref(barrier_node* p) 87 { 88 ++p->count_; 89 } 90 91 // intrusive reference counting intrusive_ptr_release(barrier_node * p)92 friend void intrusive_ptr_release(barrier_node* p) 93 { 94 if (p && --p->count_ == 0) 95 { 96 delete p; 97 } 98 } 99 }; 100 }}} 101 102 HPX_REGISTER_ACTION_DECLARATION(hpx::lcos::detail::barrier_node::gather_action, 103 barrier_node_gather_action); 104 105 #include <hpx/config/warnings_suffix.hpp> 106 107 #endif 108