• 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_data_stackless.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/thread_data.hpp>
18
#include <hpx/threading_base/thread_init_data.hpp>
19

20
#include <cstddef>
21
#include <memory>
22
#include <utility>
23

24
#include <hpx/config/warnings_prefix.hpp>
25

26
///////////////////////////////////////////////////////////////////////////////
27
namespace hpx::threads {
28

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

55
        static util::internal_allocator<thread_data_stackless> thread_alloc_;
56

57
    public:
58
        HPX_FORCEINLINE stackless_coroutine_type::result_type call()
×
59
        {
60
            HPX_ASSERT(get_state().state() == thread_schedule_state::active);
61
            HPX_ASSERT(this == coroutine_.get_thread_id().get());
62

63
            return coroutine_(this->thread_data::set_state_ex(
64
                thread_restart_state::signaled));
×
65
        }
66

67
#if defined(HPX_DEBUG)
68
        thread_id_type get_thread_id() const override
69
        {
70
            HPX_ASSERT(this == coroutine_.get_thread_id().get());
71
            return this->thread_data::get_thread_id();
72
        }
73
#endif
74
#if defined(HPX_HAVE_THREAD_PHASE_INFORMATION)
75
        std::size_t get_thread_phase() const noexcept override
76
        {
77
            return coroutine_.get_thread_phase();
78
        }
79
#endif
80

81
        std::size_t get_thread_data() const override
×
82
        {
83
            return coroutine_.get_thread_data();
×
84
        }
85

86
        std::size_t set_thread_data(std::size_t data) override
×
87
        {
88
            return coroutine_.set_thread_data(data);
×
89
        }
90

91
#if defined(HPX_HAVE_LIBCDS)
92
        std::size_t get_libcds_data() const override
93
        {
94
            return coroutine_.get_libcds_data();
95
        }
96

97
        std::size_t set_libcds_data(std::size_t data) override
98
        {
99
            return coroutine_.set_libcds_data(data);
100
        }
101

102
        std::size_t get_libcds_hazard_pointer_data() const override
103
        {
104
            return coroutine_.get_libcds_hazard_pointer_data();
105
        }
106

107
        std::size_t set_libcds_hazard_pointer_data(std::size_t data) override
108
        {
109
            return coroutine_.set_libcds_hazard_pointer_data(data);
110
        }
111

112
        std::size_t get_libcds_dynamic_hazard_pointer_data() const override
113
        {
114
            return coroutine_.get_libcds_dynamic_hazard_pointer_data();
115
        }
116

117
        std::size_t set_libcds_dynamic_hazard_pointer_data(
118
            std::size_t data) override
119
        {
120
            return coroutine_.set_libcds_dynamic_hazard_pointer_data(data);
121
        }
122
#endif
123

124
        void init() override {}
×
125

126
        void rebind(thread_init_data& init_data) override
×
127
        {
128
            this->thread_data::rebind_base(init_data);
×
129

130
            coroutine_.rebind(HPX_MOVE(init_data.func), thread_id_type(this));
131

132
            HPX_ASSERT(coroutine_.is_ready());
133
        }
×
134

135
        thread_data_stackless(thread_init_data& init_data, void* queue,
×
136
            std::ptrdiff_t stacksize, thread_id_addref addref)
137
          : thread_data(init_data, queue, stacksize, true, addref)
×
138
          , coroutine_(HPX_MOVE(init_data.func), thread_id_type(this_()))
×
139
        {
140
            HPX_ASSERT(coroutine_.is_ready());
141
        }
×
142

143
        thread_data_stackless(thread_data_stackless const&) = delete;
144
        thread_data_stackless(thread_data_stackless&&) = delete;
145
        thread_data_stackless& operator=(thread_data_stackless const&) = delete;
146
        thread_data_stackless& operator=(thread_data_stackless&&) = delete;
147

148
        ~thread_data_stackless();
149

150
        inline static thread_data* create(thread_init_data& data, void* queue,
151
            std::ptrdiff_t stacksize,
152
            thread_id_addref addref = thread_id_addref::yes);
153

154
        void destroy() noexcept override
×
155
        {
156
            std::destroy_at(this);
157
            thread_alloc_.deallocate(this, 1);
158
        }
×
159

160
    private:
161
        stackless_coroutine_type coroutine_;
162
    };
163

164
    ////////////////////////////////////////////////////////////////////////////
165
    inline thread_data* thread_data_stackless::create(thread_init_data& data,
×
166
        void* queue, std::ptrdiff_t stacksize, thread_id_addref addref)
167
    {
168
        thread_data_stackless* p = thread_alloc_.allocate(1);
169
        hpx::construct_at(p, data, queue, stacksize, addref);
170
        return p;
×
171
    }
172
}    // namespace hpx::threads
173

174
#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