• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/libs/core/threading_base/include/hpx/threading_base/thread_description.hpp
1
//  Copyright (c) 2016-2025 Hartmut Kaiser
2
//
3
//  SPDX-License-Identifier: BSL-1.0
4
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
5
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6

7
#pragma once
8

9
#include <hpx/config.hpp>
10
#include <hpx/assert.hpp>
11
#include <hpx/modules/errors.hpp>
12
#include <hpx/modules/functional.hpp>
13
#include <hpx/threading_base/threading_base_fwd.hpp>
14
#if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
15
#include <hpx/modules/itt_notify.hpp>
16
#endif
17

18
#include <cstddef>
19
#include <cstdint>
20
#include <iosfwd>
21
#include <string>
22
#include <type_traits>
23
#include <utility>
24

25
namespace hpx::detail {
26

27
    HPX_CORE_EXPORT char const* store_function_annotation(std::string name);
28
}    // namespace hpx::detail
29

30
namespace hpx::threads {
31

32
#if defined(HPX_HAVE_THREAD_DESCRIPTION)
33
    ///////////////////////////////////////////////////////////////////////////
34
    HPX_CXX_EXPORT struct thread_description
35
    {
36
    public:
37
        enum class data_type : std::uint8_t
38
        {
39
            description = 0,
40
            address = 1
41
        };
42

43
    private:
44
        struct data
45
        {
46
            union
47
            {
48
                char const* desc_;    //-V117
49
                std::size_t addr_;    //-V117
50
            };
51
            data_type type_;
52

53
            constexpr data() noexcept
54
              : desc_(nullptr)
55
              , type_(data_type::description)
56
            {
57
            }
58
            explicit constexpr data(char const* str) noexcept
59
              : desc_(str)
60
              , type_(data_type::description)
61
            {
62
            }
63
        };
64

65
        data data_;
66
#if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
67
        util::itt::string_handle desc_itt_;
68
#endif
69

70
        HPX_CORE_EXPORT void init_from_alternative_name(char const* altname);
71

72
    public:
73
        constexpr thread_description() noexcept
74
          : data_("<unknown>")
75
        {
76
        }
77

78
        constexpr thread_description(char const* desc) noexcept
79
          : data_(desc ? desc : "<unknown>")
80
        {
81
        }
82

83
        explicit thread_description(std::string desc)
84
          : data_(hpx::detail::store_function_annotation(HPX_MOVE(desc)))
85
        {
86
        }
87

88
#if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
89
        thread_description(
90
            char const* desc, util::itt::string_handle sh) noexcept
91
          : data_(desc ? desc : "<unknown>")
92
          , desc_itt_(HPX_MOVE(sh))
93
        {
94
        }
95

96
        thread_description(std::string desc, util::itt::string_handle sh)
97
          : data_(hpx::detail::store_function_annotation(HPX_MOVE(desc)))
98
          , desc_itt_(HPX_MOVE(sh))
99
        {
100
        }
101
#endif
102

103
        // The priority of description is name, altname, address
104
        template <typename F,
105
            typename =
106
                std::enable_if_t<!std::is_same_v<F, thread_description> &&
107
                    !traits::is_action_v<F>>>
108
        explicit thread_description(
109
            F const& f, char const* altname = nullptr) noexcept
110
        {
111
            // If a name exists, use it, not the altname.
112
            if (char const* name = traits::get_function_annotation<F>::call(f);
113
                name != nullptr)    // -V547
114
            {
115
                altname = name;
116
#if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
117
                desc_itt_ = traits::get_function_annotation_itt<F>::call(f);
118
#endif
119
            }
120

121
#if defined(HPX_HAVE_THREAD_DESCRIPTION_FULL)
122
            if (altname != nullptr)
123
            {
124
                data_.desc_ = altname;
125
            }
126
            else
127
            {
128
                data_.type_ = data_type::address;
129
                data_.addr_ = traits::get_function_address<F>::call(f);
130
            }
131
#else
132
            init_from_alternative_name(altname);
133
#endif
134

135
#if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
136
            if (!desc_itt_)
137
            {
138
                desc_itt_ = util::itt::string_handle(get_description());
139
            }
140
#endif
141
        }
142

143
        template <typename Action,
144
            typename = std::enable_if_t<traits::is_action_v<Action>>>
145
        explicit thread_description(
146
            Action, char const* /* altname */ = nullptr) noexcept
147
          : data_(hpx::actions::detail::get_action_name<Action>())
148
#if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
149
          , desc_itt_(hpx::actions::detail::get_action_name_itt<Action>())
150
#endif
151
        {
152
        }
153

154
        [[nodiscard]] constexpr data_type kind() const noexcept
155
        {
156
            return data_.type_;
157
        }
158

159
        [[nodiscard]] constexpr char const* get_description() const noexcept
160
        {
161
            HPX_ASSERT(data_.type_ == data_type::description);
162
            return data_.desc_;
163
        }
164

165
#if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
166
        [[nodiscard]] util::itt::string_handle get_description_itt()
167
            const noexcept
168
        {
169
            HPX_ASSERT(data_.type_ == data_type::description);
170
            return desc_itt_ ? desc_itt_ :
171
                               util::itt::string_handle(get_description());
172
        }
173

174
        [[nodiscard]] util::itt::task get_task_itt(
175
            util::itt::domain const& domain) const noexcept
176
        {
177
            switch (kind())
178
            {
179
            case threads::thread_description::data_type::description:
180
                return {domain, get_description_itt()};
181

182
            case threads::thread_description::data_type::address:
183
                return {
184
                    domain, util::itt::string_handle("address"), get_address()};
185

186
            default:
187
                HPX_ASSERT(false);
188
                break;
189
            }
190

191
            return {domain, util::itt::string_handle("<error>")};
192
        }
193
#endif
194

195
        [[nodiscard]] constexpr std::size_t get_address() const noexcept
196
        {
197
            HPX_ASSERT(data_.type_ == data_type::address);
198
            return data_.addr_;
199
        }
200

201
        [[nodiscard]] explicit constexpr operator bool() const noexcept
202
        {
203
            return valid();
204
        }
205

206
        [[nodiscard]] constexpr bool valid() const noexcept
207
        {
208
            if (data_.type_ == data_type::description)
209
                return nullptr != data_.desc_;
210

211
            HPX_ASSERT(data_.type_ == data_type::address);
212
            return 0 != data_.addr_;
213
        }
214
    };
215
#else
216
    ///////////////////////////////////////////////////////////////////////////
217
    HPX_CXX_EXPORT struct thread_description
218
    {
219
    public:
220
        enum class data_type : std::uint8_t
221
        {
222
            description = 0,
223
            address = 1
224
        };
225

226
    private:
227
        // expose for ABI compatibility reasons
228
        HPX_CORE_EXPORT void init_from_alternative_name(char const* altname);
229

230
    public:
231
        thread_description() noexcept = default;
232

233
        constexpr thread_description(char const* /*desc*/) noexcept {}
234
        constexpr explicit thread_description(
235
            std::string const& /*desc*/) noexcept
236
        {
237
        }
238

239
        template <typename F,
240
            typename =
241
                std::enable_if_t<!std::is_same_v<F, thread_description> &&
242
                    !traits::is_action_v<F>>>
243
        explicit constexpr thread_description(
244
            F const& /*f*/, char const* /*altname*/ = nullptr) noexcept
245
        {
246
        }
247

248
        template <typename Action,
249
            typename = std::enable_if_t<traits::is_action_v<Action>>>
250
        explicit constexpr thread_description(
251
            Action, char const* /*altname*/ = nullptr) noexcept
252
        {
253
        }
254

255
        [[nodiscard]] static constexpr data_type kind() noexcept
256
        {
257
            return data_type::description;
258
        }
259

260
        [[nodiscard]] static constexpr char const* get_description() noexcept
261
        {
262
            return "<unknown>";
×
263
        }
264

×
265
#if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
266
        [[nodiscard]] util::itt::string_handle get_description_itt()
267
            const noexcept
268
        {
269
            HPX_ASSERT(data_.type_ == data_type::description);
270
            return util::itt::string_handle(get_description());
271
        }
272

273
        [[nodiscard]] util::itt::task get_task_itt(
274
            util::itt::domain const& domain) const noexcept
275
        {
276
            switch (kind())
277
            {
278
            case threads::thread_description::data_type::description:
279
                return {domain, get_description_itt()};
280

281
            case threads::thread_description::data_type::address:
282
                return {domain, "address", get_address()};
283

284
            default:
285
                HPX_ASSERT(false);
286
                break;
287
            }
288

289
            return {domain, "<error>"};
290
        }
291
#endif
292

293
        [[nodiscard]] static constexpr std::size_t get_address() noexcept
294
        {
295
            return 0;
296
        }
297

298
        [[nodiscard]] explicit constexpr operator bool() const noexcept
299
        {
300
            return valid();
301
        }
302

303
        [[nodiscard]] static constexpr bool valid() noexcept
304
        {
305
            return true;
306
        }
307
    };
308
#endif
309

310
    HPX_CXX_EXPORT HPX_CORE_EXPORT std::ostream& operator<<(
311
        std::ostream&, thread_description const&);
312
    HPX_CXX_EXPORT HPX_CORE_EXPORT std::string as_string(
313
        thread_description const& desc);
314
}    // namespace hpx::threads
315

