VirtualBox

source: vbox/trunk/include/iprt/cpuset.h@ 99026

Last change on this file since 99026 was 98103, checked in by vboxsync, 2 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 8.0 KB
Line 
1/** @file
2 * IPRT - CPU Set.
3 */
4
5/*
6 * Copyright (C) 2008-2023 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef IPRT_INCLUDED_cpuset_h
37#define IPRT_INCLUDED_cpuset_h
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <iprt/types.h>
43#include <iprt/mp.h> /* RTMpCpuIdToSetIndex */
44#include <iprt/asm.h>
45
46
47RT_C_DECLS_BEGIN
48
49/** @defgroup grp_rt_cpuset RTCpuSet - CPU Set
50 * @ingroup grp_rt
51 * @{
52 */
53
54
55/**
56 * Clear all CPUs.
57 *
58 * @returns pSet.
59 * @param pSet Pointer to the set.
60 */
61DECLINLINE(PRTCPUSET) RTCpuSetEmpty(PRTCPUSET pSet)
62{
63 size_t i;
64 for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
65 pSet->bmSet[i] = 0;
66 return pSet;
67}
68
69
70/**
71 * Set all CPUs.
72 *
73 * @returns pSet.
74 * @param pSet Pointer to the set.
75 */
76DECLINLINE(PRTCPUSET) RTCpuSetFill(PRTCPUSET pSet)
77{
78 size_t i;
79 for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
80 pSet->bmSet[i] = UINT64_MAX;
81 return pSet;
82}
83
84
85/**
86 * Copies one set to another.
87 *
88 * @param pDst Pointer to the destination set.
89 * @param pSrc Pointer to the source set.
90 */
91DECLINLINE(void) RTCpuSetCopy(PRTCPUSET pDst, PRTCPUSET pSrc)
92{
93 size_t i;
94 for (i = 0; i < RT_ELEMENTS(pDst->bmSet); i++)
95 pDst->bmSet[i] = pSrc->bmSet[i];
96}
97
98
99/**
100 * ANDs the given CPU set with another.
101 *
102 * @returns pSet.
103 * @param pSet Pointer to the set.
104 * @param pAndMaskSet Pointer to the AND-mask set.
105 */
106DECLINLINE(PRTCPUSET) RTCpuSetAnd(PRTCPUSET pSet, PRTCPUSET pAndMaskSet)
107{
108 size_t i;
109 for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
110 ASMAtomicAndU64((volatile uint64_t *)&pSet->bmSet[i], pAndMaskSet->bmSet[i]);
111 return pSet;
112}
113
114
115/**
116 * Adds a CPU given by its identifier to the set.
117 *
118 * @returns 0 on success, -1 if idCpu isn't valid.
119 * @param pSet Pointer to the set.
120 * @param idCpu The identifier of the CPU to add.
121 * @remarks The modification is atomic.
122 */
123DECLINLINE(int) RTCpuSetAdd(PRTCPUSET pSet, RTCPUID idCpu)
124{
125 int iCpu = RTMpCpuIdToSetIndex(idCpu);
126 if (RT_LIKELY(iCpu >= 0))
127 {
128 ASMAtomicBitSet(pSet, iCpu);
129 return 0;
130 }
131 return -1;
132}
133
134
135/**
136 * Adds a CPU given by its identifier to the set.
137 *
138 * @returns 0 on success, -1 if iCpu isn't valid.
139 * @param pSet Pointer to the set.
140 * @param iCpu The index of the CPU to add.
141 * @remarks The modification is atomic.
142 */
143DECLINLINE(int) RTCpuSetAddByIndex(PRTCPUSET pSet, int iCpu)
144{
145 if (RT_LIKELY((unsigned)iCpu < RTCPUSET_MAX_CPUS))
146 {
147 ASMAtomicBitSet(pSet, iCpu);
148 return 0;
149 }
150 return -1;
151}
152
153
154/**
155 * Removes a CPU given by its identifier from the set.
156 *
157 * @returns 0 on success, -1 if idCpu isn't valid.
158 * @param pSet Pointer to the set.
159 * @param idCpu The identifier of the CPU to delete.
160 * @remarks The modification is atomic.
161 */
162DECLINLINE(int) RTCpuSetDel(PRTCPUSET pSet, RTCPUID idCpu)
163{
164 int iCpu = RTMpCpuIdToSetIndex(idCpu);
165 if (RT_LIKELY(iCpu >= 0))
166 {
167 ASMAtomicBitClear(pSet, iCpu);
168 return 0;
169 }
170 return -1;
171}
172
173
174/**
175 * Removes a CPU given by its index from the set.
176 *
177 * @returns 0 on success, -1 if iCpu isn't valid.
178 * @param pSet Pointer to the set.
179 * @param iCpu The index of the CPU to delete.
180 * @remarks The modification is atomic.
181 */
182DECLINLINE(int) RTCpuSetDelByIndex(PRTCPUSET pSet, int iCpu)
183{
184 if (RT_LIKELY((unsigned)iCpu < RTCPUSET_MAX_CPUS))
185 {
186 ASMAtomicBitClear(pSet, iCpu);
187 return 0;
188 }
189 return -1;
190}
191
192
193/**
194 * Checks if a CPU given by its identifier is a member of the set.
195 *
196 * @returns true / false accordingly.
197 * @param pSet Pointer to the set.
198 * @param idCpu The identifier of the CPU to look for.
199 * @remarks The test is atomic.
200 */
201DECLINLINE(bool) RTCpuSetIsMember(PCRTCPUSET pSet, RTCPUID idCpu)
202{
203 int iCpu = RTMpCpuIdToSetIndex(idCpu);
204 if (RT_LIKELY(iCpu >= 0))
205 return ASMBitTest((volatile void *)pSet, iCpu);
206 return false;
207}
208
209
210/**
211 * Checks if a CPU given by its index is a member of the set.
212 *
213 * @returns true / false accordingly.
214 * @param pSet Pointer to the set.
215 * @param iCpu The index of the CPU in the set.
216 * @remarks The test is atomic.
217 */
218DECLINLINE(bool) RTCpuSetIsMemberByIndex(PCRTCPUSET pSet, int iCpu)
219{
220 if (RT_LIKELY((unsigned)iCpu < RTCPUSET_MAX_CPUS))
221 return ASMBitTest((volatile void *)pSet, iCpu);
222 return false;
223}
224
225
226/**
227 * Checks if the two sets match or not.
228 *
229 * @returns true / false accordingly.
230 * @param pSet1 The first set.
231 * @param pSet2 The second set.
232 */
233DECLINLINE(bool) RTCpuSetIsEqual(PCRTCPUSET pSet1, PCRTCPUSET pSet2)
234{
235 size_t i;
236 for (i = 0; i < RT_ELEMENTS(pSet1->bmSet); i++)
237 if (pSet1->bmSet[i] != pSet2->bmSet[i])
238 return false;
239 return true;
240}
241
242
243/**
244 * Checks if the CPU set is empty or not.
245 *
246 * @returns true / false accordingly.
247 * @param pSet Pointer to the set.
248 */
249DECLINLINE(bool) RTCpuSetIsEmpty(PRTCPUSET pSet)
250{
251 size_t i;
252 for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
253 if (pSet->bmSet[i])
254 return false;
255 return true;
256}
257
258
259/**
260 * Converts the CPU set to a 64-bit mask.
261 *
262 * @returns The mask.
263 * @param pSet Pointer to the set.
264 * @remarks Use with extreme care as it may lose information!
265 */
266DECLINLINE(uint64_t) RTCpuSetToU64(PCRTCPUSET pSet)
267{
268 return pSet->bmSet[0];
269}
270
271
272/**
273 * Initializes the CPU set from a 64-bit mask.
274 *
275 * @param pSet Pointer to the set.
276 * @param fMask The mask.
277 */
278DECLINLINE(PRTCPUSET) RTCpuSetFromU64(PRTCPUSET pSet, uint64_t fMask)
279{
280 size_t i;
281
282 pSet->bmSet[0] = fMask;
283 for (i = 1; i < RT_ELEMENTS(pSet->bmSet); i++)
284 pSet->bmSet[i] = 0;
285
286 return pSet;
287}
288
289
290/**
291 * Count the CPUs in the set.
292 *
293 * @returns CPU count.
294 * @param pSet Pointer to the set.
295 */
296DECLINLINE(int) RTCpuSetCount(PCRTCPUSET pSet)
297{
298 int cCpus = 0;
299 size_t i;
300
301 for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
302 {
303 uint64_t u64 = pSet->bmSet[i];
304 if (u64 != 0)
305 {
306 unsigned iCpu = 64;
307 while (iCpu-- > 0)
308 {
309 if (u64 & 1)
310 cCpus++;
311 u64 >>= 1;
312 }
313 }
314 }
315 return cCpus;
316}
317
318
319/**
320 * Get the highest set index.
321 *
322 * @returns The higest set index, -1 if all bits are clear.
323 * @param pSet Pointer to the set.
324 */
325DECLINLINE(int) RTCpuLastIndex(PCRTCPUSET pSet)
326{
327 size_t i = RT_ELEMENTS(pSet->bmSet);
328 while (i-- > 0)
329 {
330 uint64_t u64 = pSet->bmSet[i];
331 if (u64)
332 {
333 /* There are more efficient ways to do this in asm.h... */
334 unsigned iBit;
335 for (iBit = 63; iBit > 0; iBit--)
336 {
337 if (u64 & RT_BIT_64(63))
338 break;
339 u64 <<= 1;
340 }
341 return (int)i * 64 + (int)iBit;
342 }
343 }
344 return 0;
345}
346
347
348/** @} */
349
350RT_C_DECLS_END
351
352#endif /* !IPRT_INCLUDED_cpuset_h */
353
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette