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

STEllAR-GROUP / hpx / #857

28 Dec 2022 11:12PM UTC coverage: 86.543% (-0.06%) from 86.602%
#857

push

StellarBot
Merge #6118

6118: Modernize modules from level 17, 18, 19, and 20 r=hkaiser a=hkaiser

working towards https://github.com/STEllAR-GROUP/hpx/issues/5497

Modules:
- core/threading_base
- full/command_line_handling
- core/io_service
- core/schedulers
- core/synchronization
- core/futures
- core/thread_pools
- core/lcos_local
- core/pack_traversal
- core/resource_partitioner
- core/threading
- full/naming_base


Co-authored-by: Hartmut Kaiser <hartmut.kaiser@gmail.com>

849 of 849 new or added lines in 98 files covered. (100.0%)

174389 of 201505 relevant lines covered (86.54%)

1916353.25 hits per line

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

57.08
/libs/core/threading_base/src/thread_helpers.cpp
1
//  Copyright (c) 2007-2022 Hartmut Kaiser
2
//  Copyright (c)      2011 Bryce Lelbach
3
//
4
//  SPDX-License-Identifier: BSL-1.0
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
#include <hpx/threading_base/thread_helpers.hpp>
9

10
#include <hpx/assert.hpp>
11
#include <hpx/coroutines/thread_enums.hpp>
12
#include <hpx/execution_base/this_thread.hpp>
13
#include <hpx/modules/errors.hpp>
14
#include <hpx/threading_base/scheduler_base.hpp>
15
#include <hpx/threading_base/scheduler_state.hpp>
16
#include <hpx/threading_base/set_thread_state.hpp>
17
#include <hpx/threading_base/set_thread_state_timed.hpp>
18
#include <hpx/threading_base/thread_description.hpp>
19
#include <hpx/threading_base/thread_pool_base.hpp>
20
#include <hpx/timing/steady_clock.hpp>
21

22
#ifdef HPX_HAVE_VERIFY_LOCKS
23
#include <hpx/lock_registration/detail/register_locks.hpp>
24
#endif
25
#ifdef HPX_HAVE_THREAD_DESCRIPTION
26
#include <hpx/threading_base/detail/reset_lco_description.hpp>
27
#endif
28
#ifdef HPX_HAVE_THREAD_BACKTRACE_ON_SUSPENSION
29
#include <hpx/debugging/backtrace.hpp>
30
#include <hpx/threading_base/detail/reset_backtrace.hpp>
31
#endif
32

33
#include <atomic>
34
#include <cstddef>
35
#include <limits>
36
#include <memory>
37
#include <string>
38
#include <utility>
39

