VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/testcase/tstSupTscDelta.cpp@ 54287

Last change on this file since 54287 was 54287, checked in by vboxsync, 10 years ago

tstSupTscDelta.cpp: Hacked up a testcase for repeatedly remeasure the tsc deltas..

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.9 KB
Line 
1/* $Id: tstSupTscDelta.cpp 54287 2015-02-18 23:39:57Z vboxsync $ */
2/** @file
3 * SUP Testcase - Global Info Page TSC Delta Measurement Utility.
4 */
5
6/*
7 * Copyright (C) 2015 Oracle Corporation
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* Header Files *
29*******************************************************************************/
30#include <VBox/sup.h>
31#include <VBox/err.h>
32#include <iprt/assert.h>
33#include <iprt/stream.h>
34#include <iprt/string.h>
35#include <iprt/getopt.h>
36#include <iprt/test.h>
37#include <iprt/thread.h>
38
39
40
41int main(int argc, char **argv)
42{
43 RTTEST hTest;
44 RTEXITCODE rcExit = RTTestInitExAndCreate(argc, &argv, 0 /*fRtInit*/, "tstSupTscDelta", &hTest);
45 if (rcExit != RTEXITCODE_SUCCESS)
46 return rcExit;
47
48 /*
49 * Parse args
50 */
51 static const RTGETOPTDEF g_aOptions[] =
52 {
53 { "--iterations", 'i', RTGETOPT_REQ_INT32 },
54 };
55
56 uint32_t cIterations = 0; /* Currently 0 so that it doesn't upset testing. */
57
58 int ch;
59 RTGETOPTUNION ValueUnion;
60 RTGETOPTSTATE GetState;
61 RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
62 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
63 {
64 switch (ch)
65 {
66 case 'i':
67 cIterations = ValueUnion.u32;
68 break;
69
70 default:
71 return RTGetOptPrintError(ch, &ValueUnion);
72 }
73 }
74 if (!cIterations)
75 return RTTestSkipAndDestroy(hTest, "Nothing to do. The --iterations argument is 0 or not given.");
76
77 /*
78 * Init
79 */
80 PSUPDRVSESSION pSession = NIL_RTR0PTR;
81 int rc = SUPR3Init(&pSession);
82 if (RT_SUCCESS(rc))
83 {
84 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
85 if (pGip)
86 {
87 if (pGip->enmUseTscDelta < SUPGIPUSETSCDELTA_PRACTICALLY_ZERO)
88 return RTTestSkipAndDestroy(hTest, "No deltas to play with: enmUseTscDelta=%d\n", pGip->enmUseTscDelta);
89
90 struct
91 {
92 int64_t iLowest;
93 int64_t iHighest;
94 int64_t iTotal;
95 uint64_t uAbsMin;
96 uint64_t uAbsMax;
97 uint64_t uAbsTotal;
98 } aCpuStats[RTCPUSET_MAX_CPUS];
99 RT_ZERO(aCpuStats);
100
101 for (uint32_t iIteration = 0; ; iIteration++)
102 {
103 /*
104 * Display the current deltas and gather statistics.
105 */
106 RTPrintf("tstSupTscDelta: Iteration #%u results:", iIteration);
107 for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++)
108 {
109 int64_t iTscDelta = pGip->aCPUs[iCpu].i64TSCDelta;
110
111 /* print */
112 if ((iCpu % 4) == 0)
113 RTPrintf("\ntstSupTscDelta:");
114 if (pGip->aCPUs[iCpu].enmState != SUPGIPCPUSTATE_ONLINE)
115 RTPrintf(" %02x: offline ", iCpu, iTscDelta);
116 else if (iTscDelta != INT64_MAX)
117 RTPrintf(" %02x: %-12lld", iCpu, iTscDelta);
118 else
119 RTPrintf(" %02x: INT64_MAX ", iCpu);
120
121 /* stats */
122 if ( iTscDelta != INT64_MAX
123 && pGip->aCPUs[iCpu].enmState == SUPGIPCPUSTATE_ONLINE)
124 {
125 if (aCpuStats[iCpu].iLowest > iTscDelta)
126 aCpuStats[iCpu].iLowest = iTscDelta;
127 if (aCpuStats[iCpu].iHighest < iTscDelta)
128 aCpuStats[iCpu].iHighest = iTscDelta;
129 aCpuStats[iCpu].iTotal += iTscDelta;
130
131 uint64_t uAbsTscDelta = iTscDelta >= 0 ? (uint64_t)iTscDelta : (uint64_t)-iTscDelta;
132 if (aCpuStats[iCpu].uAbsMin > uAbsTscDelta)
133 aCpuStats[iCpu].uAbsMin = uAbsTscDelta;
134 if (aCpuStats[iCpu].uAbsMax < uAbsTscDelta)
135 aCpuStats[iCpu].uAbsMax = uAbsTscDelta;
136 aCpuStats[iCpu].uAbsTotal += uAbsTscDelta;
137 }
138 }
139 if (((pGip->cCpus - 1) % 4) != 0)
140 RTPrintf("\n");
141
142 /*
143 * Done?
144 */
145 if (iIteration + 1 >= cIterations)
146 break;
147
148 /*
149 * Force a new measurement.
150 */
151 RTThreadSleep(16);
152 for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++)
153 if (pGip->aCPUs[iCpu].enmState == SUPGIPCPUSTATE_ONLINE)
154 {
155 rc = SUPR3TscDeltaMeasure(pGip->aCPUs[iCpu].idCpu, false /*fAsync*/, true /*fForce*/, 64, 16 /*ms*/);
156 if (RT_FAILURE(rc))
157 RTTestFailed(hTest, "SUPR3TscDeltaMeasure failed on %#x: %Rrc", pGip->aCPUs[iCpu].idCpu, rc);
158 }
159 }
160
161 /*
162 * Display statistics that we've gathered.
163 */
164 RTPrintf("tstSupTscDelta: Results:\n");
165 int64_t iLowest = 0;
166 int64_t iHighest = 0;
167 int64_t iTotal = 0;
168 uint32_t cTotal = 0;
169 for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++)
170 {
171 if (pGip->aCPUs[iCpu].enmState != SUPGIPCPUSTATE_ONLINE)
172 RTPrintf("tstSupTscDelta: %02x: offline\n", iCpu);
173 else
174 {
175 RTPrintf("tstSupTscDelta: %02x: lowest=%-12lld highest=%-12lld average=%-12lld spread=%-12lld\n",
176 iCpu,
177 aCpuStats[iCpu].iLowest,
178 aCpuStats[iCpu].iHighest,
179 aCpuStats[iCpu].iTotal / cIterations,
180 aCpuStats[iCpu].iHighest - aCpuStats[iCpu].iLowest);
181 RTPrintf( "tstSupTscDelta: absmin=%-12llu absmax=%-12llu absavg=%-12llu\n",
182 aCpuStats[iCpu].uAbsMin,
183 aCpuStats[iCpu].uAbsMax,
184 aCpuStats[iCpu].uAbsTotal / cIterations);
185 if (iLowest > aCpuStats[iCpu].iLowest)
186 iLowest = aCpuStats[iCpu].iLowest;
187 if (iHighest < aCpuStats[iCpu].iHighest)
188 iHighest = aCpuStats[iCpu].iHighest;
189 iTotal += aCpuStats[iCpu].iHighest;
190 cTotal += cIterations;
191 }
192 }
193 RTPrintf("tstSupTscDelta: all: lowest=%-12lld highest=%-12lld average=%-12lld spread=%-12lld\n",
194 iLowest, iHighest, iTotal / cTotal, iHighest - iLowest);
195 }
196 else
197 RTTestFailed(hTest, "g_pSUPGlobalInfoPage is NULL");
198
199 SUPR3Term(false /*fForced*/);
200 }
201 else
202 RTTestFailed(hTest, "SUPR3Init failed: %Rrc", rc);
203 return RTTestSummaryAndDestroy(hTest);
204}
205
206
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