VirtualBox

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

Last change on this file since 76553 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

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