VirtualBox

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

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

*: scm --fix-header-guard-endif

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 7.7 KB
RevLine 
[7326]1/** @file
[8245]2 * IPRT - CPU Set.
[7326]3 */
4
5/*
[76553]6 * Copyright (C) 2008-2019 Oracle Corporation
[7326]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
[76557]26#ifndef IPRT_INCLUDED_cpuset_h
27#define IPRT_INCLUDED_cpuset_h
[76507]28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
[7326]31
32#include <iprt/types.h>
33#include <iprt/mp.h> /* RTMpCpuIdToSetIndex */
[9309]34#include <iprt/asm.h>
[7326]35
36
[20374]37RT_C_DECLS_BEGIN
[7326]38
[12653]39/** @defgroup grp_rt_cpuset RTCpuSet - CPU Set
[7326]40 * @ingroup grp_rt
41 * @{
42 */
43
[7354]44
45/**
[7326]46 * Clear all CPUs.
47 *
[7336]48 * @returns pSet.
[7326]49 * @param pSet Pointer to the set.
50 */
[7336]51DECLINLINE(PRTCPUSET) RTCpuSetEmpty(PRTCPUSET pSet)
[7326]52{
[63398]53 size_t i;
[36232]54 for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
55 pSet->bmSet[i] = 0;
[7336]56 return pSet;
[7326]57}
58
59
60/**
61 * Set all CPUs.
62 *
[7336]63 * @returns pSet.
[7326]64 * @param pSet Pointer to the set.
65 */
[7336]66DECLINLINE(PRTCPUSET) RTCpuSetFill(PRTCPUSET pSet)
[7326]67{
[63398]68 size_t i;
[36232]69 for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
70 pSet->bmSet[i] = UINT64_MAX;
[7336]71 return pSet;
[7326]72}
73
74
75/**
[53327]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{
[63398]83 size_t i;
[53327]84 for (i = 0; i < RT_ELEMENTS(pDst->bmSet); i++)
85 pDst->bmSet[i] = pSrc->bmSet[i];
86}
87
88
89/**
[52582]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{
[63398]98 size_t i;
[52582]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/**
[9579]106 * Adds a CPU given by its identifier to the set.
[7326]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.
[9309]111 * @remarks The modification is atomic.
[7326]112 */
113DECLINLINE(int) RTCpuSetAdd(PRTCPUSET pSet, RTCPUID idCpu)
114{
115 int iCpu = RTMpCpuIdToSetIndex(idCpu);
[55948]116 if (RT_LIKELY(iCpu >= 0))
117 {
118 ASMAtomicBitSet(pSet, iCpu);
119 return 0;
120 }
121 return -1;
[7326]122}
123
124
125/**
[36254]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{
[55948]135 if (RT_LIKELY((unsigned)iCpu < RTCPUSET_MAX_CPUS))
136 {
137 ASMAtomicBitSet(pSet, iCpu);
138 return 0;
139 }
140 return -1;
[36254]141}
142
143
144/**
[9579]145 * Removes a CPU given by its identifier from the set.
[7326]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.
[9309]150 * @remarks The modification is atomic.
[7326]151 */
152DECLINLINE(int) RTCpuSetDel(PRTCPUSET pSet, RTCPUID idCpu)
153{
154 int iCpu = RTMpCpuIdToSetIndex(idCpu);
[55948]155 if (RT_LIKELY(iCpu >= 0))
156 {
157 ASMAtomicBitClear(pSet, iCpu);
158 return 0;
159 }
160 return -1;
[7326]161}
162
163
164/**
[15345]165 * Removes a CPU given by its index from the set.
166 *
[36254]167 * @returns 0 on success, -1 if iCpu isn't valid.
[15345]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{
[55948]174 if (RT_LIKELY((unsigned)iCpu < RTCPUSET_MAX_CPUS))
175 {
176 ASMAtomicBitClear(pSet, iCpu);
177 return 0;
178 }
179 return -1;
[15345]180}
181
182
183/**
[9579]184 * Checks if a CPU given by its identifier is a member of the set.
[7326]185 *
186 * @returns true / false accordingly.
187 * @param pSet Pointer to the set.
188 * @param idCpu The identifier of the CPU to look for.
[9309]189 * @remarks The test is atomic.
[7326]190 */
[7361]191DECLINLINE(bool) RTCpuSetIsMember(PCRTCPUSET pSet, RTCPUID idCpu)
[7326]192{
193 int iCpu = RTMpCpuIdToSetIndex(idCpu);
[55948]194 if (RT_LIKELY(iCpu >= 0))
195 return ASMBitTest((volatile void *)pSet, iCpu);
196 return false;
[7326]197}
198
199
200/**
[9579]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 */
[9623]208DECLINLINE(bool) RTCpuSetIsMemberByIndex(PCRTCPUSET pSet, int iCpu)
[9579]209{
[55948]210 if (RT_LIKELY((unsigned)iCpu < RTCPUSET_MAX_CPUS))
211 return ASMBitTest((volatile void *)pSet, iCpu);
212 return false;
[9579]213}
214
215
216/**
[9368]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{
[63398]225 size_t i;
[36232]226 for (i = 0; i < RT_ELEMENTS(pSet1->bmSet); i++)
[36254]227 if (pSet1->bmSet[i] != pSet2->bmSet[i])
[36232]228 return false;
229 return true;
[9368]230}
231
232
233/**
[52582]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{
[63398]241 size_t i;
[52582]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/**
[7326]250 * Converts the CPU set to a 64-bit mask.
251 *
252 * @returns The mask.
253 * @param pSet Pointer to the set.
[36232]254 * @remarks Use with extreme care as it may lose information!
[7326]255 */
256DECLINLINE(uint64_t) RTCpuSetToU64(PCRTCPUSET pSet)
257{
[36232]258 return pSet->bmSet[0];
[7326]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 */
[7336]268DECLINLINE(PRTCPUSET) RTCpuSetFromU64(PRTCPUSET pSet, uint64_t fMask)
[7326]269{
[63398]270 size_t i;
[36232]271
272 pSet->bmSet[0] = fMask;
273 for (i = 1; i < RT_ELEMENTS(pSet->bmSet); i++)
274 pSet->bmSet[i] = 0;
[36262]275
[7336]276 return pSet;
[7326]277}
278
279
280/**
[7336]281 * Count the CPUs in the set.
[7326]282 *
[7336]283 * @returns CPU count.
284 * @param pSet Pointer to the set.
[7326]285 */
[9622]286DECLINLINE(int) RTCpuSetCount(PCRTCPUSET pSet)
[7336]287{
[36232]288 int cCpus = 0;
[63398]289 size_t i;
[36232]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 }
[7336]305 return cCpus;
306}
[7326]307
308
[9622]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{
[63398]317 size_t i = RT_ELEMENTS(pSet->bmSet);
[36232]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 }
[63399]331 return (int)i * 64 + iBit;
[36232]332 }
333 }
334 return 0;
[9622]335}
336
337
[7326]338/** @} */
339
[20374]340RT_C_DECLS_END
[7326]341
[76585]342#endif /* !IPRT_INCLUDED_cpuset_h */
[7326]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