40
///////////////////////////////////////////////////////////////////////////////
41
namespace hpx::threads {
42

43
    ///////////////////////////////////////////////////////////////////////////
44
    thread_state set_thread_state(thread_id_type const& id,
876✔
45
        thread_schedule_state state, thread_restart_state stateex,
46
        thread_priority priority, bool retry_on_active, error_code& ec)
47
    {
48
        if (&ec != &throws)
876✔
49
            ec = make_success_code();
2✔
50

51
        return detail::set_thread_state(id, state, stateex, priority,
1,752✔
52
            thread_schedule_hint(), retry_on_active, ec);
876✔
53
    }
×
54

55
    ///////////////////////////////////////////////////////////////////////////
56
    thread_id_ref_type set_thread_state(thread_id_type const& id,
12,131✔
57
        hpx::chrono::steady_time_point const& abs_time,
58
        std::atomic<bool>* timer_started, thread_schedule_state state,
59
        thread_restart_state stateex, thread_priority priority,
60
        bool retry_on_active, error_code& ec)
61
    {
62
        return detail::set_thread_state_timed(
12,131✔
63
            get_thread_id_data(id)->get_scheduler_base(), abs_time, id, state,
12,131✔
64
            stateex, priority, thread_schedule_hint(), timer_started,
12,131✔
65
            retry_on_active, ec);
12,131✔
66
    }
67

68
    ///////////////////////////////////////////////////////////////////////////
69
    thread_state get_thread_state(
12✔
70
        thread_id_type const& id, error_code& /* ec */) noexcept
71
    {
72
        return id ? get_thread_id_data(id)->get_state() :
12✔
73
                    thread_state(thread_schedule_state::terminated,
×
74
                        thread_restart_state::unknown);
75
    }
76

77
    ///////////////////////////////////////////////////////////////////////////
78
    std::size_t get_thread_phase(
128✔
79
        thread_id_type const& id, error_code& /* ec */) noexcept
80
    {
81
        return id ? get_thread_id_data(id)->get_thread_phase() :
128✔
82
                    std::size_t(~0);
83
    }
84

85
    ///////////////////////////////////////////////////////////////////////////
86
    threads::thread_priority get_thread_priority(
18✔
87
        thread_id_type const& id, error_code& /* ec */) noexcept
88
    {
89
        return id ? get_thread_id_data(id)->get_priority() :
18✔
90
                    thread_priority::unknown;
91
    }
92

93
    std::ptrdiff_t get_stack_size(
1,585,390✔
94
        thread_id_type const& id, error_code& /* ec */) noexcept
95
    {
96
        return id ? get_thread_id_data(id)->get_stack_size() :
1,585,390✔
97
                    static_cast<std::ptrdiff_t>(thread_stacksize::unknown);
98
    }
99

100
    void interrupt_thread(thread_id_type const& id, bool flag, error_code& ec)
6✔
101
    {
102
        if (HPX_UNLIKELY(!id))
6✔
103
        {
104
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
×
105
                "hpx::threads::interrupt_thread", "null thread id encountered");
106
            return;
×
107
        }
108

109
        if (&ec != &throws)
6✔
110
            ec = make_success_code();
×
111

112
        get_thread_id_data(id)->interrupt(flag);    // notify thread
5✔
113

114
        // Set thread state to pending. If the thread is currently active we do
115
        // not retry. The thread will either exit or hit an interruption_point.
116
        set_thread_state(id, thread_schedule_state::pending,
12✔
117
            thread_restart_state::abort, thread_priority::normal, false, ec);
5✔
118
    }
6✔
119

120
    void interruption_point(thread_id_type const& id, error_code& ec)
3,523,922✔
121
    {
122
        if (HPX_UNLIKELY(!id))
3,523,504✔
123
        {
124
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
×
125
                "hpx::threads::interruption_point",
126
                "null thread id encountered");
127
            return;
×
128
        }
129

130
        if (&ec != &throws)
3,523,256✔
131
            ec = make_success_code();
×
132

133
        get_thread_id_data(id)->interruption_point();    // notify thread
3,523,026✔
134
    }
3,523,256✔
135

136
    ///////////////////////////////////////////////////////////////////////////
137
    bool get_thread_interruption_enabled(
1✔
138
        thread_id_type const& id, error_code& ec)
139
    {
140
        if (HPX_UNLIKELY(!id))
1✔
141
        {
142
            HPX_THROW_EXCEPTION(hpx::error::null_thread_id,
×
143
                "hpx::threads::get_thread_interruption_enabled",
144
                "null thread id encountered");
145
            return false;
146
        }
147

148
        if (&ec != &throws)
1✔
149
            ec = make_success_code();
×
150

151
        return get_thread_id_data(id)->interruption_enabled();
1✔
152
    }
×
153

154
    bool set_thread_interruption_enabled(
2✔
155
        thread_id_type const& id, bool enable, error_code& ec)
156
    {
157
        if (HPX_UNLIKELY(!id))
2✔
158
        {
159
            HPX_THROW_EXCEPTION(hpx::error::null_thread_id,
×
160
                "hpx::threads::get_thread_interruption_enabled",
161
                "null thread id encountered");
162
            return false;
163
        }
164

165
        if (&ec != &throws)
2✔
166
            ec = make_success_code();
×
167

168
        return get_thread_id_data(id)->set_interruption_enabled(enable);
2✔
169
    }
×
170

171
    bool get_thread_interruption_requested(
×
172
        thread_id_type const& id, error_code& ec)
173
    {
174
        if (HPX_UNLIKELY(!id))
×
175
        {
176
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
×
177
                "hpx::threads::get_thread_interruption_requested",
178
                "null thread id encountered");
179
            return false;
×
180
        }
181

182
        if (&ec != &throws)
×
183
            ec = make_success_code();
×
184

185
        return get_thread_id_data(id)->interruption_requested();
×
186
    }
×
187

188
    ///////////////////////////////////////////////////////////////////////////
189
    std::size_t get_thread_data(thread_id_type const& id, error_code& ec)
