tstTSC.cpp revision 7043865c42bccb88eabf015de27b029ef057ed82
46f059bea92bedbd395793702c73946ead235586vboxsync * IPRT Testcase - SMP TSC testcase.
46f059bea92bedbd395793702c73946ead235586vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
46f059bea92bedbd395793702c73946ead235586vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
46f059bea92bedbd395793702c73946ead235586vboxsync * available from http://www.virtualbox.org. This file is free software;
46f059bea92bedbd395793702c73946ead235586vboxsync * you can redistribute it and/or modify it under the terms of the GNU
46f059bea92bedbd395793702c73946ead235586vboxsync * General Public License (GPL) as published by the Free Software
46f059bea92bedbd395793702c73946ead235586vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * The contents of this file may alternatively be used under the terms
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * of the Common Development and Distribution License Version 1.0
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution, in which case the provisions of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * CDDL are applicable instead of those of the GPL.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * You may elect to license modified versions of this file under the
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * terms and conditions of either the GPL or the CDDL or both.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
46f059bea92bedbd395793702c73946ead235586vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
46f059bea92bedbd395793702c73946ead235586vboxsync * additional information or have any questions.
46f059bea92bedbd395793702c73946ead235586vboxsync/*******************************************************************************
46f059bea92bedbd395793702c73946ead235586vboxsync* Header Files *
46f059bea92bedbd395793702c73946ead235586vboxsync*******************************************************************************/
46f059bea92bedbd395793702c73946ead235586vboxsync/*******************************************************************************
46f059bea92bedbd395793702c73946ead235586vboxsync* Structures and Typedefs *
46f059bea92bedbd395793702c73946ead235586vboxsync*******************************************************************************/
46f059bea92bedbd395793702c73946ead235586vboxsynctypedef struct TSCDATA
46f059bea92bedbd395793702c73946ead235586vboxsync /** The TSC. */
46f059bea92bedbd395793702c73946ead235586vboxsync /** The APIC ID. */
46f059bea92bedbd395793702c73946ead235586vboxsync /** Did it succeed? */
46f059bea92bedbd395793702c73946ead235586vboxsync bool volatile fRead;
46f059bea92bedbd395793702c73946ead235586vboxsync /** Did it fail? */
46f059bea92bedbd395793702c73946ead235586vboxsync bool volatile fFailed;
46f059bea92bedbd395793702c73946ead235586vboxsync /** The thread handle. */
46f059bea92bedbd395793702c73946ead235586vboxsync/*******************************************************************************
46f059bea92bedbd395793702c73946ead235586vboxsync* Global Variables *
46f059bea92bedbd395793702c73946ead235586vboxsync*******************************************************************************/
46f059bea92bedbd395793702c73946ead235586vboxsync/** The number of CPUs waiting on their user event semaphore. */
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync/** The number of CPUs ready (in spin) to do the TSC read. */
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync/** The variable the CPUs are spinning on.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * 1: Go ahead.
46f059bea92bedbd395793702c73946ead235586vboxsync * 2: You're too late, back to square one. */
46f059bea92bedbd395793702c73946ead235586vboxsync/** The number of CPUs that managed to read the TSC. */
46f059bea92bedbd395793702c73946ead235586vboxsync/** The number of CPUs that failed to read the TSC. */
46f059bea92bedbd395793702c73946ead235586vboxsync/** Indicator forcing the threads to quit. */
46f059bea92bedbd395793702c73946ead235586vboxsyncstatic volatile bool g_fDone;
46f059bea92bedbd395793702c73946ead235586vboxsync/*******************************************************************************
46f059bea92bedbd395793702c73946ead235586vboxsync* Internal Functions *
46f059bea92bedbd395793702c73946ead235586vboxsync*******************************************************************************/
46f059bea92bedbd395793702c73946ead235586vboxsyncstatic DECLCALLBACK(int) ThreadFunction(RTTHREAD Thread, void *pvUser);
46f059bea92bedbd395793702c73946ead235586vboxsync * Thread function for catching the other cpus.
46f059bea92bedbd395793702c73946ead235586vboxsync * @returns VINF_SUCCESS (we don't care).
46f059bea92bedbd395793702c73946ead235586vboxsync * @param Thread The thread handle.
46f059bea92bedbd395793702c73946ead235586vboxsync * @param pvUser PTSCDATA.
46f059bea92bedbd395793702c73946ead235586vboxsyncstatic DECLCALLBACK(int) ThreadFunction(RTTHREAD Thread, void *pvUser)
46f059bea92bedbd395793702c73946ead235586vboxsync /* do the reading. */
46f059bea92bedbd395793702c73946ead235586vboxsync && TSC3 - TSC1 < 2250 /* WARNING: This is just a guess, increase if it doesn't work for you. */
46f059bea92bedbd395793702c73946ead235586vboxsync /* succeeded. */
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync /* failed */
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * This is only relevant to on SMP systems.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync RTPrintf("tstTSC: SKIPPED - Only relevant on SMP systems\n");
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * Create the threads.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync RTPrintf("tstTSC: FAILED - too many CPUs (%u)\n", cCpus);
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync /* ourselves. */
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync /* the others */
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync int rc = RTThreadCreate(&s_aData[i].Thread, ThreadFunction, &s_aData[i], 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "OTHERCPU");
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync RTPrintf("tstTSC: FAILURE - RTThreatCreate failed when creating thread #%u, rc=%Rrc!\n", i, rc);
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync while (i-- > 1)
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * Retry untill we get lucky (or give up).
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync RTPrintf("tstTSC: FAILURE - %d attempts, giving.\n", cTries);
57134cc31d26d91192e87a4541b4f82fbdb2c297vboxsync * Wait for the other threads to get ready (brute force active wait, I'm lazy).
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync RTPrintf("tstTSC: FAILURE - threads failed to get waiting (%d != %d (i=%d))\n", g_cWaiting + 1, cCpus, i);
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync * Send them spinning.
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync RTPrintf("tstTSC: WARNING - RTThreadUserSignal(%#u) -> rc=%Rrc!\n", i, rc);
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync /* wait for them to get ready. */
46f059bea92bedbd395793702c73946ead235586vboxsync RTPrintf("tstTSC: FAILURE - threads failed to get ready (%d != %d, i=%d)\n", g_cWaiting + 1, cCpus, i);
46f059bea92bedbd395793702c73946ead235586vboxsync * Flip the "go" switch and do our readings.
46f059bea92bedbd395793702c73946ead235586vboxsync * We give the other threads the slack it takes to two extra TSC and APIC ID reads.
46f059bea92bedbd395793702c73946ead235586vboxsync /* Compose our own result. */
46f059bea92bedbd395793702c73946ead235586vboxsync && TSC5 - TSC1 < 2750 /* WARNING: This is just a guess, increase if it doesn't work for you. */
df2e37f58f19997178bb9be53867a17509a3a2f9vboxsync /* succeeded. */
46f059bea92bedbd395793702c73946ead235586vboxsync /* failed */
if (i++ > _2G32)
if (i > _1M)
RTPrintf("tstTSC: FAILURE - threads failed to complete reading (%d + %d != %d)\n", g_cRead, g_cFailed, cCpus);
if (!g_cFailed)
bool fDone;
fDone = false;
} while (!fDone);
for (i = 0; i < cCpus; i++)
for (i = 0; i < cCpus; i++)