316
namespace hpx::threads {
317
    ///////////////////////////////////////////////////////////////////////////
318
    /// The function get_thread_description is part of the thread related API
319
    /// allows to query the description of one of the threads known to the
320
    /// thread-manager.
321
    ///
322
    /// \param id         [in] The thread id of the thread being queried.
323
    /// \param ec         [in,out] this represents the error status on exit,
324
    ///                   if this is pre-initialized to \a hpx#throws
325
    ///                   the function will throw on error instead.
326
    ///
327
    /// \returns          This function returns the description of the
328
    ///                   thread referenced by the \a id parameter. If the
329
    ///                   thread is not known to the thread-manager the return
330
    ///                   value will be the string "<unknown>".
331
    ///
332
    /// \note             As long as \a ec is not pre-initialized to
333
    ///                   \a hpx#throws this function doesn't
334
    ///                   throw but returns the result code using the
335
    ///                   parameter \a ec. Otherwise it throws an instance
336
    ///                   of hpx#exception.
337
    HPX_CXX_EXPORT HPX_CORE_EXPORT threads::thread_description
338
    get_thread_description(thread_id_type const& id, error_code& ec = throws);
339
    HPX_CXX_EXPORT HPX_CORE_EXPORT threads::thread_description
340
    set_thread_description(thread_id_type const& id,
341
        threads::thread_description const& desc = threads::thread_description(),
342
        error_code& ec = throws);
343

344
    HPX_CXX_EXPORT HPX_CORE_EXPORT threads::thread_description
345
    get_thread_lco_description(
346
        thread_id_type const& id, error_code& ec = throws);
347
    HPX_CXX_EXPORT HPX_CORE_EXPORT threads::thread_description
348
    set_thread_lco_description(thread_id_type const& id,
349
        threads::thread_description const& desc = threads::thread_description(),
350
        error_code& ec = throws);
351
}    // namespace hpx::threads
352

353
namespace hpx::util {
354

355
    using thread_description HPX_DEPRECATED_V(1, 9,
356
        "hpx::util::thread_description is deprecated, use "
357
        "hpx::threads::thread_description instead") =
358
        hpx::threads::thread_description;
359
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc