EmulatorPkg/Unix/Host/EmuThunk.c | 40 +++++++++++++++++++++----------- EmulatorPkg/Win/Host/WinThunk.c | 10 +++++--- 2 files changed, 34 insertions(+), 16 deletions(-)
Implement QueryPerformanceCounter() and QueryPerformanceFrequency()
for both Unix and Windows.
This has been tested in both Unix and Windows in an application using
TimerLib.
Signed-off-by: Derek Lin <derek.lin2@hpe.com>
Signed-off-by: Kitty Chen <kitty.chen@hpe.com>
---
EmulatorPkg/Unix/Host/EmuThunk.c | 40 +++++++++++++++++++++-----------
EmulatorPkg/Win/Host/WinThunk.c | 10 +++++---
2 files changed, 34 insertions(+), 16 deletions(-)
diff --git a/EmulatorPkg/Unix/Host/EmuThunk.c b/EmulatorPkg/Unix/Host/EmuThunk.c
index 1e9dc99187..92703d3088 100644
--- a/EmulatorPkg/Unix/Host/EmuThunk.c
+++ b/EmulatorPkg/Unix/Host/EmuThunk.c
@@ -11,6 +11,7 @@
Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.<BR>
+(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -33,6 +34,7 @@ struct timeval settimer_timeval;
UINTN settimer_callback = 0;
BOOLEAN gEmulatorInterruptEnabled = FALSE;
+UINT64 mPerformanceFrequency = 0;
UINTN
@@ -236,16 +238,6 @@ SecInterruptEanbled (void)
return gEmulatorInterruptEnabled;
}
-
-UINT64
-QueryPerformanceFrequency (
- VOID
- )
-{
- // Hard code to nanoseconds
- return 1000000000ULL;
-}
-
UINT64
QueryPerformanceCounter (
VOID
@@ -274,12 +266,34 @@ QueryPerformanceCounter (
return (Start * sTimebaseInfo.numer) / sTimebaseInfo.denom;
#else
- // Need to figure out what to do for Linux?
- return 0;
+ int status;
+ struct timespec time;
+ status = clock_gettime(CLOCK_REALTIME, &time);
+ return MultU64x32 (time.tv_sec, 1000000000) + time.tv_nsec;
+
#endif
}
-
+UINT64
+QueryPerformanceFrequency (
+ VOID
+ )
+{
+ UINT64 Counter1;
+ UINT64 Counter2;
+ if (mPerformanceFrequency) {
+ return mPerformanceFrequency;
+ }
+ //
+ // Don't know how to query performance frequency in Linux,
+ // so instead, sleep 0.1 second and calculate it.
+ //
+ Counter1 = QueryPerformanceCounter();
+ SecSleep (100* 1000 * 1000);
+ Counter2 = QueryPerformanceCounter();
+ mPerformanceFrequency = (Counter2-Counter1) * 10;
+ return mPerformanceFrequency;
+}
VOID
SecSleep (
diff --git a/EmulatorPkg/Win/Host/WinThunk.c b/EmulatorPkg/Win/Host/WinThunk.c
index a77be2a64b..41b5cffe18 100644
--- a/EmulatorPkg/Win/Host/WinThunk.c
+++ b/EmulatorPkg/Win/Host/WinThunk.c
@@ -1,6 +1,7 @@
/**@file
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
Module Name:
@@ -438,8 +439,9 @@ SecQueryPerformanceFrequency (
VOID
)
{
- // Hard code to nanoseconds
- return 1000000000ULL;
+ UINT64 Frequency;
+ QueryPerformanceFrequency ((LARGE_INTEGER *) &Frequency);
+ return Frequency;
}
UINT64
@@ -447,7 +449,9 @@ SecQueryPerformanceCounter (
VOID
)
{
- return 0;
+ UINT64 PerformanceCount;
+ QueryPerformanceCounter ((LARGE_INTEGER *) &PerformanceCount);
+ return PerformanceCount;
}
--
2.17.0.windows.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#53565): https://edk2.groups.io/g/devel/message/53565
Mute This Topic: https://groups.io/mt/70266535/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Hi Derik, The Linux service clock_gettime() returns a structure with seconds and nanoseconds and you are retuning the number of nanoseconds from QueryPerformanceCounter(). Doesn't that imply that the rate of the performance counter is 1 ns? Does this allow you to remove the calibration code? Depending on the clock source used by clock_gettime(), there may be large jumps in the number of ns. You can use clock_getres() to see if the resolution is acceptable. It looks like clock_gettime() optionally supports other time sources that may be based on features such like TSC and those may require calibration. Mike > -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On > Behalf Of Lin, Derek (HPS SW) > Sent: Wednesday, January 29, 2020 11:12 PM > To: derek.lin2@hpe.com; devel@edk2.groups.io > Cc: Justen, Jordan L <jordan.l.justen@intel.com>; > afish@apple.com; Ni, Ray <ray.ni@intel.com>; Kitty Chen > <kitty.chen@hpe.com> > Subject: [edk2-devel] [PATCH] EmulatorPkg: TimerLib > QueryPerformance functions > > Implement QueryPerformanceCounter() and > QueryPerformanceFrequency() > for both Unix and Windows. > > This has been tested in both Unix and Windows in an > application using > TimerLib. > > Signed-off-by: Derek Lin <derek.lin2@hpe.com> > Signed-off-by: Kitty Chen <kitty.chen@hpe.com> > --- > EmulatorPkg/Unix/Host/EmuThunk.c | 40 > +++++++++++++++++++++----------- > EmulatorPkg/Win/Host/WinThunk.c | 10 +++++--- > 2 files changed, 34 insertions(+), 16 deletions(-) > > diff --git a/EmulatorPkg/Unix/Host/EmuThunk.c > b/EmulatorPkg/Unix/Host/EmuThunk.c > index 1e9dc99187..92703d3088 100644 > --- a/EmulatorPkg/Unix/Host/EmuThunk.c > +++ b/EmulatorPkg/Unix/Host/EmuThunk.c > @@ -11,6 +11,7 @@ > > Copyright (c) 2004 - 2019, Intel Corporation. All > rights reserved.<BR> > Portions copyright (c) 2008 - 2011, Apple Inc. All > rights reserved.<BR> > +(C) Copyright 2020 Hewlett Packard Enterprise > Development LP<BR> > SPDX-License-Identifier: BSD-2-Clause-Patent > > **/ > @@ -33,6 +34,7 @@ struct timeval settimer_timeval; > UINTN settimer_callback = 0; > > BOOLEAN gEmulatorInterruptEnabled = FALSE; > +UINT64 mPerformanceFrequency = 0; > > > UINTN > @@ -236,16 +238,6 @@ SecInterruptEanbled (void) > return gEmulatorInterruptEnabled; > } > > - > -UINT64 > -QueryPerformanceFrequency ( > - VOID > - ) > -{ > - // Hard code to nanoseconds > - return 1000000000ULL; > -} > - > UINT64 > QueryPerformanceCounter ( > VOID > @@ -274,12 +266,34 @@ QueryPerformanceCounter ( > > return (Start * sTimebaseInfo.numer) / > sTimebaseInfo.denom; > #else > - // Need to figure out what to do for Linux? > - return 0; > + int status; > + struct timespec time; > + status = clock_gettime(CLOCK_REALTIME, &time); > + return MultU64x32 (time.tv_sec, 1000000000) + > time.tv_nsec; > + > #endif > } > > - > +UINT64 > +QueryPerformanceFrequency ( > + VOID > + ) > +{ > + UINT64 Counter1; > + UINT64 Counter2; > + if (mPerformanceFrequency) { > + return mPerformanceFrequency; > + } > + // > + // Don't know how to query performance frequency in > Linux, > + // so instead, sleep 0.1 second and calculate it. > + // > + Counter1 = QueryPerformanceCounter(); > + SecSleep (100* 1000 * 1000); > + Counter2 = QueryPerformanceCounter(); > + mPerformanceFrequency = (Counter2-Counter1) * 10; > + return mPerformanceFrequency; > +} > > VOID > SecSleep ( > diff --git a/EmulatorPkg/Win/Host/WinThunk.c > b/EmulatorPkg/Win/Host/WinThunk.c > index a77be2a64b..41b5cffe18 100644 > --- a/EmulatorPkg/Win/Host/WinThunk.c > +++ b/EmulatorPkg/Win/Host/WinThunk.c > @@ -1,6 +1,7 @@ > /**@file > > Copyright (c) 2006 - 2018, Intel Corporation. All > rights reserved.<BR> > +(C) Copyright 2020 Hewlett Packard Enterprise > Development LP<BR> > SPDX-License-Identifier: BSD-2-Clause-Patent > > Module Name: > @@ -438,8 +439,9 @@ SecQueryPerformanceFrequency ( > VOID > ) > { > - // Hard code to nanoseconds > - return 1000000000ULL; > + UINT64 Frequency; > + QueryPerformanceFrequency ((LARGE_INTEGER *) > &Frequency); > + return Frequency; > } > > UINT64 > @@ -447,7 +449,9 @@ SecQueryPerformanceCounter ( > VOID > ) > { > - return 0; > + UINT64 PerformanceCount; > + QueryPerformanceCounter ((LARGE_INTEGER *) > &PerformanceCount); > + return PerformanceCount; > } > > > -- > 2.17.0.windows.1 > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#53589): https://edk2.groups.io/g/devel/message/53589 Mute This Topic: https://groups.io/mt/70266535/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2024 Red Hat, Inc.