• 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

81.93
/libs/core/threading_base/src/execution_agent.cpp
1
//  Copyright (c) 2019 Thomas Heller
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
#include <hpx/config.hpp>
8
#include <hpx/assert.hpp>
9
#include <hpx/coroutines/thread_enums.hpp>
10
#include <hpx/errors/throw_exception.hpp>
11
#include <hpx/lock_registration/detail/register_locks.hpp>
12
#include <hpx/modules/format.hpp>
13
#include <hpx/modules/logging.hpp>
14
#include <hpx/threading_base/execution_agent.hpp>
15
#include <hpx/threading_base/scheduler_base.hpp>
16
#include <hpx/threading_base/set_thread_state.hpp>
17
#include <hpx/threading_base/thread_data.hpp>
18
#include <hpx/threading_base/thread_description.hpp>
19
#include <hpx/threading_base/thread_num_tss.hpp>
20

21
#ifdef HPX_HAVE_THREAD_DESCRIPTION
22
#include <hpx/threading_base/detail/reset_lco_description.hpp>
23
#endif
24
#ifdef HPX_HAVE_THREAD_BACKTRACE_ON_SUSPENSION
25
#include <hpx/debugging/backtrace.hpp>
26
#include <hpx/threading_base/detail/reset_backtrace.hpp>
27
#endif
28

29
#include <cstddef>
30
#include <cstdint>
31
#include <memory>
32
#include <string>
33
#include <utility>
34

