1 //  Copyright (c) 2018 Hartmut Kaiser
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 #include <hpx/config.hpp>
7 #include <hpx/runtime/threads/thread_data_fwd.hpp>
8 
9 #include <hpx/runtime/actions/base_action.hpp>
10 #include <hpx/runtime/get_locality_id.hpp>
11 #include <hpx/runtime/serialization/serialize.hpp>
12 #include <hpx/runtime/serialization/input_archive.hpp>
13 #include <hpx/runtime/serialization/output_archive.hpp>
14 #include <hpx/traits/is_bitwise_serializable.hpp>
15 
16 #include <cstdint>
17 
18 ///////////////////////////////////////////////////////////////////////////////
19 namespace hpx { namespace actions { namespace detail
20 {
21     ///////////////////////////////////////////////////////////////////////////
22     struct action_serialization_data
23     {
action_serialization_datahpx::actions::detail::action_serialization_data24         action_serialization_data()
25           : parent_locality_(naming::invalid_locality_id)
26           , parent_id_(static_cast<std::uint64_t>(0))
27           , parent_phase_(0)
28           , priority_(static_cast<threads::thread_priority>(0))
29           , stacksize_(static_cast<threads::thread_stacksize>(0))
30         {}
31 
action_serialization_datahpx::actions::detail::action_serialization_data32         action_serialization_data(std::uint32_t parent_locality,
33                 threads::thread_id_type parent_id,
34                 std::uint64_t parent_phase,
35                 threads::thread_priority priority,
36                 threads::thread_stacksize stacksize)
37           : parent_locality_(parent_locality)
38           , parent_id_(reinterpret_cast<std::uint64_t>(parent_id.get()))
39           , parent_phase_(parent_phase)
40           , priority_(priority)
41           , stacksize_(stacksize)
42         {}
43 
44         std::uint32_t parent_locality_;
45         std::uint64_t parent_id_;
46         std::uint64_t parent_phase_;
47         threads::thread_priority priority_;
48         threads::thread_stacksize stacksize_;
49 
50         template <typename Archive>
serializehpx::actions::detail::action_serialization_data51         void serialize(Archive& ar, unsigned)
52         {
53             ar & parent_id_ & parent_phase_ & parent_locality_
54                & priority_ & stacksize_;
55         }
56     };
57 }}}
58 
59 HPX_IS_BITWISE_SERIALIZABLE(hpx::actions::detail::action_serialization_data)
60 
61 ///////////////////////////////////////////////////////////////////////////////
62 namespace hpx { namespace actions
63 {
64     ///////////////////////////////////////////////////////////////////////////
~base_action()65     base_action::~base_action()
66     {
67     }
68 
69     ///////////////////////////////////////////////////////////////////////////
base_action_data(threads::thread_priority priority,threads::thread_stacksize stacksize)70     base_action_data::base_action_data(threads::thread_priority priority,
71             threads::thread_stacksize stacksize)
72       : priority_(priority)
73       , stacksize_(stacksize)
74 #if defined(HPX_HAVE_THREAD_PARENT_REFERENCE)
75       , parent_locality_(base_action_data::get_locality_id())
76       , parent_id_(threads::get_parent_id())
77       , parent_phase_(threads::get_parent_phase())
78 #endif
79     {
80     }
81 
82     // serialization support
83     // loading ...
load_base(hpx::serialization::input_archive & ar)84     void base_action_data::load_base(hpx::serialization::input_archive & ar)
85     {
86         // Always serialize the parent information to maintain binary
87         // compatibility on the wire.
88 
89         detail::action_serialization_data data;
90         ar >> data;
91 
92 #if defined(HPX_HAVE_THREAD_PARENT_REFERENCE)
93         parent_locality_ = data.parent_locality_;
94         parent_id_ = threads::thread_id_type(
95             reinterpret_cast<threads::thread_data*>(data.parent_id_));
96         parent_phase_ = data.parent_phase_;
97 #endif
98         priority_ = data.priority_;
99         stacksize_ = data.stacksize_;
100     }
101 
102     // saving ...
save_base(hpx::serialization::output_archive & ar)103     void base_action_data::save_base(hpx::serialization::output_archive & ar)
104     {
105         // Always serialize the parent information to maintain binary
106         // compatibility on the wire.
107 
108 #if !defined(HPX_HAVE_THREAD_PARENT_REFERENCE)
109         std::uint32_t parent_locality_ = naming::invalid_locality_id;
110         threads::thread_id_type parent_id_;
111         std::uint64_t parent_phase_ = 0;
112 #endif
113         detail::action_serialization_data data(parent_locality_,
114             parent_id_, parent_phase_, priority_, stacksize_);
115         ar << data;
116     }
117 
118     ///////////////////////////////////////////////////////////////////////////
get_locality_id()119     std::uint32_t base_action_data::get_locality_id()
120     {
121         error_code ec(lightweight);      // ignore any errors
122         return hpx::get_locality_id(ec);
123     }
124 
125     ///////////////////////////////////////////////////////////////////////////
126 #if !defined(HPX_HAVE_THREAD_PARENT_REFERENCE)
127     /// Return the locality of the parent thread
get_parent_locality_id() const128     std::uint32_t base_action_data::get_parent_locality_id() const
129     {
130         return naming::invalid_locality_id;
131     }
132 
133     /// Return the thread id of the parent thread
get_parent_thread_id() const134     threads::thread_id_type base_action_data::get_parent_thread_id() const
135     {
136         return threads::invalid_thread_id;
137     }
138 
139     /// Return the phase of the parent thread
get_parent_thread_phase() const140     std::uint64_t base_action_data::get_parent_thread_phase() const
141     {
142         return 0;
143     }
144 #else
145     /// Return the locality of the parent thread
get_parent_locality_id() const146     std::uint32_t base_action_data::get_parent_locality_id() const
147     {
148         return parent_locality_;
149     }
150 
151     /// Return the thread id of the parent thread
get_parent_thread_id() const152     threads::thread_id_type base_action_data::get_parent_thread_id() const
153     {
154         return parent_id_;
155     }
156 
157     /// Return the phase of the parent thread
get_parent_thread_phase() const158     std::uint64_t base_action_data::get_parent_thread_phase() const
159     {
160         return parent_phase_;
161     }
162 #endif
163 
164     /// Return the thread priority this action has to be executed with
get_thread_priority() const165     threads::thread_priority base_action_data::get_thread_priority() const
166     {
167         return priority_;
168     }
169 
170     /// Return the thread stacksize this action has to be executed with
get_thread_stacksize() const171     threads::thread_stacksize base_action_data::get_thread_stacksize() const
172     {
173         return stacksize_;
174     }
175 }}
176