• 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

64.0
/libs/core/threading_base/include/hpx/threading_base/thread_data_stackful.hpp
1
//  Copyright (c) 2007-2025 Hartmut Kaiser
2
//  Copyright (c)      2011 Bryce Lelbach
3
//  Copyright (c) 2008-2009 Chirag Dekate, Anshul Tandon
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
#pragma once
10

11
#include <hpx/config.hpp>
12
#include <hpx/assert.hpp>
13
#include <hpx/modules/allocator_support.hpp>
14
#include <hpx/modules/coroutines.hpp>
15
#include <hpx/modules/errors.hpp>
16
#include <hpx/modules/type_support.hpp>
17
#include <hpx/threading_base/execution_agent.hpp>
18
#include <hpx/threading_base/thread_data.hpp>
19
#include <hpx/threading_base/thread_init_data.hpp>
20

21
#include <cstddef>
22
#include <cstdint>
23
#include <memory>
24
#include <utility>
25

26
#include <hpx/config/warnings_prefix.hpp>
27

28
///////////////////////////////////////////////////////////////////////////////
29
namespace hpx::threads {
30

31
    ///////////////////////////////////////////////////////////////////////////
32
    /// A \a thread is the representation of a HPX thread. It's a first class
33
    /// object in HPX. In our implementation this is a user level thread running
34
    /// on top of one of the OS threads spawned by the \a thread-manager.
35
    ///
36
    /// A \a thread encapsulates:
37
    ///  - A thread status word (see the functions \a thread#get_state and
38
    ///    \a thread#set_state)
39
    ///  - A function to execute (the thread function)
40
    ///  - A frame (in this implementation this is a block of memory used as the
41
    ///    threads stack)
42
    ///  - A block of registers (not implemented yet)
43
    ///
44
    /// Generally, \a threads are not created or executed directly. All
45
    /// functionality related to the management of \a threads is implemented by
46
    /// the thread-manager.
47
    HPX_CXX_EXPORT class HPX_CORE_EXPORT thread_data_stackful
48
      : public thread_data
49
    {
50
    private:
51
        // Avoid warning about using 'this' in initializer list
52
        constexpr thread_data* this_() noexcept
53
        {
54
            return this;
55
        }
56

57
        static util::internal_allocator<thread_data_stackful> thread_alloc_;
58

59
    public:
60
        HPX_FORCEINLINE coroutine_type::result_type call(
61
            hpx::execution_base::this_thread::detail::agent_storage*
62
                agent_storage)
63
        {
64
            HPX_ASSERT(get_state().state() == thread_schedule_state::active);
65
            HPX_ASSERT(this == coroutine_.get_thread_id().get());
66

67
            hpx::execution_base::this_thread::reset_agent ctx(
1,831,158✔
68
                agent_storage, agent_);
1,831,158✔
69
            return coroutine_(set_state_ex(thread_restart_state::signaled));
1,831,158✔
70
        }
71

72
        HPX_FORCEINLINE coroutine_type::result_type invoke_directly()
73
        {
74
            HPX_ASSERT(get_state().state() == thread_schedule_state::active);
75
            HPX_ASSERT(this == coroutine_.get_thread_id().get());
76

77
            coroutine_type::result_type result = coroutine_.invoke_directly(
×
78
                set_state_ex(thread_restart_state::signaled));
79

×
80
            if (result.first == thread_schedule_state::terminated &&
81
                runs_as_child(std::memory_order_relaxed))
82
            {
×
83
                result.first = thread_schedule_state::deleted;
84
            }
85

86
            return result;
87
        }
88

89
#if defined(HPX_DEBUG)
90
        thread_id_type get_thread_id() const override
91
        {
92
            HPX_ASSERT(this == coroutine_.get_thread_id().get());
93
            return this->thread_data::get_thread_id();
94
        }
95
#endif
96
#if defined(HPX_HAVE_THREAD_PHASE_INFORMATION)
97
        std::size_t get_thread_phase() const noexcept override
98
        {
99
            return coroutine_.get_thread_phase();
100
        }
101
#endif
102

×
103
        std::size_t get_thread_data() const override
104
        {
×
105
            return coroutine_.get_thread_data();
106
        }
107

×
108
        std::size_t set_thread_data(std::size_t data) override
109
        {
×
110
            return coroutine_.set_thread_data(data);
111
        }
112

113
#if defined(HPX_HAVE_LIBCDS)
114
        std::size_t get_libcds_data() const override
115
        {
116
            return coroutine_.get_libcds_data();
117
        }
118

119
        std::size_t set_libcds_data(std::size_t data) override
120
        {
121
            return coroutine_.set_libcds_data(data);
122
        }
123

124
        std::size_t get_libcds_hazard_pointer_data() const override
125
        {
126
            return coroutine_.get_libcds_hazard_pointer_data();
127
        }
128

129
        std::size_t set_libcds_hazard_pointer_data(std::size_t data) override
130
        {
131
            return coroutine_.set_libcds_hazard_pointer_data(data);
132
        }
133

134
        std::size_t get_libcds_dynamic_hazard_pointer_data() const override
135
        {
136
            return coroutine_.get_libcds_dynamic_hazard_pointer_data();
137
        }
138

139
        std::size_t set_libcds_dynamic_hazard_pointer_data(
140
            std::size_t data) override
141
        {
142
            return coroutine_.set_libcds_dynamic_hazard_pointer_data(data);
143
        }
144
#endif
145

×
146
        void init() override
147
        {
148
            coroutine_.init();
×
149
        }
150

40,055✔
151
        void rebind(thread_init_data& init_data) override
152
        {
40,055✔
153
            this->thread_data::rebind_base(init_data);
154

40,055✔
155
            coroutine_.rebind(HPX_MOVE(init_data.func), thread_id_type(this));
156

157
            HPX_ASSERT(coroutine_.is_ready());
40,055✔
158
        }
159

8,397✔
160
        thread_data_stackful(thread_init_data& init_data, void* queue,
161
            std::ptrdiff_t stacksize, thread_id_addref addref)
8,397✔
162
          : thread_data(init_data, queue, stacksize, false, addref)
163
          , coroutine_(
8,397✔
164
                HPX_MOVE(init_data.func), thread_id_type(this_()), stacksize)
8,397✔
165
          , agent_(coroutine_.impl())
166
        {
167
            HPX_ASSERT(coroutine_.is_ready());
8,397✔
168
        }
169

170
        thread_data_stackful(thread_data_stackful const&) = delete;
171
        thread_data_stackful(thread_data_stackful&&) = delete;
172
        thread_data_stackful& operator=(thread_data_stackful const&) = delete;
173
        thread_data_stackful& operator=(thread_data_stackful&&) = delete;
174

175
        ~thread_data_stackful();
176

177
        static inline thread_data* create(thread_init_data& init_data,
178
            void* queue, std::ptrdiff_t stacksize,
179
            thread_id_addref addref = thread_id_addref::yes);
180

8,397✔
181
        void destroy() noexcept override
182
        {
183
            std::destroy_at(this);
184
            thread_alloc_.deallocate(this, 1);
8,397✔
185
        }
186

187
    private:
188
        coroutine_type coroutine_;
189
        execution_agent agent_;
190
    };
191

192
    ////////////////////////////////////////////////////////////////////////////
8,397✔
193
    inline thread_data* thread_data_stackful::create(thread_init_data& data,
194
        void* queue, std::ptrdiff_t stacksize, thread_id_addref addref)
195
    {
196
        thread_data_stackful* p = thread_alloc_.allocate(1);
197
        hpx::construct_at(p, data, queue, stacksize, addref);
8,397✔
198
        return p;
199
    }
200
}    // namespace hpx::threads
201

202
#include <hpx/config/warnings_suffix.hpp>
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