2✔
190
    {
191
        if (HPX_UNLIKELY(!id))
2✔
192
        {
193
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
×
194
                "hpx::threads::get_thread_data", "null thread id encountered");
195
            return 0;
×
196
        }
197

198
        return get_thread_id_data(id)->get_thread_data();
2✔
199
    }
2✔
200

201
    std::size_t set_thread_data(
2✔
202
        thread_id_type const& id, std::size_t data, error_code& ec)
203
    {
204
        if (HPX_UNLIKELY(!id))
2✔
205
        {
206
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
×
207
                "hpx::threads::set_thread_data", "null thread id encountered");
208
            return 0;
×
209
        }
210

211
        return get_thread_id_data(id)->set_thread_data(data);
2✔
212
    }
2✔
213

214
#if defined(HPX_HAVE_LIBCDS)
215
    std::size_t get_libcds_data(thread_id_type const& id, error_code& ec)
216
    {
217
        if (HPX_UNLIKELY(!id))
218
        {
219
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
220
                "hpx::threads::get_libcds_data", "null thread id encountered");
221
            return 0;
222
        }
223

224
        return get_thread_id_data(id)->get_libcds_data();
225
    }
226

227
    std::size_t set_libcds_data(
228
        thread_id_type const& id, std::size_t data, error_code& ec)
229
    {
230
        if (HPX_UNLIKELY(!id))
231
        {
232
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
233
                "hpx::threads::set_libcds_data", "null thread id encountered");
234
            return 0;
235
        }
236

237
        return get_thread_id_data(id)->set_libcds_data(data);
238
    }
239

240
    std::size_t get_libcds_hazard_pointer_data(
241
        thread_id_type const& id, error_code& ec)
242
    {
243
        if (HPX_UNLIKELY(!id))
244
        {
245
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
246
                "hpx::threads::get_libcds_hazard_pointer_data",
247
                "null thread id encountered");
248
            return 0;
249
        }
250

251
        return get_thread_id_data(id)->get_libcds_hazard_pointer_data();
252
    }
253

254
    std::size_t set_libcds_hazard_pointer_data(
255
        thread_id_type const& id, std::size_t data, error_code& ec)
256
    {
257
        if (HPX_UNLIKELY(!id))
258
        {
259
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
260
                "hpx::threads::set_libcds_hazard_pointer_data",
261
                "null thread id encountered");
262
            return 0;
263
        }
264

265
        return get_thread_id_data(id)->set_libcds_hazard_pointer_data(data);
266
    }
267

268
    std::size_t get_libcds_dynamic_hazard_pointer_data(
269
        thread_id_type const& id, error_code& ec)
270
    {
271
        if (HPX_UNLIKELY(!id))
272
        {
273
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
274
                "hpx::threads::get_libcds_dynamic_hazard_pointer_data",
275
                "null thread id encountered");
276
            return 0;
277
        }
278

279
        return get_thread_id_data(id)->get_libcds_dynamic_hazard_pointer_data();
280
    }
281

282
    std::size_t set_libcds_dynamic_hazard_pointer_data(
283
        thread_id_type const& id, std::size_t data, error_code& ec)
284
    {
285
        if (HPX_UNLIKELY(!id))
286
        {
287
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
288
                "hpx::threads::set_libcds_dynamic_hazard_pointer_data",
289
                "null thread id encountered");
290
            return 0;
291
        }
292

293
        return get_thread_id_data(id)->set_libcds_dynamic_hazard_pointer_data(
294
            data);
295
    }
296

297
#endif
298

299
    ////////////////////////////////////////////////////////////////////////////
300
    static thread_local std::size_t continuation_recursion_count(0);
301

302
    std::size_t& get_continuation_recursion_count() noexcept
×
303
    {
304
        thread_self* self_ptr = get_self_ptr();
×
305
        if (self_ptr)
×
306
        {
307
            return self_ptr->get_continuation_recursion_count();
×
308
        }
309
        return continuation_recursion_count;
×
310
    }
×
311

312
    void reset_continuation_recursion_count() noexcept
10,899✔
313
    {
314
        continuation_recursion_count = 0;
10,899✔
315
    }
10,938✔
316

317
    ///////////////////////////////////////////////////////////////////////////
318
    void run_thread_exit_callbacks(thread_id_type const& id, error_code& ec)
1,135✔
319
    {
320
        if (HPX_UNLIKELY(!id))
1,135✔
321
        {
322
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
×
323
                "hpx::threads::run_thread_exit_callbacks",
324
                "null thread id encountered");
325
            return;
×
326
        }
327

328
        if (&ec != &throws)
1,135✔
329
            ec = make_success_code();
×
330

331
        get_thread_id_data(id)->run_thread_exit_callbacks();
1,135✔
332
    }
1,135✔
333

334
    bool add_thread_exit_callback(thread_id_type const& id,
1,135✔
335
        hpx::function<void()> const& f, error_code& ec)
336
    {
337
        if (HPX_UNLIKELY(!id))
1,135✔
338
        {
339
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
×
340
                "hpx::threads::add_thread_exit_callback",
341
                "null thread id encountered");
342
            return false;
×
343
        }
344

345
        if (&ec != &throws)
1,135✔
346
            ec = make_success_code();
×
347

348
        return get_thread_id_data(id)->add_thread_exit_callback(f);
1,135✔
349
    }
1,135✔
350

351
    void free_thread_exit_callbacks(thread_id_type const& id, error_code& ec)
1,135✔
352
    {
353
        if (HPX_UNLIKELY(!id))
1,135✔
354
        {
355
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
×
356
                "hpx::threads::add_thread_exit_callback",
357
                "null thread id encountered");
358
            return;
×
359
        }
360

361
        if (&ec != &throws)
1,135✔
362
            ec = make_success_code();
×
363

364
        get_thread_id_data(id)->free_thread_exit_callbacks();
1,135✔
365
    }
1,135✔
366

367
    ///////////////////////////////////////////////////////////////////////////
368
#ifdef HPX_HAVE_THREAD_FULLBACKTRACE_ON_SUSPENSION
369
    char const* get_thread_backtrace(thread_id_type const& id, error_code& ec)
370
#else
371
    util::backtrace const* get_thread_backtrace(
×
372
        thread_id_type const& id, error_code& ec)
373
#endif
374
    {
375
        if (HPX_UNLIKELY(!id))
×
376
        {
377
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
×
378
                "hpx::threads::get_thread_backtrace",
379
                "null thread id encountered");
380
            return nullptr;
×
381
        }
382

383
        if (&ec != &throws)
×
384
            ec = make_success_code();
×
385

386
        return get_thread_id_data(id)->get_backtrace();
×
387
    }
×
388

389
#ifdef HPX_HAVE_THREAD_FULLBACKTRACE_ON_SUSPENSION
390
    char const* set_thread_backtrace(
391
        thread_id_type const& id, char const* bt, error_code& ec)
392
#else
393
    util::backtrace const* set_thread_backtrace(
×
394
        thread_id_type const& id, util::backtrace const* bt, error_code& ec)
395
#endif
396
    {
397
        if (HPX_UNLIKELY(!id))
×
398
        {
399
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
×
400
                "hpx::threads::set_thread_backtrace",
401
                "null thread id encountered");
402
            return nullptr;
×
403
        }
404

405
        if (&ec != &throws)
×
406
            ec = make_success_code();
×
407

408
        return get_thread_id_data(id)->set_backtrace(bt);
×
409
    }
×
410

411
    threads::thread_pool_base* get_pool(
52,091✔
412
        thread_id_type const& id, error_code& ec)
413
    {
414
        if (HPX_UNLIKELY(!id))
52,091✔
415
        {
416
            HPX_THROWS_IF(ec, hpx::error::null_thread_id,
×
417
                "hpx::threads::get_pool", "null thread id encountered");
418
            return nullptr;
×
419
        }
420

421
        if (&ec != &throws)
52,091✔
422
            ec = make_success_code();
×
423

424
        return get_thread_id_data(id)->get_scheduler_base()->get_parent_pool();
52,091✔
425
    }
52,091✔
426
}    // namespace hpx::threads
427

