• 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

83.67
/libs/core/execution_base/src/this_thread.cpp
1
//  Copyright (c) 2013-2019 Thomas Heller
2
//  Copyright (c) 2008 Peter Dimov
3
//  Copyright (c) 2018-2022 Hartmut Kaiser
4
//
5
//  SPDX-License-Identifier: BSL-1.0
6
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
7
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8

9
#include <hpx/config.hpp>
10
#include <hpx/assert.hpp>
11
#include <hpx/errors/throw_exception.hpp>
12
#include <hpx/execution_base/agent_base.hpp>
13
#include <hpx/execution_base/context_base.hpp>
14
#include <hpx/execution_base/this_thread.hpp>
15
#include <hpx/modules/format.hpp>
16
#include <hpx/timing/steady_clock.hpp>
17

18
#include <condition_variable>
19
#include <cstddef>
20
#include <cstdint>
21
#include <mutex>
22
#include <string>
23
#include <thread>
24
#include <utility>
25

26
#if defined(HPX_WINDOWS)
27
#include <windows.h>
28
#else
29
#ifndef _AIX
30
#include <sched.h>
31
#else
32
// AIX's sched.h defines ::var which sometimes conflicts with Lambda's var
33
extern "C" int sched_yield(void);
34
#endif
35
#include <time.h>
36
#endif
37

