[7251] | 1 | /** @file
|
---|
[8245] | 2 | * IPRT - Multiprocessor.
|
---|
[7251] | 3 | */
|
---|
| 4 |
|
---|
| 5 | /*
|
---|
[98103] | 6 | * Copyright (C) 2008-2023 Oracle and/or its affiliates.
|
---|
[7251] | 7 | *
|
---|
[96407] | 8 | * This file is part of VirtualBox base platform packages, as
|
---|
| 9 | * available from https://www.virtualbox.org.
|
---|
[7251] | 10 | *
|
---|
[96407] | 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 | *
|
---|
[7251] | 24 | * The contents of this file may alternatively be used under the terms
|
---|
| 25 | * of the Common Development and Distribution License Version 1.0
|
---|
[96407] | 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
|
---|
[7251] | 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.
|
---|
[96407] | 32 | *
|
---|
| 33 | * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
|
---|
[7251] | 34 | */
|
---|
| 35 |
|
---|
[76557] | 36 | #ifndef IPRT_INCLUDED_mp_h
|
---|
| 37 | #define IPRT_INCLUDED_mp_h
|
---|
[76507] | 38 | #ifndef RT_WITHOUT_PRAGMA_ONCE
|
---|
| 39 | # pragma once
|
---|
| 40 | #endif
|
---|
[7251] | 41 |
|
---|
| 42 | #include <iprt/cdefs.h>
|
---|
| 43 | #include <iprt/types.h>
|
---|
| 44 |
|
---|
| 45 |
|
---|
[20374] | 46 | RT_C_DECLS_BEGIN
|
---|
[7251] | 47 |
|
---|
| 48 | /** @defgroup grp_rt_mp RTMp - Multiprocessor
|
---|
| 49 | * @ingroup grp_rt
|
---|
| 50 | * @{
|
---|
| 51 | */
|
---|
| 52 |
|
---|
| 53 | /**
|
---|
| 54 | * Gets the identifier of the CPU executing the call.
|
---|
[7325] | 55 | *
|
---|
[7251] | 56 | * When called from a system mode where scheduling is active, like ring-3 or
|
---|
| 57 | * kernel mode with interrupts enabled on some systems, no assumptions should
|
---|
| 58 | * be made about the current CPU when the call returns.
|
---|
[7325] | 59 | *
|
---|
[7251] | 60 | * @returns CPU Id.
|
---|
| 61 | */
|
---|
| 62 | RTDECL(RTCPUID) RTMpCpuId(void);
|
---|
| 63 |
|
---|
[7325] | 64 | /**
|
---|
[54415] | 65 | * Get the CPU set index of the CPU executing the call.
|
---|
| 66 | *
|
---|
| 67 | * Same scheduling warnings as for RTMpCpuId().
|
---|
| 68 | *
|
---|
| 69 | * @returns CPU set index.
|
---|
| 70 | */
|
---|
| 71 | RTDECL(int) RTMpCurSetIndex(void);
|
---|
| 72 |
|
---|
| 73 | /**
|
---|
| 74 | * Get the CPU set index and identifier of the CPU executing the call.
|
---|
| 75 | *
|
---|
| 76 | * Same scheduling warnings as for RTMpCpuId().
|
---|
| 77 | *
|
---|
| 78 | * @returns CPU set index.
|
---|
| 79 | * @param pidCpu Where to return the CPU identifier. (not optional)
|
---|
| 80 | */
|
---|
| 81 | RTDECL(int) RTMpCurSetIndexAndId(PRTCPUID pidCpu);
|
---|
| 82 |
|
---|
| 83 | /**
|
---|
[7326] | 84 | * Converts a CPU identifier to a CPU set index.
|
---|
| 85 | *
|
---|
[10418] | 86 | * This may or may not validate the presence of the CPU.
|
---|
[7330] | 87 | *
|
---|
[7326] | 88 | * @returns The CPU set index on success, -1 on failure.
|
---|
| 89 | * @param idCpu The identifier of the CPU.
|
---|
| 90 | */
|
---|
| 91 | RTDECL(int) RTMpCpuIdToSetIndex(RTCPUID idCpu);
|
---|
[7325] | 92 |
|
---|
[7328] | 93 | /**
|
---|
[7330] | 94 | * Converts a CPU set index to a a CPU identifier.
|
---|
| 95 | *
|
---|
[10418] | 96 | * This may or may not validate the presence of the CPU, so, use
|
---|
[9429] | 97 | * RTMpIsCpuPossible for that.
|
---|
[7330] | 98 | *
|
---|
| 99 | * @returns The corresponding CPU identifier, NIL_RTCPUID on failure.
|
---|
| 100 | * @param iCpu The CPU set index.
|
---|
| 101 | */
|
---|
| 102 | RTDECL(RTCPUID) RTMpCpuIdFromSetIndex(int iCpu);
|
---|
| 103 |
|
---|
| 104 | /**
|
---|
[64281] | 105 | * Translates an NT process group member to a CPU set index.
|
---|
| 106 | *
|
---|
| 107 | * @returns CPU set index, -1 if not valid.
|
---|
| 108 | * @param idxGroup The CPU group.
|
---|
| 109 | * @param idxMember The CPU group member number.
|
---|
| 110 | *
|
---|
| 111 | * @remarks Only available on Windows.
|
---|
| 112 | */
|
---|
| 113 | RTDECL(int) RTMpSetIndexFromCpuGroupMember(uint32_t idxGroup, uint32_t idxMember);
|
---|
| 114 |
|
---|
| 115 | /**
|
---|
| 116 | * Gets the member numbers for a CPU group.
|
---|
| 117 | *
|
---|
| 118 | * @returns Maximum number of group members.
|
---|
| 119 | * @param idxGroup The CPU group.
|
---|
| 120 | * @param pcActive Where to return the number of active members.
|
---|
| 121 | *
|
---|
| 122 | * @remarks Only available on Windows.
|
---|
| 123 | */
|
---|
| 124 | RTDECL(uint32_t) RTMpGetCpuGroupCounts(uint32_t idxGroup, uint32_t *pcActive);
|
---|
| 125 |
|
---|
| 126 | /**
|
---|
| 127 | * Get the maximum number of CPU groups.
|
---|
| 128 | *
|
---|
| 129 | * @returns Maximum number of CPU groups.
|
---|
| 130 | *
|
---|
| 131 | * @remarks Only available on Windows.
|
---|
| 132 | */
|
---|
| 133 | RTDECL(uint32_t) RTMpGetMaxCpuGroupCount(void);
|
---|
| 134 |
|
---|
| 135 | /**
|
---|
[7330] | 136 | * Gets the max CPU identifier (inclusive).
|
---|
| 137 | *
|
---|
[32572] | 138 | * Intended for brute force enumerations, but use with
|
---|
[7330] | 139 | * care as it may be expensive.
|
---|
| 140 | *
|
---|
| 141 | * @returns The current higest CPU identifier value.
|
---|
| 142 | */
|
---|
| 143 | RTDECL(RTCPUID) RTMpGetMaxCpuId(void);
|
---|
| 144 |
|
---|
[32572] | 145 | /**
|
---|
| 146 | * Gets the size of a CPU array that is indexed by CPU set index.
|
---|
| 147 | *
|
---|
| 148 | * This takes both online, offline and hot-plugged cpus into account.
|
---|
| 149 | *
|
---|
| 150 | * @returns Number of elements.
|
---|
| 151 | *
|
---|
| 152 | * @remarks Use RTMpCpuIdToSetIndex to convert a RTCPUID into an array index.
|
---|
| 153 | */
|
---|
| 154 | RTDECL(uint32_t) RTMpGetArraySize(void);
|
---|
[12104] | 155 |
|
---|
[7330] | 156 | /**
|
---|
[9429] | 157 | * Checks if a CPU exists in the system or may possibly be hotplugged later.
|
---|
[7354] | 158 | *
|
---|
| 159 | * @returns true/false accordingly.
|
---|
| 160 | * @param idCpu The identifier of the CPU.
|
---|
| 161 | */
|
---|
[9429] | 162 | RTDECL(bool) RTMpIsCpuPossible(RTCPUID idCpu);
|
---|
[7354] | 163 |
|
---|
| 164 | /**
|
---|
[33540] | 165 | * Gets set of the CPUs present in the system plus any that may
|
---|
[9429] | 166 | * possibly be hotplugged later.
|
---|
[7354] | 167 | *
|
---|
[7328] | 168 | * @returns pSet.
|
---|
| 169 | * @param pSet Where to put the set.
|
---|
| 170 | */
|
---|
| 171 | RTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet);
|
---|
[7325] | 172 |
|
---|
[7328] | 173 | /**
|
---|
[9429] | 174 | * Get the count of CPUs present in the system plus any that may
|
---|
| 175 | * possibly be hotplugged later.
|
---|
[7328] | 176 | *
|
---|
[32572] | 177 | * @returns The count.
|
---|
| 178 | * @remarks Don't use this for CPU array sizing, use RTMpGetArraySize instead.
|
---|
[7328] | 179 | */
|
---|
| 180 | RTDECL(RTCPUID) RTMpGetCount(void);
|
---|
[7326] | 181 |
|
---|
[46144] | 182 | /**
|
---|
[46636] | 183 | * Get the count of physical CPU cores present in the system plus any that may
|
---|
| 184 | * possibly be hotplugged later.
|
---|
| 185 | *
|
---|
| 186 | * @returns The number of cores.
|
---|
[46144] | 187 | */
|
---|
| 188 | RTDECL(RTCPUID) RTMpGetCoreCount(void);
|
---|
[12104] | 189 |
|
---|
[7328] | 190 | /**
|
---|
| 191 | * Gets set of the CPUs present that are currently online.
|
---|
| 192 | *
|
---|
| 193 | * @returns pSet.
|
---|
| 194 | * @param pSet Where to put the set.
|
---|
| 195 | */
|
---|
[7329] | 196 | RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet);
|
---|
[7328] | 197 |
|
---|
| 198 | /**
|
---|
| 199 | * Get the count of CPUs that are currently online.
|
---|
| 200 | *
|
---|
| 201 | * @return The count.
|
---|
| 202 | */
|
---|
| 203 | RTDECL(RTCPUID) RTMpGetOnlineCount(void);
|
---|
| 204 |
|
---|
[9429] | 205 | /**
|
---|
[46639] | 206 | * Get the count of physical CPU cores in the system with one or more online
|
---|
| 207 | * threads.
|
---|
| 208 | *
|
---|
| 209 | * @returns The number of online cores.
|
---|
| 210 | */
|
---|
[48765] | 211 | RTDECL(RTCPUID) RTMpGetOnlineCoreCount(void);
|
---|
[46639] | 212 |
|
---|
| 213 | /**
|
---|
[9429] | 214 | * Checks if a CPU is online or not.
|
---|
| 215 | *
|
---|
| 216 | * @returns true/false accordingly.
|
---|
| 217 | * @param idCpu The identifier of the CPU.
|
---|
| 218 | */
|
---|
| 219 | RTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu);
|
---|
[7328] | 220 |
|
---|
[12104] | 221 |
|
---|
[10418] | 222 | /**
|
---|
[12104] | 223 | * Gets set of the CPUs present in the system.
|
---|
| 224 | *
|
---|
| 225 | * @returns pSet.
|
---|
| 226 | * @param pSet Where to put the set.
|
---|
| 227 | */
|
---|
| 228 | RTDECL(PRTCPUSET) RTMpGetPresentSet(PRTCPUSET pSet);
|
---|
| 229 |
|
---|
| 230 | /**
|
---|
| 231 | * Get the count of CPUs that are present in the system.
|
---|
| 232 | *
|
---|
| 233 | * @return The count.
|
---|
| 234 | */
|
---|
| 235 | RTDECL(RTCPUID) RTMpGetPresentCount(void);
|
---|
| 236 |
|
---|
| 237 | /**
|
---|
[46639] | 238 | * Get the count of physical CPU cores present in the system.
|
---|
| 239 | *
|
---|
| 240 | * @returns The number of cores.
|
---|
| 241 | */
|
---|
| 242 | RTDECL(RTCPUID) RTMpGetPresentCoreCount(void);
|
---|
| 243 |
|
---|
| 244 | /**
|
---|
[12104] | 245 | * Checks if a CPU is present in the system.
|
---|
| 246 | *
|
---|
| 247 | * @returns true/false accordingly.
|
---|
| 248 | * @param idCpu The identifier of the CPU.
|
---|
| 249 | */
|
---|
| 250 | RTDECL(bool) RTMpIsCpuPresent(RTCPUID idCpu);
|
---|
| 251 |
|
---|
| 252 |
|
---|
| 253 | /**
|
---|
[10422] | 254 | * Get the current frequency of a CPU.
|
---|
[10418] | 255 | *
|
---|
[10422] | 256 | * The CPU must be online.
|
---|
| 257 | *
|
---|
| 258 | * @returns The frequency as MHz. 0 if the CPU is offline
|
---|
| 259 | * or the information is not available.
|
---|
| 260 | * @param idCpu The identifier of the CPU.
|
---|
[10418] | 261 | */
|
---|
| 262 | RTDECL(uint32_t) RTMpGetCurFrequency(RTCPUID idCpu);
|
---|
[9429] | 263 |
|
---|
[10418] | 264 | /**
|
---|
[10422] | 265 | * Get the maximum frequency of a CPU.
|
---|
[10418] | 266 | *
|
---|
[10422] | 267 | * The CPU must be online.
|
---|
| 268 | *
|
---|
| 269 | * @returns The frequency as MHz. 0 if the CPU is offline
|
---|
| 270 | * or the information is not available.
|
---|
| 271 | * @param idCpu The identifier of the CPU.
|
---|
[10418] | 272 | */
|
---|
| 273 | RTDECL(uint32_t) RTMpGetMaxFrequency(RTCPUID idCpu);
|
---|
| 274 |
|
---|
[21725] | 275 | /**
|
---|
| 276 | * Get the CPU description string.
|
---|
| 277 | *
|
---|
| 278 | * The CPU must be online.
|
---|
| 279 | *
|
---|
| 280 | * @returns IPRT status code.
|
---|
[50641] | 281 | * @param idCpu The identifier of the CPU. NIL_RTCPUID can be used to
|
---|
| 282 | * indicate the current CPU.
|
---|
[21725] | 283 | * @param pszBuf The output buffer.
|
---|
| 284 | * @param cbBuf The size of the output buffer.
|
---|
| 285 | */
|
---|
| 286 | RTDECL(int) RTMpGetDescription(RTCPUID idCpu, char *pszBuf, size_t cbBuf);
|
---|
[10418] | 287 |
|
---|
[21725] | 288 |
|
---|
[7251] | 289 | #ifdef IN_RING0
|
---|
| 290 |
|
---|
| 291 | /**
|
---|
[15843] | 292 | * Check if there's work (DPCs on Windows) pending on the current CPU.
|
---|
| 293 | *
|
---|
| 294 | * @return true if there's pending work on the current CPU, false otherwise.
|
---|
| 295 | */
|
---|
| 296 | RTDECL(bool) RTMpIsCpuWorkPending(void);
|
---|
| 297 |
|
---|
| 298 |
|
---|
| 299 | /**
|
---|
[7251] | 300 | * Worker function passed to RTMpOnAll, RTMpOnOthers and RTMpOnSpecific that
|
---|
| 301 | * is to be called on the target cpus.
|
---|
[7325] | 302 | *
|
---|
[7251] | 303 | * @param idCpu The identifier for the CPU the function is called on.
|
---|
| 304 | * @param pvUser1 The 1st user argument.
|
---|
| 305 | * @param pvUser2 The 2nd user argument.
|
---|
| 306 | */
|
---|
[85121] | 307 | typedef DECLCALLBACKTYPE(void, FNRTMPWORKER,(RTCPUID idCpu, void *pvUser1, void *pvUser2));
|
---|
[7252] | 308 | /** Pointer to a FNRTMPWORKER. */
|
---|
| 309 | typedef FNRTMPWORKER *PFNRTMPWORKER;
|
---|
[7251] | 310 |
|
---|
[54408] | 311 | /** @name RTMPON_F_XXX - RTMpOn flags.
|
---|
| 312 | * @{ */
|
---|
| 313 | /** Caller doesn't care if pfnWorker is executed at the same time on the
|
---|
| 314 | * specified CPUs or not, as long as it gets executed. */
|
---|
| 315 | #define RTMPON_F_WHATEVER_EXEC 0
|
---|
| 316 | /** The caller insists on pfnWorker being executed more or less concurrently
|
---|
| 317 | * on the specified CPUs. */
|
---|
| 318 | #define RTMPON_F_CONCURRENT_EXEC RT_BIT_32(1)
|
---|
| 319 | /** Mask of valid bits. */
|
---|
| 320 | #define RTMPON_F_VALID_MASK UINT32_C(0x00000001)
|
---|
| 321 | /** @}*/
|
---|
| 322 |
|
---|
[7251] | 323 | /**
|
---|
[52618] | 324 | * Checks if the RTMpOnAll() is safe with regards to all threads executing
|
---|
| 325 | * concurrently.
|
---|
| 326 | *
|
---|
| 327 | * If for instance, the RTMpOnAll() is implemented in a way where the threads
|
---|
| 328 | * might cause a classic deadlock, it is considered -not- concurrent safe.
|
---|
| 329 | * Windows currently is one such platform where it isn't safe.
|
---|
| 330 | *
|
---|
| 331 | * @returns true if RTMpOnAll() is concurrent safe, false otherwise.
|
---|
| 332 | */
|
---|
| 333 | RTDECL(bool) RTMpOnAllIsConcurrentSafe(void);
|
---|
| 334 |
|
---|
| 335 | /**
|
---|
[7251] | 336 | * Executes a function on each (online) CPU in the system.
|
---|
[7325] | 337 | *
|
---|
[7251] | 338 | * @returns IPRT status code.
|
---|
| 339 | * @retval VINF_SUCCESS on success.
|
---|
| 340 | * @retval VERR_NOT_SUPPORTED if this kind of operation isn't supported by the system.
|
---|
[7325] | 341 | *
|
---|
[7251] | 342 | * @param pfnWorker The worker function.
|
---|
[7325] | 343 | * @param pvUser1 The first user argument for the worker.
|
---|
| 344 | * @param pvUser2 The second user argument for the worker.
|
---|
[7251] | 345 | *
|
---|
| 346 | * @remarks The execution isn't in any way guaranteed to be simultaneous,
|
---|
| 347 | * it might even be serial (cpu by cpu).
|
---|
| 348 | */
|
---|
[7252] | 349 | RTDECL(int) RTMpOnAll(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
|
---|
[7251] | 350 |
|
---|
| 351 | /**
|
---|
[75230] | 352 | * Executes a function on all other (online) CPUs in the system.
|
---|
[7325] | 353 | *
|
---|
[19390] | 354 | * The caller must disable preemption prior to calling this API if the outcome
|
---|
| 355 | * is to make any sense. But do *not* disable interrupts.
|
---|
| 356 | *
|
---|
[7251] | 357 | * @returns IPRT status code.
|
---|
| 358 | * @retval VINF_SUCCESS on success.
|
---|
| 359 | * @retval VERR_NOT_SUPPORTED if this kind of operation isn't supported by the system.
|
---|
[7325] | 360 | *
|
---|
[7251] | 361 | * @param pfnWorker The worker function.
|
---|
[7325] | 362 | * @param pvUser1 The first user argument for the worker.
|
---|
| 363 | * @param pvUser2 The second user argument for the worker.
|
---|
| 364 | *
|
---|
[7251] | 365 | * @remarks The execution isn't in any way guaranteed to be simultaneous,
|
---|
| 366 | * it might even be serial (cpu by cpu).
|
---|
| 367 | */
|
---|
[7252] | 368 | RTDECL(int) RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
|
---|
[7251] | 369 |
|
---|
| 370 | /**
|
---|
| 371 | * Executes a function on a specific CPU in the system.
|
---|
[7325] | 372 | *
|
---|
[7251] | 373 | * @returns IPRT status code.
|
---|
| 374 | * @retval VINF_SUCCESS on success.
|
---|
| 375 | * @retval VERR_NOT_SUPPORTED if this kind of operation isn't supported by the system.
|
---|
| 376 | * @retval VERR_CPU_OFFLINE if the CPU is offline.
|
---|
| 377 | * @retval VERR_CPU_NOT_FOUND if the CPU wasn't found.
|
---|
[7325] | 378 | *
|
---|
[7251] | 379 | * @param idCpu The id of the CPU.
|
---|
| 380 | * @param pfnWorker The worker function.
|
---|
[7325] | 381 | * @param pvUser1 The first user argument for the worker.
|
---|
| 382 | * @param pvUser2 The second user argument for the worker.
|
---|
[7251] | 383 | */
|
---|
[7252] | 384 | RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
|
---|
[7251] | 385 |
|
---|
[19386] | 386 | /**
|
---|
[54408] | 387 | * Executes a function on two specific CPUs in the system.
|
---|
| 388 | *
|
---|
| 389 | * @returns IPRT status code.
|
---|
| 390 | * @retval VINF_SUCCESS on success.
|
---|
| 391 | * @retval VERR_NOT_SUPPORTED if this kind of operation isn't supported by the
|
---|
| 392 | * system or if the specified modifier flag isn't supported.
|
---|
| 393 | * @retval VERR_CPU_OFFLINE if one or more of the CPUs are offline (see
|
---|
| 394 | * remarks).
|
---|
| 395 | * @retval VERR_CPU_NOT_FOUND if on or both of the CPUs weren't found.
|
---|
| 396 | * @retval VERR_NOT_ALL_CPUS_SHOWED if one of the CPUs didn't show.
|
---|
| 397 | *
|
---|
| 398 | * @param idCpu1 The id of the first CPU.
|
---|
| 399 | * @param idCpu2 The id of the second CPU.
|
---|
| 400 | * @param fFlags Combination of RTMPON_F_XXX flags.
|
---|
| 401 | * @param pfnWorker The worker function.
|
---|
| 402 | * @param pvUser1 The first user argument for the worker.
|
---|
| 403 | * @param pvUser2 The second user argument for the worker.
|
---|
| 404 | *
|
---|
| 405 | * @remarks There is a possible race between one (or both) of the CPUs going
|
---|
| 406 | * offline while setting up the call. The worker function must take
|
---|
| 407 | * this into account.
|
---|
| 408 | */
|
---|
| 409 | RTDECL(int) RTMpOnPair(RTCPUID idCpu1, RTCPUID idCpu2, uint32_t fFlags, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
|
---|
| 410 |
|
---|
| 411 | /**
|
---|
| 412 | * Indicates whether RTMpOnPair supports running the pfnWorker concurrently on
|
---|
| 413 | * both CPUs using RTMPON_F_CONCURRENT_EXEC.
|
---|
| 414 | *
|
---|
| 415 | * @returns true if supported, false if not.
|
---|
| 416 | */
|
---|
| 417 | RTDECL(bool) RTMpOnPairIsConcurrentExecSupported(void);
|
---|
| 418 |
|
---|
| 419 |
|
---|
| 420 | /**
|
---|
[19386] | 421 | * Pokes the specified CPU.
|
---|
| 422 | *
|
---|
| 423 | * This should cause the execution on the CPU to be interrupted and forcing it
|
---|
| 424 | * to enter kernel context. It is optimized version of a RTMpOnSpecific call
|
---|
| 425 | * with a worker which returns immediately.
|
---|
| 426 | *
|
---|
| 427 | * @returns IPRT status code.
|
---|
| 428 | * @retval VERR_NOT_SUPPORTED if this kind of operation isn't supported by the
|
---|
| 429 | * system. The caller must not automatically assume that this API works
|
---|
| 430 | * when any of the RTMpOn* APIs works. This is because not all systems
|
---|
| 431 | * supports unicast MP events and this API will not be implemented as a
|
---|
| 432 | * broadcast.
|
---|
| 433 | * @retval VERR_CPU_OFFLINE if the CPU is offline.
|
---|
| 434 | * @retval VERR_CPU_NOT_FOUND if the CPU wasn't found.
|
---|
| 435 | *
|
---|
| 436 | * @param idCpu The id of the CPU to poke.
|
---|
| 437 | */
|
---|
| 438 | RTDECL(int) RTMpPokeCpu(RTCPUID idCpu);
|
---|
[9309] | 439 |
|
---|
[19386] | 440 |
|
---|
[9309] | 441 | /**
|
---|
| 442 | * MP event, see FNRTMPNOTIFICATION.
|
---|
| 443 | */
|
---|
| 444 | typedef enum RTMPEVENT
|
---|
| 445 | {
|
---|
| 446 | /** The CPU goes online. */
|
---|
| 447 | RTMPEVENT_ONLINE = 1,
|
---|
| 448 | /** The CPU goes offline. */
|
---|
| 449 | RTMPEVENT_OFFLINE
|
---|
| 450 | } RTMPEVENT;
|
---|
| 451 |
|
---|
| 452 | /**
|
---|
| 453 | * Notification callback.
|
---|
| 454 | *
|
---|
[54293] | 455 | * The context this is called in differs a bit from platform to platform, so be
|
---|
| 456 | * careful while in here.
|
---|
[9309] | 457 | *
|
---|
[54382] | 458 | * On Windows we're running with IRQL=PASSIVE_LEVEL (reschedulable) according to
|
---|
| 459 | * the KeRegisterProcessorChangeCallback documentation - unrestricted API
|
---|
| 460 | * access. Probably not being called on the onlined/offlined CPU...
|
---|
[54293] | 461 | *
|
---|
[54294] | 462 | * On Solaris we're holding the cpu_lock, IPL/SPL/PIL is not yet known, however
|
---|
| 463 | * we will most likely -not- be firing on the CPU going offline/online.
|
---|
[54293] | 464 | *
|
---|
[54382] | 465 | * On Linux it looks like we're called with preemption enabled on any CPU and
|
---|
| 466 | * not necessarily on the CPU going offline/online.
|
---|
[54293] | 467 | *
|
---|
| 468 | * There is no callbacks for darwin at the moment, due to lack of suitable KPI.
|
---|
| 469 | *
|
---|
[9309] | 470 | * @param idCpu The CPU this applies to.
|
---|
| 471 | * @param enmEvent The event.
|
---|
| 472 | * @param pvUser The user argument.
|
---|
| 473 | */
|
---|
[85121] | 474 | typedef DECLCALLBACKTYPE(void, FNRTMPNOTIFICATION,(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvUser));
|
---|
[9309] | 475 | /** Pointer to a FNRTMPNOTIFICATION(). */
|
---|
| 476 | typedef FNRTMPNOTIFICATION *PFNRTMPNOTIFICATION;
|
---|
| 477 |
|
---|
| 478 | /**
|
---|
| 479 | * Registers a notification callback for cpu events.
|
---|
| 480 | *
|
---|
| 481 | * On platforms which doesn't do cpu offline/online events this API
|
---|
| 482 | * will just be a no-op that pretends to work.
|
---|
| 483 | *
|
---|
[9611] | 484 | * @todo We'll be adding a flag to this soon to indicate whether the callback should be called on all
|
---|
| 485 | * CPUs that are currently online while it's being registered. This is to help avoid some race
|
---|
| 486 | * conditions (we'll hopefully be able to implement this on linux, solaris/win is no issue).
|
---|
| 487 | *
|
---|
[9309] | 488 | * @returns IPRT status code.
|
---|
| 489 | * @retval VINF_SUCCESS on success.
|
---|
| 490 | * @retval VERR_NO_MEMORY if a registration record cannot be allocated.
|
---|
| 491 | * @retval VERR_ALREADY_EXISTS if the pfnCallback and pvUser already exist
|
---|
| 492 | * in the callback list.
|
---|
| 493 | *
|
---|
| 494 | * @param pfnCallback The callback.
|
---|
| 495 | * @param pvUser The user argument to the callback function.
|
---|
| 496 | */
|
---|
| 497 | RTDECL(int) RTMpNotificationRegister(PFNRTMPNOTIFICATION pfnCallback, void *pvUser);
|
---|
| 498 |
|
---|
| 499 | /**
|
---|
| 500 | * This deregisters a notification callback registered via RTMpNotificationRegister().
|
---|
| 501 | *
|
---|
| 502 | * The pfnCallback and pvUser arguments must be identical to the registration call
|
---|
| 503 | * of we won't find the right entry.
|
---|
| 504 | *
|
---|
| 505 | * @returns IPRT status code.
|
---|
| 506 | * @retval VINF_SUCCESS on success.
|
---|
| 507 | * @retval VERR_NOT_FOUND if no matching entry was found.
|
---|
| 508 | *
|
---|
| 509 | * @param pfnCallback The callback.
|
---|
| 510 | * @param pvUser The user argument to the callback function.
|
---|
| 511 | */
|
---|
| 512 | RTDECL(int) RTMpNotificationDeregister(PFNRTMPNOTIFICATION pfnCallback, void *pvUser);
|
---|
| 513 |
|
---|
[7251] | 514 | #endif /* IN_RING0 */
|
---|
| 515 |
|
---|
| 516 | /** @} */
|
---|
| 517 |
|
---|
[20374] | 518 | RT_C_DECLS_END
|
---|
[7251] | 519 |
|
---|
[76585] | 520 | #endif /* !IPRT_INCLUDED_mp_h */
|
---|
[7251] | 521 |
|
---|