35
namespace hpx::threads {
36

37
    execution_agent::execution_agent(
341,081✔
38
        coroutines::detail::coroutine_impl* coroutine) noexcept
39
      : self_(coroutine)
341,090✔
40
    {
682,162✔
41
    }
341,090✔
42

43
    std::string execution_agent::description() const
×
44
    {
45
        thread_id_type id = self_.get_thread_id();
×
46
        if (HPX_UNLIKELY(!id))
×
47
        {
48
            HPX_THROW_EXCEPTION(hpx::error::null_thread_id,
×
49
                "execution_agent::description",
50
                "null thread id encountered (is this executed on a "
51
                "HPX-thread?)");
52
        }
53

54
        return hpx::util::format(
×
55
            "{}: {}", id, get_thread_id_data(id)->get_description());
×
56
    }
×
57

58
    void execution_agent::yield(char const* desc)
74,095,967✔
59
    {
60
        do_yield(desc, hpx::threads::thread_schedule_state::pending);
74,097,763✔
61
    }
74,097,763✔
62

63
    void execution_agent::yield_k(std::size_t k, char const* desc)
4,809,375✔
64
    {
65
        if (k < 4)    //-V112
4,816,932✔
66
        {
67
        }
3,405,723✔
68
        else if (k < 16)
1,411,574✔
69
        {
70
            HPX_SMT_PAUSE;
1,089,329✔
71
        }
1,089,329✔
72
        else if (k < 32 || k & 1)    //-V112
322,256✔
73
        {
74
            do_yield(desc, hpx::threads::thread_schedule_state::pending_boost);
267,355✔
75
        }
267,355✔
76
        else
77
        {
78
            do_yield(desc, hpx::threads::thread_schedule_state::pending);
55,027✔
79
        }
80
    }
4,809,518✔
81

82
    void execution_agent::resume(char const* desc)
1,115,183✔
83
    {
84
        do_resume(desc, threads::thread_restart_state::signaled);
1,115,184✔
85
    }
1,115,184✔
86

87
    void execution_agent::abort(char const* desc)
×
88
    {
89
        do_resume(desc, threads::thread_restart_state::abort);
×
90
    }
×
91

92
    void execution_agent::suspend(char const* desc)
1,115,175✔
93
    {
94
        do_yield(desc, threads::thread_schedule_state::suspended);
1,115,175✔
95
    }
1,115,175✔
96

97
    void execution_agent::sleep_for(
×
98
        hpx::chrono::steady_duration const& sleep_duration, char const* desc)
99
    {
100
        sleep_until(sleep_duration.from_now(), desc);
×
101
    }
×
102

103
    void execution_agent::sleep_until(
62✔
104
        hpx::chrono::steady_time_point const& sleep_time, char const* desc)
105
    {
106
        // Just yield until time has passed by...
107
        auto now = std::chrono::steady_clock::now();
62✔
108

109
        // Note: we yield at least once to allow for other threads to
110
        // make progress in any case. We also use yield instead of yield_k
111
        // for the same reason.
112
        std::size_t k = 0;
62✔
113
        do
62✔
114
        {
115
            if (k < 32 || k & 1)
402,295✔
116
            {
117
                do_yield(
202,061✔
118
                    desc, hpx::threads::thread_schedule_state::pending_boost);
202,061✔
119
            }
202,061✔
120
            else
121
            {
122
                do_yield(desc, hpx::threads::thread_schedule_state::pending);
200,234✔
123
            }
124
            ++k;
402,295✔
125
            now = std::chrono::steady_clock::now();
402,295✔
126
        } while (now < sleep_time.value());
402,295✔
127
    }
62✔
128

129
#if defined(HPX_HAVE_VERIFY_LOCKS)
130
    struct on_exit_reset_held_lock_data
131
    {
132
        on_exit_reset_held_lock_data()
76,081,166✔
133
          : data_(hpx::util::get_held_locks_data())
76,099,824✔
134
        {
135
        }
76,099,824✔
136

137
        ~on_exit_reset_held_lock_data()
75,262,559✔
138
        {
139
            hpx::util::set_held_locks_data(HPX_MOVE(data_));
75,960,897✔
140
        }
75,960,897✔
141

142
        std::unique_ptr<hpx::util::held_locks_data> data_;
143
    };
144
#else
145
    struct on_exit_reset_held_lock_data
146
    {
147
    };
148
#endif
149

150
    hpx::threads::thread_restart_state execution_agent::do_yield(
75,922,548✔
151
        char const* desc, threads::thread_schedule_state state)
152
    {
153
        thread_id_ref_type id = self_.get_thread_id();    // keep alive
76,812,865✔
154
        if (HPX_UNLIKELY(!id))
76,812,865✔
155
        {
156
            HPX_THROW_EXCEPTION(hpx::error::null_thread_id,
×
157
                "execution_agent::do_yield",
158
                "null thread id encountered (is this executed on a "
159
                "HPX-thread?)");
160
        }
161

162
        // handle interruption, if needed
163
        thread_data* thrd_data = get_thread_id_data(id);
76,508,209✔
164
        HPX_ASSERT(thrd_data);
76,812,865✔
165
        thrd_data->interruption_point();
76,154,969✔
166

167
        thrd_data->set_last_worker_thread_num(
76,154,969✔
168
            hpx::get_local_worker_thread_num());
76,061,016✔
169

170
        threads::thread_restart_state statex =
76,607,200✔
171
            threads::thread_restart_state::unknown;
172

173
        {
174
#ifdef HPX_HAVE_THREAD_DESCRIPTION
175
            threads::detail::reset_lco_description desc(
176
                id.noref(), threads::thread_description(desc));
177
#endif
178
#ifdef HPX_HAVE_THREAD_BACKTRACE_ON_SUSPENSION
179
            threads::detail::reset_backtrace bt(id);
180
#endif
181
            [[maybe_unused]] on_exit_reset_held_lock_data held_locks;
76,607,200✔
182

183
            HPX_ASSERT(thrd_data->get_state().state() ==
76,607,200✔
184
                thread_schedule_state::active);
185
            HPX_ASSERT(state != thread_schedule_state::active);
76,318,335✔
186

187
            // actual yield operation
188
            statex = self_.yield(
76,302,177✔
189
                threads::thread_result_type(state, threads::invalid_thread_id));
76,263,461✔
190

191
            HPX_ASSERT(get_thread_id_data(id)->get_state().state() ==
75,490,062✔
192
                thread_schedule_state::active);
193
        }
75,291,774✔
194

195
        // handle interruption, if needed
196
        thrd_data->interruption_point();
76,206,044✔
197

198
        // handle interrupt and abort
199
        if (statex == threads::thread_restart_state::abort)
76,207,979✔
200
        {
201
            HPX_THROW_EXCEPTION(hpx::error::yield_aborted, desc,
×
202
                "thread({}) aborted (yield returned wait_abort)",
203
                description());
204
        }
205

206
        return statex;
76,139,778✔
207
    }
76,207,979✔
208

209
    void execution_agent::do_resume(
1,115,185✔
210
        char const* /* desc */, hpx::threads::thread_restart_state statex)
211
    {
212
        threads::detail::set_thread_state(self_.get_thread_id(),
2,230,370✔
213
            thread_schedule_state::pending, statex, thread_priority::normal,
1,115,186✔
214
            thread_schedule_hint{}, false);
1,115,186✔
215
    }
1,115,186✔
216
}    // namespace hpx::threads
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