38
namespace hpx::execution_base {
39

40
    namespace {
41

42
        struct default_context : execution_base::context_base
16,850✔
43
        {
44
            resource_base const& resource() const noexcept override
×
45
            {
46
                return resource_;
×
47
            }
48
            resource_base resource_;
49
        };
50

51
        struct default_agent : execution_base::agent_base
8,565✔
52
        {
53
            default_agent();
54

55
            std::string description() const override
×
56
            {
57
                return hpx::util::format("{}", id_);
×
58
            }
59

60
            default_context const& context() const noexcept override
×
61
            {
62
                return context_;
×
63
            }
64

65
            void yield(char const* desc) override;
66
            void yield_k(std::size_t k, char const* desc) override;
67
            void suspend(char const* desc) override;
68
            void resume(char const* desc) override;
69
            void abort(char const* desc) override;
70
            void sleep_for(hpx::chrono::steady_duration const& sleep_duration,
71
                char const* desc) override;
72
            void sleep_until(hpx::chrono::steady_time_point const& sleep_time,
73
                char const* desc) override;
74

75
        private:
76
            bool running_;
77
            bool aborted_;
78
            std::thread::id id_;
79
            std::mutex mtx_;
80
            std::condition_variable suspend_cv_;
81
            std::condition_variable resume_cv_;
82

83
            default_context context_;
84
        };
85

86
        default_agent::default_agent()
8,078✔
87
          : running_(true)
8,088✔
88
          , aborted_(false)
8,088✔
89
          , id_(std::this_thread::get_id())
8,088✔
90
        {
16,156✔
91
        }
8,088✔
92

93
        void default_agent::yield(char const* /* desc */)
79,819✔
94
        {
95
#if defined(HPX_WINDOWS)
96
            Sleep(0);
97
#else
98
            sched_yield();
81,391✔
99
#endif
100
        }
81,391✔
101

102
        void default_agent::yield_k(std::size_t k, char const* /* desc */)
3,615,770✔
103
        {
104
            if (k < 4)    //-V112
3,616,228✔
105
            {
106
            }
172,325✔
107
            else if (k < 16)
3,444,135✔
108
            {
109
                HPX_SMT_PAUSE;
81,301✔
110
            }
81,301✔
111
            else if (k < 32 || k & 1)    //-V112
3,362,869✔
112
            {
113
#if defined(HPX_WINDOWS)
114
                Sleep(0);
115
#else
116
                sched_yield();
1,701,350✔
117
#endif
118
            }
1,701,350✔
119
            else
120
            {
121
#if defined(HPX_WINDOWS)
122
                Sleep(1);
123
#else
124
                // g++ -Wextra warns on {} or {0}
125
                struct timespec rqtp = {0, 0};
1,661,792✔
126

127
                // POSIX says that timespec has tv_sec and tv_nsec
128
                // But it doesn't guarantee order or placement
129

130
                rqtp.tv_sec = 0;
1,661,792✔
131
                rqtp.tv_nsec = 1000;
1,661,792✔
132

133
                nanosleep(&rqtp, nullptr);
1,661,792✔
134
#endif
135
            }
136
        }
3,616,194✔
137

138
        void default_agent::suspend(char const* /* desc */)
1✔
139
        {
140
            std::unique_lock<std::mutex> l(mtx_);
1✔
141
            HPX_ASSERT(running_);
1✔
142

143
            running_ = false;
1✔
144
            resume_cv_.notify_all();
1✔
145

146
            while (!running_)
2✔
147
            {
148
                suspend_cv_.wait(l);
1✔
149
            }
150

151
            if (aborted_)
1✔
152
            {
153
                HPX_THROW_EXCEPTION(hpx::error::yield_aborted, "suspend",
×
154
                    "std::thread({}) aborted (yield returned wait_abort)", id_);
155
            }
156
        }
1✔
157

158
        void default_agent::resume(char const* /* desc */)
1✔
159
        {
160
            {
161
                std::unique_lock<std::mutex> l(mtx_);
1✔
162
                while (running_)
2✔
163
                {
164
                    resume_cv_.wait(l);
1✔
165
                }
166
                running_ = true;
1✔
167
            }
1✔
168
            suspend_cv_.notify_one();
1✔
169
        }
1✔
170

171
        void default_agent::abort(char const* /* desc */)
×
172
        {
173
            {
174
                std::unique_lock<std::mutex> l(mtx_);
×
175
                while (running_)
×
176
                {
177
                    resume_cv_.wait(l);
×
178
                }
179
                running_ = true;
×
180
                aborted_ = true;
×
181
            }
×
182
            suspend_cv_.notify_one();
×
183
        }
×
184

185
        void default_agent::sleep_for(
1✔
186
            hpx::chrono::steady_duration const& sleep_duration,
187
            char const* /* desc */)
188
        {
189
            std::this_thread::sleep_for(sleep_duration.value());
1✔
190
        }
1✔
191

192
        void default_agent::sleep_until(
1✔
193
            hpx::chrono::steady_time_point const& sleep_time,
194
            char const* /* desc */)
195
        {
196
            std::this_thread::sleep_until(sleep_time.value());
1✔
197
        }
1✔
198
    }    // namespace
199

200
    namespace detail {
201

202
        agent_base& get_default_agent()
8,195✔
203
        {
204
            static thread_local default_agent agent;
8,195✔
205
            return agent;
8,577✔
206
        }
207
    }    // namespace detail
208

209
    namespace this_thread {
210

211
        namespace detail {
212

213
            struct agent_storage
214
            {
215
                agent_storage()
8,126✔
216
                  : impl_(&hpx::execution_base::detail::get_default_agent())
8,126✔
217
                {
218
                }
8,126✔
219

220
                agent_base* set(agent_base* context) noexcept
164,409,526✔
221
                {
222
                    std::swap(context, impl_);
164,223,360✔
223
                    return context;
164,223,360✔
224
                }
225

226
                agent_base* impl_;
227
            };
228

229
            agent_storage* get_agent_storage()
168,274,753✔
230
            {
231
                static thread_local agent_storage storage;
168,274,753✔
232
                return &storage;
168,284,552✔
233
            }
234
        }    // namespace detail
235

236
        reset_agent::reset_agent(
82,964,361✔
237
            detail::agent_storage* storage, agent_base& impl)
238
          : storage_(storage)
82,964,882✔
239
          , old_(storage_->set(&impl))
82,964,882✔
240
        {
241
        }
82,964,882✔
242

243
        reset_agent::reset_agent(agent_base& impl)
1✔
244
          : reset_agent(detail::get_agent_storage(), impl)
1✔
245
        {
246
        }
1✔
247

248
        reset_agent::~reset_agent()
83,564,880✔
249
        {
250
            storage_->set(old_);
83,565,505✔
251
        }
83,565,505✔
252

253
        hpx::execution_base::agent_ref agent()
168,299,310✔
254
        {
255
            return hpx::execution_base::agent_ref(
168,318,202✔
256
                detail::get_agent_storage()->impl_);
168,299,310✔
257
        }
258

259
        void yield(char const* desc)
74,486,182✔
260
        {
261
            agent().yield(desc);
74,489,206✔
262
        }
74,489,206✔
263

264
        void yield_k(std::size_t k, char const* desc)
8,420,834✔
265
        {
266
            agent().yield_k(k, desc);
8,420,945✔
267
        }
8,420,945✔
268

269
        void suspend(char const* desc)
12✔
270
        {
271
            agent().suspend(desc);
12✔
272
        }
12✔
273
    }    // namespace this_thread
274
}    // namespace hpx::execution_base
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