VirtualBox

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

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

tstSupTscDelta.cpp: added --delay <ms> option.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1/* $Id: tstSupTscDelta.cpp 54346 2015-02-20 21:30:40Z 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 { "--delay", 'd', RTGETOPT_REQ_INT32 },
55 };
56
57 uint32_t cIterations = 0; /* Currently 0 so that it doesn't upset testing. */
58 uint32_t cMsSleepBetweenIterations = 10;
59
60 int ch;
61 RTGETOPTUNION ValueUnion;
62 RTGETOPTSTATE GetState;
63 RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
64 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
65 {
66 switch (ch)
67 {
68 case 'd':
69 cMsSleepBetweenIterations = ValueUnion.u32;
70 break;
71 case 'i':
72 cIterations = ValueUnion.u32;
73 break;
74
75 default:
76 return RTGetOptPrintError(ch, &ValueUnion);
77 }
78 }
79 if (!cIterations)
80 return RTTestSkipAndDestroy(hTest, "Nothing to do. The --iterations argument is 0 or not given.");
81
82 /*
83 * Init
84 */
85 PSUPDRVSESSION pSession = NIL_RTR0PTR;
86 int rc = SUPR3Init(&pSession);
87 if (RT_SUCCESS(rc))
88 {
89 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
90 if (pGip)
91 {
92 if (pGip->enmUseTscDelta < SUPGIPUSETSCDELTA_PRACTICALLY_ZERO)
93 return RTTestSkipAndDestroy(hTest, "No deltas to play with: enmUseTscDelta=%d\n", pGip->enmUseTscDelta);
94
95 /*
96 * Init stats.
97 */
98 struct
99 {
100 int64_t iLowest;
101 int64_t iHighest;
102 int64_t iTotal;
103 uint64_t uAbsMin;
104 uint64_t uAbsMax;
105 uint64_t uAbsTotal;
106 } aCpuStats[RTCPUSET_MAX_CPUS];
107 RT_ZERO(aCpuStats);
108 for (uint32_t i = 0; i < pGip->cCpus; i++)
109 {
110 aCpuStats[i].iLowest = INT64_MAX;
111 aCpuStats[i].iHighest = INT64_MIN;
112 aCpuStats[i].uAbsMin = UINT64_MAX;
113 }
114
115 /*
116 * Do the work.
117 */
118 for (uint32_t iIteration = 0; ; iIteration++)
119 {
120 /*
121 * Display the current deltas and gather statistics.
122 */
123 RTPrintf("tstSupTscDelta: Iteration #%u results:", iIteration);
124 for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++)
125 {
126 int64_t iTscDelta = pGip->aCPUs[iCpu].i64TSCDelta;
127
128 /* print */
129 if ((iCpu % 4) == 0)
130 RTPrintf("\ntstSupTscDelta:");
131 if (pGip->aCPUs[iCpu].enmState != SUPGIPCPUSTATE_ONLINE)
132 RTPrintf(" %02x: offline ", iCpu, iTscDelta);
133 else if (iTscDelta != INT64_MAX)
134 RTPrintf(" %02x: %-12lld", iCpu, iTscDelta);
135 else
136 RTPrintf(" %02x: INT64_MAX ", iCpu);
137
138 /* stats */
139 if ( iTscDelta != INT64_MAX
140 && pGip->aCPUs[iCpu].enmState == SUPGIPCPUSTATE_ONLINE)
141 {
142 if (aCpuStats[iCpu].iLowest > iTscDelta)
143 aCpuStats[iCpu].iLowest = iTscDelta;
144 if (aCpuStats[iCpu].iHighest < iTscDelta)
145 aCpuStats[iCpu].iHighest = iTscDelta;
146 aCpuStats[iCpu].iTotal += iTscDelta;
147
148 uint64_t uAbsTscDelta = iTscDelta >= 0 ? (uint64_t)iTscDelta : (uint64_t)-iTscDelta;
149 if (aCpuStats[iCpu].uAbsMin > uAbsTscDelta)
150 aCpuStats[iCpu].uAbsMin = uAbsTscDelta;
151 if (aCpuStats[iCpu].uAbsMax < uAbsTscDelta)
152 aCpuStats[iCpu].uAbsMax = uAbsTscDelta;
153 aCpuStats[iCpu].uAbsTotal += uAbsTscDelta;
154 }
155 }
156 if (((pGip->cCpus - 1) % 4) != 0)
157 RTPrintf("\n");
158
159 /*
160 * Done?
161 */
162 if (iIteration + 1 >= cIterations)
163 break;
164
165 /*
166 * Force a new measurement.
167 */
168 RTThreadSleep(cMsSleepBetweenIterations);
169 for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++)
170 if (pGip->aCPUs[iCpu].enmState == SUPGIPCPUSTATE_ONLINE)
171 {
172 rc = SUPR3TscDeltaMeasure(pGip->aCPUs[iCpu].idCpu, false /*fAsync*/, true /*fForce*/, 64, 16 /*ms*/);
173 if (RT_FAILURE(rc))
174 RTTestFailed(hTest, "SUPR3TscDeltaMeasure failed on %#x: %Rrc", pGip->aCPUs[iCpu].idCpu, rc);
175 }
176 }
177
178 /*
179 * Display statistics that we've gathered.
180 */
181 RTPrintf("tstSupTscDelta: Results:\n");
182 int64_t iLowest = INT64_MAX;
183 int64_t iHighest = INT64_MIN;
184 int64_t iTotal = 0;
185 uint32_t cTotal = 0;
186 for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++)
187 {
188 if (pGip->aCPUs[iCpu].enmState != SUPGIPCPUSTATE_ONLINE)
189 RTPrintf("tstSupTscDelta: %02x: offline\n", iCpu);
190 else
191 {
192 RTPrintf("tstSupTscDelta: %02x: lowest=%-12lld highest=%-12lld average=%-12lld spread=%-12lld\n",
193 iCpu,
194 aCpuStats[iCpu].iLowest,
195 aCpuStats[iCpu].iHighest,
196 aCpuStats[iCpu].iTotal / cIterations,
197 aCpuStats[iCpu].iHighest - aCpuStats[iCpu].iLowest);
198 RTPrintf( "tstSupTscDelta: absmin=%-12llu absmax=%-12llu absavg=%-12llu idCpu=%#4x idApic=%#4x\n",
199 aCpuStats[iCpu].uAbsMin,
200 aCpuStats[iCpu].uAbsMax,
201 aCpuStats[iCpu].uAbsTotal / cIterations,
202 pGip->aCPUs[iCpu].idCpu,
203 pGip->aCPUs[iCpu].idApic);
204 if (iLowest > aCpuStats[iCpu].iLowest)
205 iLowest = aCpuStats[iCpu].iLowest;
206 if (iHighest < aCpuStats[iCpu].iHighest)
207 iHighest = aCpuStats[iCpu].iHighest;
208 iTotal += aCpuStats[iCpu].iHighest;
209 cTotal += cIterations;
210 }
211 }
212 RTPrintf("tstSupTscDelta: all: lowest=%-12lld highest=%-12lld average=%-12lld spread=%-12lld\n",
213 iLowest, iHighest, iTotal / cTotal, iHighest - iLowest);
214 }
215 else
216 RTTestFailed(hTest, "g_pSUPGlobalInfoPage is NULL");
217
218 SUPR3Term(false /*fForced*/);
219 }
220 else
221 RTTestFailed(hTest, "SUPR3Init failed: %Rrc", rc);
222 return RTTestSummaryAndDestroy(hTest);
223}
224
225
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