VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/solaris/mp-r0drv-solaris.c@ 7913

Last change on this file since 7913 was 7913, checked in by vboxsync, 17 years ago

Check for NIL_CPUID in RTMpOnSpecific.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.8 KB
Line 
1/* $Id: mp-r0drv-solaris.c 7913 2008-04-11 12:54:53Z vboxsync $ */
2/** @file
3 * innotek Portable Runtime - Multiprocessor, Ring-0 Driver, Solaris.
4 */
5
6/*
7 * Copyright (C) 2008 innotek GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include "the-solaris-kernel.h"
32
33#include <iprt/mp.h>
34#include <iprt/cpuset.h>
35#include <iprt/err.h>
36#include <iprt/asm.h>
37#include "r0drv/mp-r0drv.h"
38
39
40RTDECL(RTCPUID) RTMpCpuId(void)
41{
42 return cpuid_get_chipid(CPU); /* is there a better way? */
43}
44
45
46RTDECL(int) RTMpCpuIdToSetIndex(RTCPUID idCpu)
47{
48 return idCpu < NCPU ? idCpu : -1;
49}
50
51
52RTDECL(RTCPUID) RTMpCpuIdFromSetIndex(int iCpu)
53{
54 return (unsigned)iCpu < NCPU ? iCpu : NIL_RTCPUID;
55}
56
57
58RTDECL(RTCPUID) RTMpGetMaxCpuId(void)
59{
60 return NCPU - 1;
61}
62
63
64RTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu)
65{
66 cpu_t *pCpu = idCpu < NCPU ? cpu_get(idCpu) : NULL;
67 return pCpu
68 && cpu_is_online(pCpu);
69}
70
71
72RTDECL(bool) RTMpDoesCpuExist(RTCPUID idCpu)
73{
74 cpu_t *pCpu = idCpu < NCPU ? cpu_get(idCpu) : NULL;
75 return pCpu != NULL;
76}
77
78
79RTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet)
80{
81 RTCPUID idCpu;
82
83 RTCpuSetEmpty(pSet);
84 idCpu = RTMpGetMaxCpuId(); /* it's inclusive */
85 do
86 {
87 if (RTMpDoesCpuExist(idCpu))
88 RTCpuSetAdd(pSet, idCpu);
89 } while (idCpu-- > 0);
90
91 return pSet;
92}
93
94
95RTDECL(RTCPUID) RTMpGetCount(void)
96{
97 return ncpus;
98}
99
100
101RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet)
102{
103 RTCPUID idCpu;
104
105 RTCpuSetEmpty(pSet);
106 idCpu = RTMpGetMaxCpuId(); /* it's inclusive */
107 do
108 {
109 if (RTMpIsCpuOnline(idCpu))
110 RTCpuSetAdd(pSet, idCpu);
111 } while (idCpu-- > 0);
112
113 return pSet;
114}
115
116
117RTDECL(RTCPUID) RTMpGetOnlineCount(void)
118{
119 return ncpus_online;
120}
121
122
123
124/**
125 * Wrapper between the native solaris per-cpu callback and PFNRTWORKER
126 * for the RTMpOnAll API.
127 *
128 * @param uArgs Pointer to the RTMPARGS package.
129 * @param uIgnored1 Ignored.
130 * @param uIgnored2 Ignored.
131 */
132static int rtmpOnAllSolarisWrapper(xc_arg_t uArg, xc_arg_t uIgnored1, xc_arg_t uIgnored2)
133{
134 PRTMPARGS pArgs = (PRTMPARGS)(uArg);
135
136 pArgs->pfnWorker(RTMpCpuId(), pArgs->pvUser1, pArgs->pvUser2);
137
138 NOREF(uIgnored1);
139 NOREF(uIgnored2);
140 return 0;
141}
142
143
144RTDECL(int) RTMpOnAll(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
145{
146 cpuset_t Set;
147 RTMPARGS Args;
148
149 Args.pfnWorker = pfnWorker;
150 Args.pvUser1 = pvUser1;
151 Args.pvUser2 = pvUser2;
152 Args.idCpu = NIL_RTCPUID;
153 Args.cHits = 0;
154
155 CPUSET_ALL(Set);
156 xc_call((uintptr_t)&Args, 0, 0, X_CALL_HIPRI, Set, rtmpOnAllSolarisWrapper);
157
158 return VINF_SUCCESS;
159}
160
161
162/**
163 * Wrapper between the native solaris per-cpu callback and PFNRTWORKER
164 * for the RTMpOnOthers API.
165 *
166 * @param uArgs Pointer to the RTMPARGS package.
167 * @param uIgnored1 Ignored.
168 * @param uIgnored2 Ignored.
169 */
170static int rtmpOnOthersSolarisWrapper(xc_arg_t uArg, xc_arg_t uIgnored1, xc_arg_t uIgnored2)
171{
172 PRTMPARGS pArgs = (PRTMPARGS)(uArg);
173 RTCPUID idCpu = RTMpCpuId();
174
175 Assert(idCpu != pArgs->idCpu);
176 pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
177
178 NOREF(uIgnored1);
179 NOREF(uIgnored2);
180 return 0;
181}
182
183
184RTDECL(int) RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
185{
186 int rc;
187 cpuset_t Set;
188 RTMPARGS Args;
189
190 Args.pfnWorker = pfnWorker;
191 Args.pvUser1 = pvUser1;
192 Args.pvUser2 = pvUser2;
193 Args.idCpu = RTMpCpuId();
194 Args.cHits = 0;
195
196 CPUSET_ALL_BUT(Set, Args.idCpu);
197 xc_call((uintptr_t)&Args, 0, 0, X_CALL_HIPRI, Set, rtmpOnOthersSolarisWrapper);
198
199 return VINF_SUCCESS;
200}
201
202
203/**
204 * Wrapper between the native solaris per-cpu callback and PFNRTWORKER
205 * for the RTMpOnSpecific API.
206 *
207 *
208 * @param uArgs Pointer to the RTMPARGS package.
209 * @param uIgnored1 Ignored.
210 * @param uIgnored2 Ignored.
211 */
212static int rtmpOnSpecificSolarisWrapper(xc_arg_t uArg, xc_arg_t uIgnored1, xc_arg_t uIgnored2)
213{
214 PRTMPARGS pArgs = (PRTMPARGS)(uArg);
215 RTCPUID idCpu = RTMpCpuId();
216
217 Assert(idCpu != pArgs->idCpu);
218 pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
219 ASMAtomicIncU32(&pArgs->cHits);
220
221 NOREF(uIgnored1);
222 NOREF(uIgnored2);
223 return 0;
224}
225
226
227RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
228{
229 int rc;
230 cpuset_t Set;
231 RTMPARGS Args;
232
233 if (idCpu >= NCPU)
234 return VERR_CPU_NOT_FOUND;
235
236 Args.pfnWorker = pfnWorker;
237 Args.pvUser1 = pvUser1;
238 Args.pvUser2 = pvUser2;
239 Args.idCpu = idCpu;
240 Args.cHits = 0;
241
242 CPUSET_ZERO(Set);
243 CPUSET_ADD(Set, idCpu);
244
245 xc_call((uintptr_t)&Args, 0, 0, X_CALL_HIPRI, Set, rtmpOnSpecificSolarisWrapper);
246 Assert(ASMAtomicUoReadU32(&Args.cHits) <= 1);
247
248 return ASMAtomicUoReadU32(&Args.cHits) == 1
249 ? VINF_SUCCESS
250 : VERR_CPU_NOT_FOUND;
251}
252
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette