NUMA++ 0.12.0
Loading...
Searching...
No Matches
bitmask.hpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup numapp_numa
4 * @brief Contains declarations for numapp::Bitmask
5 * @copyright
6 * SPDX-FileCopyrightText: 2020-2024 European Southern Observatory (ESO)
7 *
8 * SPDX-License-Identifier: LGPL-3.0-only
9 */
10#ifndef NUMAPP_BITMASK_HPP_
11#define NUMAPP_BITMASK_HPP_
12#include <iosfwd>
13#include <memory>
14#include <type_traits>
15
16#include <numa.h>
17
18namespace numapp {
19
20/**
21 * Lowlevel bitmask type.
22 *
23 * @ingroup numapp_numa
24 */
25using NumaBitmaskPtr = std::unique_ptr<struct bitmask, void (*)(struct bitmask*)>;
26
27template <class Class>
28class Bitmask;
29
30/**
31 * Invoke function for each bit in mask that matches @a value.
32 *
33 * @param bitmask Bitmask to iterate over.
34 * @param f function callable as `f(position)` where @a position is the `unsigned int` bit position.
35 * @param value to test bit for (true == bit is set, false == bit is unset).
36 *
37 * Example that starts a pinned thread for each bit in a CPU mask:
38 *
39 * @include forEachExample.cpp
40 *
41 * @par Header file
42 * @c <numapp/bitmask.hpp>
43 *
44 * @relatesalso Bitmask
45 * @sa Cpumask Nodemask
46 * @ingroup numapp_numa
47 */
48template <class Class, class F>
49void ForEach(Bitmask<Class> const& bitmask, F&& f, bool value = true);
50
51/**
52 * Generic bitmask
53 *
54 * @ingroup numapp_numa
55 */
56template <class Class>
57class Bitmask {
58public:
59 Bitmask() : m_bitmask(Class::Alloc()) {
60 }
61
62 Bitmask(Bitmask&& rhs) noexcept = default;
63 Bitmask(Bitmask const& rhs) : m_bitmask(Class::Alloc()) {
64 *this = rhs;
65 }
66 Bitmask& operator=(Bitmask&&) noexcept = default;
67 /**
68 * Copy from @a rhs to this.
69 *
70 * @param rhs bitmask to copy from.
71 * @returns reference to this.
72 */
73 Bitmask& operator=(Bitmask const& rhs) noexcept {
74 // Copy from rhs to this
75 copy_bitmask_to_bitmask(rhs.m_bitmask.get(), m_bitmask.get());
76 return *this;
77 }
78
79 /**
80 * @name Comparison
81 */
82 /// @{
83 /**
84 * @returns true if bitmask are equal.
85 */
86 [[nodiscard]] bool operator==(Bitmask const& rhs) const noexcept {
87 return numa_bitmask_equal(m_bitmask.get(), rhs.m_bitmask.get()) == 1;
88 }
89 /**
90 * @returns true if bitmask are equal.
91 */
92 [[nodiscard]] bool operator!=(Bitmask const& rhs) const noexcept {
93 return !(this == rhs);
94 }
95 /// @}
96
97 /**
98 * @name Accessors
99 */
100 /// @{
101 /**
102 * Access native bitmask type.
103 *
104 * @return pointer to libnuma bitmask type.
105 */
106 struct bitmask const* GetNative() const noexcept {
107 return m_bitmask.get();
108 }
109 /**
110 * Access native bitmask type.
111 *
112 * @return pointer to libnuma bitmask type.
113 */
114 struct bitmask* GetNative() noexcept {
115 return m_bitmask.get();
116 }
117
118 /**
119 * Query number of bits in mask.
120 *
121 * @return number of bits in mask.
122 */
123 [[nodiscard]] std::size_t GetSize() const noexcept {
124 return m_bitmask->size;
125 }
126
127 /**
128 * Test if bit in specified position is set.
129 *
130 * @param position Zero-indexed bit position to test.
131 * @return value of bit in requested @a position or false if @a position is outside valid range.
132 */
133 [[nodiscard]] bool Test(unsigned int position) const noexcept {
134 return numa_bitmask_isbitset(GetNative(), position);
135 }
136
137 /// @}
138 /**
139 * @name Modifiers
140 *
141 * If specified bit position is outside valid range no operations is performed. This behaviour
142 * is inherited from libnuma.
143 */
144 /// @{
145 /**
146 * Set bit in @a position to specified value.
147 *
148 * @note If position is outside valid range nothing is done.
149 *
150 * @param position Zero-indexed bit position to modify.
151 * @param value Bit value to set (default true).
152 * @return Reference to this object (for call chaining).
153 */
154 Bitmask& Set(unsigned int position, bool value = true) noexcept {
155 if (value) {
156 numa_bitmask_setbit(GetNative(), position);
157 } else {
158 numa_bitmask_clearbit(GetNative(), position);
159 }
160 return *this;
161 }
162
163 /**
164 * Sets bit in specified position to false.
165 *
166 * @note If position is outside valid range nothing is done.
167 *
168 * @param position Zero-indexed bit position to modify.
169 * @return Reference to this object (for call chaining).
170 */
171 Bitmask& Reset(unsigned int position) noexcept {
172 numa_bitmask_clearbit(GetNative(), position);
173 return *this;
174 }
175 /// @}
176protected:
177 /**
178 * Construction from native bitmask type can be error prone in that
179 * the mask wasn't allocated using the correction function. To prevent mistakes this is made
180 * protected so it can only be used by the concrete implementations.
181 */
182 Bitmask(NumaBitmaskPtr&& bitmask) : m_bitmask(std::move(bitmask)) {
183 }
184
185private:
186 NumaBitmaskPtr m_bitmask;
187};
188
189/**
190 * Formats @a mask and inserts it to @a os.
191 *
192 * @param os output stream to insert into.
193 * @param mask Bitmask to format.
194 * @param min_bits Minimum number of bits to format.
195 * @returns @a os
196 *
197 * @relatesalso Bitmask
198 * @ingroup numapp_numa
199 */
200template <class Class>
201std::ostream& FormatBitmask(std::ostream& os, Bitmask<Class> const& mask, int min_bits);
202
203/**
204 * Formats @a mask and inserts it to @a os.
205 *
206 * @param os output stream to insert into.
207 * @param mask Bitmask to format.
208 * @param min_bits Minimum number of bits to format.
209 * @returns @a os
210 *
211 * @relatesalso Bitmask
212 * @ingroup numapp_numa
213 */
214std::ostream& FormatBitmask(std::ostream& os, bitmask const* mask, int min_bits);
215
216template <class Class>
217std::ostream& FormatBitmask(std::ostream& os, Bitmask<Class> const& mask, int min_bits) {
218 return FormatBitmask(os, mask.GetNative(), min_bits);
219}
220
221template <class Class, class F>
222void ForEach(Bitmask<Class> const& bits, F&& f, bool value) {
223 static_assert(std::is_invocable_v<F, unsigned int>,
224 "Function must be invocable with signature `f(unsigned int)`");
225 auto const num_bits = bits.GetSize();
226 for (unsigned int position = 0u; position < num_bits; ++position) {
227 if (bits.Test(position) == value) {
228 f(position);
229 }
230 }
231}
232
233} // namespace numapp
234
235#endif // #ifndef NUMAPP_BITMASK_HPP_
Generic bitmask.
Definition bitmask.hpp:57
std::size_t GetSize() const noexcept
Query number of bits in mask.
Definition bitmask.hpp:123
bool operator==(Bitmask const &rhs) const noexcept
Definition bitmask.hpp:86
Bitmask & Set(unsigned int position, bool value=true) noexcept
Set bit in position to specified value.
Definition bitmask.hpp:154
struct bitmask * GetNative() noexcept
Access native bitmask type.
Definition bitmask.hpp:114
Bitmask & operator=(Bitmask const &rhs) noexcept
Copy from rhs to this.
Definition bitmask.hpp:73
Bitmask(NumaBitmaskPtr &&bitmask)
Construction from native bitmask type can be error prone in that the mask wasn't allocated using the ...
Definition bitmask.hpp:182
Bitmask & Reset(unsigned int position) noexcept
Sets bit in specified position to false.
Definition bitmask.hpp:171
struct bitmask const * GetNative() const noexcept
Access native bitmask type.
Definition bitmask.hpp:106
bool Test(unsigned int position) const noexcept
Test if bit in specified position is set.
Definition bitmask.hpp:133
bool operator!=(Bitmask const &rhs) const noexcept
Definition bitmask.hpp:92
std::unique_ptr< struct bitmask, void(*)(struct bitmask *)> NumaBitmaskPtr
Lowlevel bitmask type.
Definition bitmask.hpp:25
void ForEach(Bitmask< Class > const &bitmask, F &&f, bool value=true)
Invoke function for each bit in mask that matches value.
Definition bitmask.hpp:222
void ForEach(Bitmask< Class > const &bitmask, F &&f, bool value=true)
Invoke function for each bit in mask that matches value.
Definition bitmask.hpp:222
std::ostream & FormatBitmask(std::ostream &os, Bitmask< Class > const &mask, int min_bits)
Formats mask and inserts it to os.
Definition bitmask.hpp:217
std::ostream & FormatBitmask(std::ostream &os, bitmask const *mask, int min_bits)
Formats mask and inserts it to os.
Definition bitmask.cpp:14