mp-solaris.cpp revision 1f942a68581d7c1b72d28bf52355dc6cb3cae4c6
537680a235921a9a53f5040185a15cdcf228c217vboxsync * IPRT - Multiprocessor, Solaris.
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2008-2012 Oracle Corporation
537680a235921a9a53f5040185a15cdcf228c217vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
537680a235921a9a53f5040185a15cdcf228c217vboxsync * available from http://www.virtualbox.org. This file is free software;
537680a235921a9a53f5040185a15cdcf228c217vboxsync * you can redistribute it and/or modify it under the terms of the GNU
537680a235921a9a53f5040185a15cdcf228c217vboxsync * General Public License (GPL) as published by the Free Software
537680a235921a9a53f5040185a15cdcf228c217vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
537680a235921a9a53f5040185a15cdcf228c217vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
537680a235921a9a53f5040185a15cdcf228c217vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
537680a235921a9a53f5040185a15cdcf228c217vboxsync * The contents of this file may alternatively be used under the terms
537680a235921a9a53f5040185a15cdcf228c217vboxsync * of the Common Development and Distribution License Version 1.0
537680a235921a9a53f5040185a15cdcf228c217vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
537680a235921a9a53f5040185a15cdcf228c217vboxsync * VirtualBox OSE distribution, in which case the provisions of the
537680a235921a9a53f5040185a15cdcf228c217vboxsync * CDDL are applicable instead of those of the GPL.
537680a235921a9a53f5040185a15cdcf228c217vboxsync * You may elect to license modified versions of this file under the
537680a235921a9a53f5040185a15cdcf228c217vboxsync * terms and conditions of either the GPL or the CDDL or both.
537680a235921a9a53f5040185a15cdcf228c217vboxsync/*******************************************************************************
537680a235921a9a53f5040185a15cdcf228c217vboxsync* Header Files *
537680a235921a9a53f5040185a15cdcf228c217vboxsync*******************************************************************************/
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync/*******************************************************************************
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync* Global Variables *
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync*******************************************************************************/
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync/** Initialization serializing (rtMpSolarisOnce). */
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync/** Critical section serializing access to kstat. */
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync/** The kstat handle. */
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync/** Array pointing to the cpu_info instances. */
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync/** The number of entries in g_papCpuInfo */
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync * Run once function that initializes the kstats we need here.
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync * @returns IPRT status code.
a438caaf732f7839dc66b4f8dad672527845a003vboxsync * @param pvUser Unused.
a438caaf732f7839dc66b4f8dad672527845a003vboxsyncstatic DECLCALLBACK(int) rtMpSolarisOnce(void *pvUser)
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync * Open kstat and find the cpu_info entries for each of the CPUs.
6ae948500828abfb01b923bb81950f44bde0dfc5vboxsync g_papCpuInfo = (kstat_t **)RTMemAllocZ(g_capCpuInfo * sizeof(kstat_t *));
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync for (kstat_t *pKsp = g_pKsCtl->kc_chain; pKsp != NULL; pKsp = pKsp->ks_next)
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync /** @todo ks_instance == cpu_id (/usr/src/uts/common/os/cpu.c)? Check this and fix it ASAP. */
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync /* bail out, we failed. */
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync * Worker for RTMpGetCurFrequency and RTMpGetMaxFrequency.
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync * @returns The desired frequency on success, 0 on failure.
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync * @param idCpu The CPU ID.
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync * @param pszStatName The cpu_info stat name.
1f942a68581d7c1b72d28bf52355dc6cb3cae4c6vboxsyncstatic uint64_t rtMpSolarisGetFrequency(RTCPUID idCpu, const char *pszStatName)
a438caaf732f7839dc66b4f8dad672527845a003vboxsync int rc = RTOnce(&g_MpSolarisOnce, rtMpSolarisOnce, NULL);
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync if (kstat_read(g_pKsCtl, g_papCpuInfo[idCpu], 0) != -1)
1f942a68581d7c1b72d28bf52355dc6cb3cae4c6vboxsync kstat_named_t *pStat = (kstat_named_t *)kstat_data_lookup(g_papCpuInfo[idCpu], (char*)pszStatName);
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync Assert(pStat->data_type == KSTAT_DATA_UINT64 || pStat->data_type == KSTAT_DATA_LONG);
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync case KSTAT_DATA_UINT64: u64 = pStat->value.ui64; break; /* current_clock_Hz */
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync case KSTAT_DATA_INT32: u64 = pStat->value.i32; break; /* clock_MHz */
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync /* just in case... */
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync case KSTAT_DATA_UINT32: u64 = pStat->value.ui32; break;
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync case KSTAT_DATA_INT64: u64 = pStat->value.i64; break;
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync Log(("kstat_data_lookup(%s) -> %d\n", pszStatName, errno));
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync Log(("invalid idCpu: %d (g_capCpuInfo=%d)\n", (int)idCpu, (int)g_capCpuInfo));
1f942a68581d7c1b72d28bf52355dc6cb3cae4c6vboxsync /* Solaris really need to fix their APIs. */
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync return rtMpSolarisGetFrequency(idCpu, "current_clock_Hz") / 1000000;
148b03bcfa337a0e994b1f7297662c972b77ac3avboxsync return rtMpSolarisGetFrequency(idCpu, "clock_MHz");
f6aff34d987eb8063700c4c26456df4e70f3721cvboxsync#if defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
f6aff34d987eb8063700c4c26456df4e70f3721cvboxsync /** @todo implement RTMpCpuId on solaris/r3! */
6bd18639c3cba30caeea5bc4fa2fe87de208c708vboxsync return idCpu < RTCPUSET_MAX_CPUS ? (int)idCpu : -1;
b929f4d04ad2a9b1cf968da876979367430c5efavboxsync return (unsigned)iCpu < RTCPUSET_MAX_CPUS ? iCpu : NIL_RTCPUID;
7153a94e631ff3ba3ae93aa08299b4819cbd1501vboxsync * Solaris has sysconf.
b9f55d08827aba9a80f57ca6af945abf6b725abcvboxsync while (idCpu-- > 0)
7153a94e631ff3ba3ae93aa08299b4819cbd1501vboxsync * Solaris has sysconf.
e7fd455c7cf734fefff2b0bd4c620eebe2ce3777vboxsync * Solaris has sysconf.