428
namespace hpx::this_thread {
429

430
    // The function \a suspend will return control to the thread manager
431
    // (suspends the current thread). It sets the new state of this thread
432
    // to the thread state passed as the parameter.
433
    //
434
    // If the suspension was aborted, this function will throw a
435
    // \a yield_aborted exception.
436
    threads::thread_restart_state suspend(threads::thread_schedule_state state,
1,751,811✔
437
        threads::thread_id_type nextid,
438
        [[maybe_unused]] threads::thread_description const& description,
439
        error_code& ec)
440
    {
441
        // let the thread manager do other things while waiting
442
        threads::thread_self& self = threads::get_self();
1,751,797✔
443

444
        // keep alive
445
        threads::thread_id_ref_type id = self.get_thread_id();
1,751,797✔
446

447
        // handle interruption, if needed
448
        threads::interruption_point(id.noref(), ec);
1,751,797✔
449
        if (ec)
1,751,771✔
450
            return threads::thread_restart_state::unknown;
×
451

452
        threads::thread_restart_state statex =
1,751,661✔
453
            threads::thread_restart_state::unknown;
454

455
        {
456
            // verify that there are no more registered locks for this OS-thread
457
#ifdef HPX_HAVE_VERIFY_LOCKS
458
            util::verify_no_locks();
1,751,661✔
459
#endif
460
#ifdef HPX_HAVE_THREAD_DESCRIPTION
461
            threads::detail::reset_lco_description desc(
462
                id.noref(), description, ec);
463
#endif
464
#ifdef HPX_HAVE_THREAD_BACKTRACE_ON_SUSPENSION
465
            threads::detail::reset_backtrace bt(id, ec);
466
#endif
467
            // We might need to dispatch 'nextid' to it's correct scheduler
468
            // only if our current scheduler is the same, we should yield the id
469
            if (nextid &&
1,751,661✔
470
                get_thread_id_data(nextid)->get_scheduler_base() !=
28,292✔
471
                    get_thread_id_data(id)->get_scheduler_base())
14,146✔
472
            {
473
                auto* scheduler =
×
474
                    get_thread_id_data(nextid)->get_scheduler_base();
×
475
                scheduler->schedule_thread(
×
476
                    HPX_MOVE(nextid), threads::thread_schedule_hint());
×
477

478
                statex = self.yield(threads::thread_result_type(
×
479
                    state, threads::invalid_thread_id));
480
            }
×
481
            else
482
            {
483
                statex = self.yield(
1,751,635✔
484
                    threads::thread_result_type(state, HPX_MOVE(nextid)));
1,751,626✔
485
            }
486
        }
487

488
        // handle interruption, if needed
489
        threads::interruption_point(id.noref(), ec);
1,751,958✔
490
        if (ec)
1,751,969✔
491
            return threads::thread_restart_state::unknown;
×
492

493
        // handle interrupt and abort
494
        if (statex == threads::thread_restart_state::abort)
1,751,969✔
495
        {
496
            HPX_THROWS_IF(ec, hpx::error::yield_aborted, "suspend",
×
497
                "thread({}, {}) aborted (yield returned wait_abort)",
498
                id.noref(), threads::get_thread_description(id.noref()));
499
        }
×
500

501
        if (&ec != &throws)
1,751,968✔
502
            ec = make_success_code();
×
503

504
        return statex;
1,751,969✔
505
    }
1,751,973✔
506

507
    threads::thread_restart_state suspend(
11,649✔
508
        hpx::chrono::steady_time_point const& abs_time,
509
        threads::thread_id_type nextid,
510
        [[maybe_unused]] threads::thread_description const& description,
511
        error_code& ec)
512
    {
513
        // schedule a thread waking us up at_time
514
        threads::thread_self& self = threads::get_self();
11,649✔
515

516
        // keep alive
517
        threads::thread_id_ref_type id = self.get_thread_id();
11,649✔
518

519
        // handle interruption, if needed
520
        threads::interruption_point(id.noref(), ec);
11,649✔
521
        if (ec)
11,649✔
522
            return threads::thread_restart_state::unknown;
×
523

524
        // let the thread manager do other things while waiting
525
        threads::thread_restart_state statex =
11,649✔
526
            threads::thread_restart_state::unknown;
527

528
        {
529
#ifdef HPX_HAVE_VERIFY_LOCKS
530
            // verify that there are no more registered locks for this OS-thread
531
            util::verify_no_locks();
11,649✔
532
#endif
533
#ifdef HPX_HAVE_THREAD_DESCRIPTION
534
            threads::detail::reset_lco_description desc(
535
                id.noref(), description, ec);
536
#endif
537
#ifdef HPX_HAVE_THREAD_BACKTRACE_ON_SUSPENSION
538
            threads::detail::reset_backtrace bt(id, ec);
539
#endif
540
            std::atomic<bool> timer_started(false);
11,649✔
541
            threads::thread_id_ref_type timer_id =
542
                threads::set_thread_state(id.noref(), abs_time, &timer_started,
23,298✔
543
                    threads::thread_schedule_state::pending,
544
                    threads::thread_restart_state::timeout,
545
                    threads::thread_priority::boost, true, ec);
11,649✔
546
            if (ec)
11,649✔
547
                return threads::thread_restart_state::unknown;
×
548

549
            // We might need to dispatch 'nextid' to it's correct scheduler
550
            // only if our current scheduler is the same, we should yield the id
551
            if (nextid &&
11,649✔
552
                get_thread_id_data(nextid)->get_scheduler_base() !=
×
553
                    get_thread_id_data(id)->get_scheduler_base())
×
554
            {
555
                auto* scheduler =
×
556
                    get_thread_id_data(nextid)->get_scheduler_base();
×
557
                scheduler->schedule_thread(
×
558
                    HPX_MOVE(nextid), threads::thread_schedule_hint());
×
559

560
                statex = self.yield(threads::thread_result_type(
×
561
                    threads::thread_schedule_state::suspended,
×
562
                    threads::invalid_thread_id));
563
            }
×
564
            else
565
            {
566
                statex = self.yield(threads::thread_result_type(
23,298✔
567
                    threads::thread_schedule_state::suspended,
11,649✔
568
                    HPX_MOVE(nextid)));
569
            }
570

571
            if (statex != threads::thread_restart_state::timeout)
11,649✔
572
            {
573
                HPX_ASSERT(statex == threads::thread_restart_state::abort ||
×
574
                    statex == threads::thread_restart_state::signaled);
575

576
                error_code ec1(throwmode::lightweight);    // do not throw
×
577
                hpx::util::yield_while<true>(
×
578
                    [&timer_started]() { return !timer_started.load(); },
×
579
                    "set_thread_state_timed");
580
                threads::set_thread_state(timer_id.noref(),
×
581
                    threads::thread_schedule_state::pending,
582
                    threads::thread_restart_state::abort,
583
                    threads::thread_priority::boost, true, ec1);
584
            }
×
585
        }
11,649✔
586

587
        // handle interruption, if needed
588
        threads::interruption_point(id.noref(), ec);
11,649✔
589
        if (ec)
11,649✔
590
            return threads::thread_restart_state::unknown;
×
591

592
        // handle interrupt and abort
593
        if (statex == threads::thread_restart_state::abort)
11,649✔
594
        {
595
            HPX_THROWS_IF(ec, hpx::error::yield_aborted, "suspend_at",
×
596
                "thread({}, {}) aborted (yield returned wait_abort)",
597
                id.noref(), threads::get_thread_description(id.noref()));
598
        }
×
599

600
        if (&ec != &throws)
11,649✔
601
            ec = make_success_code();
×
602

603
        return statex;
11,649✔
604
    }
11,649✔
605

606
    ///////////////////////////////////////////////////////////////////////////
607
    threads::thread_pool_base* get_pool(error_code& ec)
52,091✔
608
    {
609
        return threads::get_pool(threads::get_self_id(), ec);
52,091✔
610
    }
611

612
    std::ptrdiff_t get_available_stack_space() noexcept
5,453,461✔
613
    {
614
        threads::thread_self* self = threads::get_self_ptr();
5,453,461✔
615
        if (self)
5,453,375✔
616
        {
617
            return self->get_available_stack_space();
5,453,389✔
618
        }
619

620
        return (std::numeric_limits<std::ptrdiff_t>::max)();
×
621
    }
5,453,389✔
622

623
    bool has_sufficient_stack_space(std::size_t space_needed) noexcept
5,817,980✔
624
    {
625
        if (nullptr == hpx::threads::get_self_ptr())
5,817,974✔
626
            return false;
364,530✔
627

628
#if defined(HPX_HAVE_THREADS_GET_STACK_POINTER)
629
        std::ptrdiff_t remaining_stack = get_available_stack_space();
5,453,363✔
630
        if (remaining_stack < 0)
5,453,363✔
631
        {
632
            HPX_THROW_EXCEPTION(hpx::error::out_of_memory,
×
633
                "has_sufficient_stack_space", "Stack overflow");
634
        }
635
        bool sufficient_stack_space =
5,453,362✔
636
            std::size_t(remaining_stack) >= space_needed;
5,453,362✔
637

638
        return sufficient_stack_space;
5,453,362✔
639
#else
640
        return true;
641
#endif
642
    }
5,817,892✔
643
}    // namespace hpx::this_thread
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

© 2025 Coveralls, Inc