VirtualBox

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

Last change on this file since 63399 was 63399, checked in by vboxsync, 8 years ago

iprt/cpuset.h: GCC is a bundle of joy

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