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