VirtualBox

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

Last change on this file since 55319 was 53327, checked in by vboxsync, 10 years ago

iprt/cpuset: RTCpuSetCopy.

  • 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-2011 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 unsigned 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 unsigned 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 unsigned 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 unsigned 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_UNLIKELY(iCpu < 0))
114 return -1;
115 ASMAtomicBitSet(pSet, iCpu);
116 return 0;
117}
118
119
120/**
121 * Adds a CPU given by its identifier to the set.
122 *
123 * @returns 0 on success, -1 if iCpu isn't valid.
124 * @param pSet Pointer to the set.
125 * @param iCpu The index of the CPU to add.
126 * @remarks The modification is atomic.
127 */
128DECLINLINE(int) RTCpuSetAddByIndex(PRTCPUSET pSet, int iCpu)
129{
130 if (RT_UNLIKELY((unsigned)iCpu >= RTCPUSET_MAX_CPUS))
131 return -1;
132 ASMAtomicBitSet(pSet, iCpu);
133 return 0;
134}
135
136
137/**
138 * Removes a CPU given by its identifier from the set.
139 *
140 * @returns 0 on success, -1 if idCpu isn't valid.
141 * @param pSet Pointer to the set.
142 * @param idCpu The identifier of the CPU to delete.
143 * @remarks The modification is atomic.
144 */
145DECLINLINE(int) RTCpuSetDel(PRTCPUSET pSet, RTCPUID idCpu)
146{
147 int iCpu = RTMpCpuIdToSetIndex(idCpu);
148 if (RT_UNLIKELY(iCpu < 0))
149 return -1;
150 ASMAtomicBitClear(pSet, iCpu);
151 return 0;
152}
153
154
155/**
156 * Removes a CPU given by its index from the set.
157 *
158 * @returns 0 on success, -1 if iCpu isn't valid.
159 * @param pSet Pointer to the set.
160 * @param iCpu The index of the CPU to delete.
161 * @remarks The modification is atomic.
162 */
163DECLINLINE(int) RTCpuSetDelByIndex(PRTCPUSET pSet, int iCpu)
164{
165 if (RT_UNLIKELY((unsigned)iCpu >= RTCPUSET_MAX_CPUS))
166 return -1;
167 ASMAtomicBitClear(pSet, iCpu);
168 return 0;
169}
170
171
172/**
173 * Checks if a CPU given by its identifier is a member of the set.
174 *
175 * @returns true / false accordingly.
176 * @param pSet Pointer to the set.
177 * @param idCpu The identifier of the CPU to look for.
178 * @remarks The test is atomic.
179 */
180DECLINLINE(bool) RTCpuSetIsMember(PCRTCPUSET pSet, RTCPUID idCpu)
181{
182 int iCpu = RTMpCpuIdToSetIndex(idCpu);
183 if (RT_UNLIKELY(iCpu < 0))
184 return false;
185 return ASMBitTest((volatile void *)pSet, iCpu);
186}
187
188
189/**
190 * Checks if a CPU given by its index is a member of the set.
191 *
192 * @returns true / false accordingly.
193 * @param pSet Pointer to the set.
194 * @param iCpu The index of the CPU in the set.
195 * @remarks The test is atomic.
196 */
197DECLINLINE(bool) RTCpuSetIsMemberByIndex(PCRTCPUSET pSet, int iCpu)
198{
199 if (RT_UNLIKELY((unsigned)iCpu >= RTCPUSET_MAX_CPUS))
200 return false;
201 return ASMBitTest((volatile void *)pSet, iCpu);
202}
203
204
205/**
206 * Checks if the two sets match or not.
207 *
208 * @returns true / false accordingly.
209 * @param pSet1 The first set.
210 * @param pSet2 The second set.
211 */
212DECLINLINE(bool) RTCpuSetIsEqual(PCRTCPUSET pSet1, PCRTCPUSET pSet2)
213{
214 unsigned i;
215 for (i = 0; i < RT_ELEMENTS(pSet1->bmSet); i++)
216 if (pSet1->bmSet[i] != pSet2->bmSet[i])
217 return false;
218 return true;
219}
220
221
222/**
223 * Checks if the CPU set is empty or not.
224 *
225 * @returns true / false accordingly.
226 * @param pSet Pointer to the set.
227 */
228DECLINLINE(bool) RTCpuSetIsEmpty(PRTCPUSET pSet)
229{
230 unsigned i;
231 for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
232 if (pSet->bmSet[i])
233 return false;
234 return true;
235}
236
237
238/**
239 * Converts the CPU set to a 64-bit mask.
240 *
241 * @returns The mask.
242 * @param pSet Pointer to the set.
243 * @remarks Use with extreme care as it may lose information!
244 */
245DECLINLINE(uint64_t) RTCpuSetToU64(PCRTCPUSET pSet)
246{
247 return pSet->bmSet[0];
248}
249
250
251/**
252 * Initializes the CPU set from a 64-bit mask.
253 *
254 * @param pSet Pointer to the set.
255 * @param fMask The mask.
256 */
257DECLINLINE(PRTCPUSET) RTCpuSetFromU64(PRTCPUSET pSet, uint64_t fMask)
258{
259 unsigned i;
260
261 pSet->bmSet[0] = fMask;
262 for (i = 1; i < RT_ELEMENTS(pSet->bmSet); i++)
263 pSet->bmSet[i] = 0;
264
265 return pSet;
266}
267
268
269/**
270 * Count the CPUs in the set.
271 *
272 * @returns CPU count.
273 * @param pSet Pointer to the set.
274 */
275DECLINLINE(int) RTCpuSetCount(PCRTCPUSET pSet)
276{
277 int cCpus = 0;
278 unsigned i;
279
280 for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
281 {
282 uint64_t u64 = pSet->bmSet[i];
283 if (u64 != 0)
284 {
285 unsigned iCpu = 64;
286 while (iCpu-- > 0)
287 {
288 if (u64 & 1)
289 cCpus++;
290 u64 >>= 1;
291 }
292 }
293 }
294 return cCpus;
295}
296
297
298/**
299 * Get the highest set index.
300 *
301 * @returns The higest set index, -1 if all bits are clear.
302 * @param pSet Pointer to the set.
303 */
304DECLINLINE(int) RTCpuLastIndex(PCRTCPUSET pSet)
305{
306 unsigned i = RT_ELEMENTS(pSet->bmSet);
307 while (i-- > 0)
308 {
309 uint64_t u64 = pSet->bmSet[i];
310 if (u64)
311 {
312 /* There are more efficient ways to do this in asm.h... */
313 unsigned iBit;
314 for (iBit = 63; iBit > 0; iBit--)
315 {
316 if (u64 & RT_BIT_64(63))
317 break;
318 u64 <<= 1;
319 }
320 return i * 64 + iBit;
321 }
322 }
323 return 0;
324}
325
326
327/** @} */
328
329RT_C_DECLS_END
330
331#endif
332
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