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