1 //  Copyright (c) 2007-2017 Hartmut Kaiser
2 //  Copyright (c)      2011 Bryce Lelbach
3 //  Copyright (c)      2011 Thomas Heller
4 //
5 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
6 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 
8 /// \file action_support.hpp
9 
10 #if !defined(HPX_RUNTIME_ACTIONS_ACTION_SUPPORT_NOV_14_2008_0711PM)
11 #define HPX_RUNTIME_ACTIONS_ACTION_SUPPORT_NOV_14_2008_0711PM
12 
13 #include <hpx/config.hpp>
14 #include <hpx/runtime/actions_fwd.hpp>
15 #include <hpx/runtime/components/pinned_ptr.hpp>
16 #include <hpx/runtime/parcelset_fwd.hpp>
17 #include <hpx/runtime/serialization/base_object.hpp>
18 #include <hpx/runtime/serialization/input_archive.hpp>
19 #include <hpx/runtime/serialization/output_archive.hpp>
20 #include <hpx/runtime/threads/thread_helpers.hpp>
21 #include <hpx/runtime/threads/thread_init_data.hpp>
22 #include <hpx/traits/action_remote_result.hpp>
23 #include <hpx/util/detail/pp/cat.hpp>
24 #include <hpx/util/detail/pp/nargs.hpp>
25 #include <hpx/util/tuple.hpp>
26 #include <hpx/util/debug/demangle_helper.hpp>
27 #if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
28 #include <hpx/util/itt_notify.hpp>
29 #endif
30 
31 #include <cstddef>
32 #include <cstdint>
33 #include <memory>
34 #include <utility>
35 
36 #include <hpx/config/warnings_prefix.hpp>
37 
38 /// \cond NOINTERNAL
39 namespace hpx { namespace traits
40 {
41     namespace detail
42     {
43         ///////////////////////////////////////////////////////////////////////
44         // If an action returns void, we need to do special things
45         template <>
46         struct action_remote_result_customization_point<void>
47         {
48             typedef util::unused_type type;
49         };
50     }
51 }}
52 /// \endcond
53 
54 ///////////////////////////////////////////////////////////////////////////////
55 /// \namespace actions
56 namespace hpx { namespace actions
57 {
58     /// \cond NOINTERNAL
59 
60     ///////////////////////////////////////////////////////////////////////////
61     namespace detail
62     {
63         template <typename Action>
64         char const* get_action_name()
65 #ifndef HPX_HAVE_AUTOMATIC_SERIALIZATION_REGISTRATION
66         ;
67 #else
68         {
69             /// If you encounter this assert while compiling code, that means that
70             /// you have a HPX_REGISTER_ACTION macro somewhere in a source file,
71             /// but the header in which the action is defined misses a
72             /// HPX_REGISTER_ACTION_DECLARATION
73             static_assert(
74                 traits::needs_automatic_registration<Action>::value,
75                 "HPX_REGISTER_ACTION_DECLARATION missing");
76             return util::debug::type_id<Action>::typeid_.type_id();
77         }
78 #endif
79 
80         template <typename Action>
get_action_id()81         std::uint32_t get_action_id()
82         {
83             static std::uint32_t id = get_action_id_from_name(
84                 get_action_name<Action>());
85             return id;
86         }
87 
88 #if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
89         template <typename Action>
90         util::itt::string_handle const& get_action_name_itt()
91 #ifndef HPX_HAVE_AUTOMATIC_SERIALIZATION_REGISTRATION
92         ;
93 #else
94         {
95             static util::itt::string_handle sh = get_action_name<Action>();
96             return sh;
97         }
98 #endif
99 #endif
100     }
101 
102 
103     ///////////////////////////////////////////////////////////////////////////
104     namespace detail
105     {
106         ///////////////////////////////////////////////////////////////////////
107         // Figure out what priority the action has to be be associated with
108         // A dynamically specified default priority results in using the static
109         // Priority.
110         template <threads::thread_priority Priority>
111         struct thread_priority
112         {
113             static threads::thread_priority
callhpx::actions::detail::thread_priority114             call(threads::thread_priority priority)
115             {
116                 if (priority == threads::thread_priority_default)
117                     return Priority;
118                 return priority;
119             }
120         };
121 
122         // If the static Priority is default, a dynamically specified default
123         // priority results in using the normal priority.
124         template <>
125         struct thread_priority<threads::thread_priority_default>
126         {
127             static threads::thread_priority
callhpx::actions::detail::thread_priority128             call(threads::thread_priority priority)
129             {
130 //              The mapping to 'normal' is now done at the last possible moment
131 //              in the scheduler.
132 //                 if (priority == threads::thread_priority_default)
133 //                     return threads::thread_priority_normal;
134                 return priority;
135             }
136         };
137 
138         ///////////////////////////////////////////////////////////////////////
139         // Figure out what stacksize the action has to be be associated with
140         // A dynamically specified default stacksize results in using the static
141         // Stacksize.
142         template <threads::thread_stacksize Stacksize>
143         struct thread_stacksize
144         {
145             static threads::thread_stacksize
callhpx::actions::detail::thread_stacksize146             call(threads::thread_stacksize stacksize)
147             {
148                 if (stacksize == threads::thread_stacksize_default)
149                     return Stacksize;
150                 return stacksize;
151             }
152         };
153 
154         // If the static Stacksize is default, a dynamically specified default
155         // stacksize results in using the normal stacksize.
156         template <>
157         struct thread_stacksize<threads::thread_stacksize_default>
158         {
159             static threads::thread_stacksize
callhpx::actions::detail::thread_stacksize160             call(threads::thread_stacksize stacksize)
161             {
162                 if (stacksize == threads::thread_stacksize_default)
163                     return threads::thread_stacksize_minimal;
164                 return stacksize;
165             }
166         };
167     }
168     /// \endcond
169 }}
170 
171 #include <hpx/config/warnings_suffix.hpp>
172 
173 #endif
174