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

STEllAR-GROUP / hpx / #862

10 Jan 2023 05:30PM UTC coverage: 86.582% (-0.05%) from 86.634%
#862

push

StellarBot
Merge #6130

6130: Remove the mutex lock in the critical path of get_partitioner. r=hkaiser a=JiakunYan

Remove the mutex lock in the critical path of hpx::resource::detail::get_partitioner.

The protected variable `partitioner_ref` is only set once during initialization.

Co-authored-by: Jiakun Yan <jiakunyan1998@gmail.com>

6 of 6 new or added lines in 1 file covered. (100.0%)

174767 of 201851 relevant lines covered (86.58%)

2069816.07 hits per line

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

78.08
/libs/core/threading_base/src/thread_pool_base.cpp
1
//  Copyright (c) 2007-2022 Hartmut Kaiser
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/affinity/affinity_data.hpp>
8
#include <hpx/assert.hpp>
9
#include <hpx/functional/bind.hpp>
10
#include <hpx/hardware/timestamp.hpp>
11
#include <hpx/modules/errors.hpp>
12
#include <hpx/threading_base/callback_notifier.hpp>
13
#include <hpx/threading_base/scheduler_base.hpp>
14
#include <hpx/threading_base/scheduler_state.hpp>
15
#include <hpx/threading_base/thread_pool_base.hpp>
16
#include <hpx/timing/high_resolution_clock.hpp>
17
#include <hpx/topology/topology.hpp>
18

19
#include <cstddef>
20
#include <cstdint>
21
#include <memory>
22
#include <mutex>
23
#include <ostream>
24
#include <string>
25
#include <thread>
26

27
namespace hpx::threads {
28

29
    ///////////////////////////////////////////////////////////////////////////
30
    thread_pool_base::thread_pool_base(thread_pool_init_parameters const& init)
1,269✔
31
      : id_(init.index_, init.name_)
1,269✔
32
      , thread_offset_(init.thread_offset_)
1,269✔
33
      , affinity_data_(init.affinity_data_)
1,269✔
34
      , timestamp_scale_(1.0)
1,269✔
35
      , notifier_(init.notifier_)
1,269✔
36
    {
1,269✔
37
    }
1,269✔
38

39
    ///////////////////////////////////////////////////////////////////////////
40
    mask_type thread_pool_base::get_used_processing_units(
85✔
41
        std::size_t num_cores, bool full_cores) const
42
    {
43
        auto const& topo = create_topology();
85✔
44
        auto const sched = get_scheduler();
85✔
45

46
        mask_type used_processing_units = mask_type();
85✔
47
        threads::resize(used_processing_units,
85✔
48
            static_cast<std::size_t>(hardware_concurrency()));
85✔
49

50
        std::size_t max_cores = get_os_thread_count();
85✔
51
        for (std::size_t thread_num = 0;
2,572✔
52
             thread_num != max_cores && num_cores != 0; ++thread_num)
1,286✔
53
        {
54
            if (sched->get_state(thread_num).load() <= hpx::state::suspended)
1,201✔
55
            {
56
                if (!full_cores)
1,201✔
57
                {
58
                    used_processing_units |= affinity_data_.get_pu_mask(
2,386✔
59
                        topo, thread_num + get_thread_offset());
1,193✔
60
                }
1,193✔
61
                else
62
                {
63
                    used_processing_units |= topo.get_core_affinity_mask(
16✔
64
                        thread_num + get_thread_offset());
8✔
65
                }
66
                --num_cores;
1,201✔
67
            }
1,201✔
68
        }
1,201✔
69

70
        return used_processing_units;
85✔
71
    }
85✔
72

73
    mask_type thread_pool_base::get_used_processing_units(bool full_cores) const
81✔
74
    {
75
        return get_used_processing_units(get_os_thread_count(), full_cores);
81✔
76
    }
77

78
    mask_type thread_pool_base::get_used_processing_unit(
×
79
        std::size_t thread_num, bool full_cores) const
80
    {
81
        auto const& topo = create_topology();
×
82
        if (!full_cores)
×
83
        {
84
            return affinity_data_.get_pu_mask(
×
85
                topo, thread_num + get_thread_offset());
×
86
        }
87
        return topo.get_core_affinity_mask(thread_num + get_thread_offset());
×
88
    }
×
89

90
    hwloc_bitmap_ptr thread_pool_base::get_numa_domain_bitmap() const
40✔
91
    {
92
        auto const& topo = create_topology();
40✔
93
        mask_type used_processing_units = get_used_processing_units();
40✔
94
        return topo.cpuset_to_nodeset(used_processing_units);
40✔
95
    }
40✔
96

97
    std::size_t thread_pool_base::get_active_os_thread_count() const
×
98
    {
99
        std::size_t active_os_thread_count = 0;
×
100

101
        for (std::size_t thread_num = 0; thread_num < get_os_thread_count();
×
102
             ++thread_num)
×
103
        {
104
            if (get_scheduler()->get_state(thread_num).load() <=
×
105
                hpx::state::suspended)
106
            {
107
                ++active_os_thread_count;
×
108
            }
×
109
        }
×
110

111
        return active_os_thread_count;
×
112
    }
113

114
    ///////////////////////////////////////////////////////////////////////////
115
    void thread_pool_base::init_pool_time_scale()
1,269✔
116
    {
117
        // scale timestamps to nanoseconds
118
        std::uint64_t base_timestamp = util::hardware::timestamp();
1,269✔
119
        std::uint64_t base_time = hpx::chrono::high_resolution_clock::now();
1,269✔
120
        std::uint64_t curr_timestamp = util::hardware::timestamp();
1,269✔
121
        std::uint64_t curr_time = hpx::chrono::high_resolution_clock::now();
1,269✔
122

123
        while ((curr_time - base_time) <= 100000)
2,164,950✔
124
        {
125
            curr_timestamp = util::hardware::timestamp();
2,163,681✔
126
            curr_time = hpx::chrono::high_resolution_clock::now();
2,163,681✔
127
        }
128

129
        if (curr_timestamp - base_timestamp != 0)
1,269✔
130
        {
131
            timestamp_scale_ = double(curr_time - base_time) /
2,538✔
132
                double(curr_timestamp - base_timestamp);
1,269✔
133
        }
1,269✔
134
    }
1,269✔
135

136
    void thread_pool_base::init(
1,268✔
137
        std::size_t /* pool_threads */, std::size_t threads_offset)
138
    {
139
        thread_offset_ = threads_offset;
1,268✔
140
    }
1,268✔
141

142
    std::ostream& operator<<(
32,088,453✔
143
        std::ostream& os, thread_pool_base const& thread_pool)
144
    {
145
        auto id = thread_pool.get_pool_id();
32,084,727✔
146
        os << id.name() << "(" << static_cast<std::uint64_t>(id.index()) << ")";
32,088,453✔
147

148
        return os;
32,109,465✔
149
    }
32,109,101✔
150
}    // 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