VirtualBox

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

Last change on this file since 11280 was 10954, checked in by vboxsync, 16 years ago

IPRT: Integrated vbi v2 changes (r0drv/solaris/vbi).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.1 KB
Line 
1/* $Id: mp-r0drv-solaris.c 10954 2008-07-29 19:51:36Z vboxsync $ */
2/** @file
3 * IPRT - Multiprocessor, Ring-0 Driver, Solaris.
4 */
5
6/*
7 * Copyright (C) 2008 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#include "the-solaris-kernel.h"
36
37#include <iprt/mp.h>
38#include <iprt/cpuset.h>
39#include <iprt/err.h>
40#include <iprt/asm.h>
41#include "r0drv/mp-r0drv.h"
42
43
44RTDECL(RTCPUID) RTMpCpuId(void)
45{
46 return vbi_cpu_id();
47}
48
49
50RTDECL(int) RTMpCpuIdToSetIndex(RTCPUID idCpu)
51{
52 return idCpu < vbi_cpu_maxcount() ? idCpu : -1;
53}
54
55
56RTDECL(RTCPUID) RTMpCpuIdFromSetIndex(int iCpu)
57{
58 return (unsigned)iCpu < vbi_cpu_maxcount() ? iCpu : NIL_RTCPUID;
59}
60
61
62RTDECL(RTCPUID) RTMpGetMaxCpuId(void)
63{
64 return vbi_max_cpu_id();
65}
66
67
68RTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu)
69{
70 return idCpu < vbi_cpu_count() && vbi_cpu_online(idCpu);
71}
72
73
74RTDECL(bool) RTMpIsCpuPossible(RTCPUID idCpu)
75{
76 return idCpu < vbi_cpu_count();
77}
78
79
80RTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet)
81{
82 RTCPUID idCpu;
83
84 RTCpuSetEmpty(pSet);
85 idCpu = RTMpGetMaxCpuId(); /* it's inclusive */
86 do
87 {
88 if (RTMpIsCpuPossible(idCpu))
89 RTCpuSetAdd(pSet, idCpu);
90 } while (idCpu-- > 0);
91
92 return pSet;
93}
94
95
96RTDECL(RTCPUID) RTMpGetCount(void)
97{
98 return vbi_cpu_count();
99}
100
101
102RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet)
103{
104 RTCPUID idCpu;
105
106 RTCpuSetEmpty(pSet);
107 idCpu = RTMpGetMaxCpuId(); /* it's inclusive */
108 do
109 {
110 if (RTMpIsCpuOnline(idCpu))
111 RTCpuSetAdd(pSet, idCpu);
112 } while (idCpu-- > 0);
113
114 return pSet;
115}
116
117
118RTDECL(RTCPUID) RTMpGetOnlineCount(void)
119{
120 int c;
121 int cnt = 0;
122
123 for (c = 0; c < vbi_cpu_count(); ++c)
124 {
125 if (vbi_cpu_online(c))
126 ++cnt;
127 }
128 return cnt;
129}
130
131
132
133/**
134 * Wrapper between the native solaris per-cpu callback and PFNRTWORKER
135 * for the RTMpOnAll API.
136 *
137 * @param uArgs Pointer to the RTMPARGS package.
138 * @param uIgnored1 Ignored.
139 * @param uIgnored2 Ignored.
140 */
141static int rtmpOnAllSolarisWrapper(void *uArg, void *uIgnored1, void *uIgnored2)
142{
143 PRTMPARGS pArgs = (PRTMPARGS)(uArg);
144
145 pArgs->pfnWorker(RTMpCpuId(), pArgs->pvUser1, pArgs->pvUser2);
146
147 NOREF(uIgnored1);
148 NOREF(uIgnored2);
149 return 0;
150}
151
152
153RTDECL(int) RTMpOnAll(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
154{
155 RTMPARGS Args;
156
157 Args.pfnWorker = pfnWorker;
158 Args.pvUser1 = pvUser1;
159 Args.pvUser2 = pvUser2;
160 Args.idCpu = NIL_RTCPUID;
161 Args.cHits = 0;
162
163 vbi_preempt_disable();
164
165 vbi_execute_on_all(rtmpOnAllSolarisWrapper, &Args);
166
167 vbi_preempt_enable();
168
169 return VINF_SUCCESS;
170}
171
172
173/**
174 * Wrapper between the native solaris per-cpu callback and PFNRTWORKER
175 * for the RTMpOnOthers API.
176 *
177 * @param uArgs Pointer to the RTMPARGS package.
178 * @param uIgnored1 Ignored.
179 * @param uIgnored2 Ignored.
180 */
181static int rtmpOnOthersSolarisWrapper(void *uArg, void *uIgnored1, void *uIgnored2)
182{
183 PRTMPARGS pArgs = (PRTMPARGS)(uArg);
184 RTCPUID idCpu = RTMpCpuId();
185
186 Assert(idCpu != pArgs->idCpu);
187 pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
188
189 NOREF(uIgnored1);
190 NOREF(uIgnored2);
191 return 0;
192}
193
194
195RTDECL(int) RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
196{
197 int rc;
198 RTMPARGS Args;
199
200 Args.pfnWorker = pfnWorker;
201 Args.pvUser1 = pvUser1;
202 Args.pvUser2 = pvUser2;
203 Args.idCpu = RTMpCpuId(); /** @todo should disable pre-emption before doing this.... */
204 Args.cHits = 0;
205
206 /* HERE JOE - this looks broken, explain to Knut */
207 vbi_preempt_disable();
208
209 vbi_execute_on_others(rtmpOnOthersSolarisWrapper, &Args);
210
211 vbi_preempt_enable();
212
213 return VINF_SUCCESS;
214}
215
216
217/**
218 * Wrapper between the native solaris per-cpu callback and PFNRTWORKER
219 * for the RTMpOnSpecific API.
220 *
221 *
222 * @param uArgs Pointer to the RTMPARGS package.
223 * @param uIgnored1 Ignored.
224 * @param uIgnored2 Ignored.
225 */
226static int rtmpOnSpecificSolarisWrapper(void *uArg, void *uIgnored1, void *uIgnored2)
227{
228 PRTMPARGS pArgs = (PRTMPARGS)(uArg);
229 RTCPUID idCpu = RTMpCpuId();
230
231 Assert(idCpu == pArgs->idCpu);
232 pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
233 ASMAtomicIncU32(&pArgs->cHits);
234
235 NOREF(uIgnored1);
236 NOREF(uIgnored2);
237 return 0;
238}
239
240
241RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
242{
243 int rc;
244 RTMPARGS Args;
245
246 if (idCpu >= vbi_cpu_count())
247 return VERR_CPU_NOT_FOUND;
248
249 Args.pfnWorker = pfnWorker;
250 Args.pvUser1 = pvUser1;
251 Args.pvUser2 = pvUser2;
252 Args.idCpu = idCpu;
253 Args.cHits = 0;
254
255 /* TBD HERE JOE again.. perhaps broken */
256 vbi_preempt_disable();
257
258 vbi_execute_on_one(rtmpOnSpecificSolarisWrapper, &Args, idCpu);
259
260 vbi_preempt_enable();
261
262 Assert(ASMAtomicUoReadU32(&Args.cHits) <= 1);
263
264 return ASMAtomicUoReadU32(&Args.cHits) == 1
265 ? VINF_SUCCESS
266 : VERR_CPU_NOT_FOUND;
267}
268
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