Laszlo, The TimerLib already has the following API.
/** Converts elapsed ticks of performance counter to time in nanoseconds. This function converts the elapsed ticks of running performance counter to time value in unit of nanoseconds. @param Ticks The number of elapsed ticks of running performance counter. @return The elapsed time in nanoseconds. **/ UINT64 EFIAPI GetTimeInNanoSecond ( IN UINT64 Ticks ); I think a couple macros on top of this API could provide the microsecond and millisecond units. Mike > -----Original Message----- > From: Laszlo Ersek [mailto:[email protected]] > Sent: Wednesday, August 16, 2017 4:46 AM > To: Kinney, Michael D <[email protected]>; Gao, Liming > <[email protected]> > Cc: edk2-devel-01 <[email protected]> > Subject: TimerTickDiffLib for MdePkg? > > Hi, > > edk2 code frequently needs to calculate a time difference (in > nano-, > micro-, or milliseconds) between two timer tick values retrieved > with > TimerLib's GetPerformanceCounter() call. For performance > measurements, > PERF_START() and friends can be used, but in many contexts the > time > difference is needed for lower-level reasons. > > Such users can be enumerated by grepping for > GetPerformanceCounterProperties() call sites that pass in non- > NULL > parameters -- this is needed for interpreting wrap-arounds in > tick > values (direction and boundaries). I'm seeing a whole lot of > such call > sites. (And some call sites don't handle both directions of > counting.) > > I've written a very small library for centralizing this. While > I'm not > suggesting that existent code be rebased (although I'm also not > advising > against it), I think this library would be convenient for new > code. > > I don't think TimerLib should be extended with the new > (suggested) APIs. > There's a huge number of TimerLib instances (21 in my count), > and > replicating the implementation of the new APIs -- which are > totally > platform independent -- would defeat the whole exercise (which > is to > prevent code duplication). > > The library is currently for OvmfPkg only (in my local tree). > I'm > pasting the patch below. If there is interest, I could rework it > for > MdePkg. > > Thanks > Laszlo > > > commit f1963c7b1705c7e46ce369802d8c15f943a114d6 > > Author: Laszlo Ersek <[email protected]> > > Date: Tue Aug 8 22:46:47 2017 +0200 > > > > OvmfPkg: add TimerTickDiffLib > > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > Signed-off-by: Laszlo Ersek <[email protected]> > > > > diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec > > index 6a4c15c7917a..53a0a34d326d 100644 > > --- a/OvmfPkg/OvmfPkg.dec > > +++ b/OvmfPkg/OvmfPkg.dec > > @@ -60,6 +60,10 @@ [LibraryClasses] > > # > > HexDumpLib|Include/Library/HexDumpLib.h > > > > + ## @libraryclass Timer tick difference functions, to be > used with TimerLib. > > + # > > + TimerTickDiffLib|Include/Library/TimerTickDiffLib.h > > + > > [Guids] > > gUefiOvmfPkgTokenSpaceGuid = {0x93bb96af, 0xb9f2, > 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}} > > gEfiXenInfoGuid = {0xd3b46f3b, 0xd441, > 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}} > > diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc > > index 5b0461ff46b1..17f1db43f57d 100644 > > --- a/OvmfPkg/OvmfPkgIa32.dsc > > +++ b/OvmfPkg/OvmfPkgIa32.dsc > > @@ -97,6 +97,7 @@ [SkuIds] > > # > > > ################################################################ > ################ > > [LibraryClasses] > > + > TimerTickDiffLib|OvmfPkg/Library/TimerTickDiffLib/TimerTickDiffL > ib.inf > > HexDumpLib|OvmfPkg/Library/HexDumpLib/HexDumpLib.inf > > PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf > > TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf > > diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc > b/OvmfPkg/OvmfPkgIa32X64.dsc > > index 0ce3cbd3ebd0..924e17824760 100644 > > --- a/OvmfPkg/OvmfPkgIa32X64.dsc > > +++ b/OvmfPkg/OvmfPkgIa32X64.dsc > > @@ -102,6 +102,7 @@ [SkuIds] > > # > > > ################################################################ > ################ > > [LibraryClasses] > > + > TimerTickDiffLib|OvmfPkg/Library/TimerTickDiffLib/TimerTickDiffL > ib.inf > > HexDumpLib|OvmfPkg/Library/HexDumpLib/HexDumpLib.inf > > PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf > > TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf > > diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc > > index e7bdf8711b0f..d22384a26768 100644 > > --- a/OvmfPkg/OvmfPkgX64.dsc > > +++ b/OvmfPkg/OvmfPkgX64.dsc > > @@ -102,6 +102,7 @@ [SkuIds] > > # > > > ################################################################ > ################ > > [LibraryClasses] > > + > TimerTickDiffLib|OvmfPkg/Library/TimerTickDiffLib/TimerTickDiffL > ib.inf > > HexDumpLib|OvmfPkg/Library/HexDumpLib/HexDumpLib.inf > > PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf > > TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf > > diff --git > a/OvmfPkg/Library/TimerTickDiffLib/TimerTickDiffLib.inf > b/OvmfPkg/Library/TimerTickDiffLib/TimerTickDiffLib.inf > > new file mode 100644 > > index 000000000000..4d464565eb2f > > --- /dev/null > > +++ b/OvmfPkg/Library/TimerTickDiffLib/TimerTickDiffLib.inf > > @@ -0,0 +1,31 @@ > > +## @file > > +# Timer tick difference functions, to be used with TimerLib. > > +# > > +# Copyright (C) 2017, Red Hat, Inc. > > +# > > +# This program and the accompanying materials are licensed > and made available > > +# under the terms and conditions of the BSD License which > accompanies this > > +# distribution. The full text of the license may be found at > > +# http://opensource.org/licenses/bsd-license.php > > +# > > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS > IS" BASIS, WITHOUT > > +# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS > OR IMPLIED. > > +## > > + > > +[Defines] > > + INF_VERSION = 1.26 > > + BASE_NAME = TimerTickDiffLib > > + FILE_GUID = F1998AED-934F-4C96-AEFB- > 29C39FA62434 > > + MODULE_TYPE = BASE > > + VERSION_STRING = 1.0 > > + LIBRARY_CLASS = TimerTickDiffLib > > + > > +[Sources] > > + TimerTickDiffLib.c > > + > > +[Packages] > > + MdePkg/MdePkg.dec > > + > > +[LibraryClasses] > > + BaseLib > > + TimerLib > > diff --git a/OvmfPkg/Include/Library/TimerTickDiffLib.h > b/OvmfPkg/Include/Library/TimerTickDiffLib.h > > new file mode 100644 > > index 000000000000..40052e11b6ed > > --- /dev/null > > +++ b/OvmfPkg/Include/Library/TimerTickDiffLib.h > > @@ -0,0 +1,109 @@ > > +/** @file > > + Timer tick difference functions, to be used with TimerLib. > > + > > + Copyright (C) 2017, Red Hat, Inc. > > + > > + This program and the accompanying materials are licensed > and made available > > + under the terms and conditions of the BSD License which > accompanies this > > + distribution. The full text of the license may be found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS > IS" BASIS, WITHOUT > > + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS > OR IMPLIED. > > +**/ > > + > > +#ifndef __TIMER_TICK_DIFF_LIB_H__ > > +#define __TIMER_TICK_DIFF_LIB_H__ > > + > > +#include <Base.h> > > + > > +/** > > + From two values retrieved with TimerLib's > GetPerformanceCounter(), calculate > > + the number of ticks elapsed between them, such that the > difference can be > > + passed to TimerLib's GetTimeInNanoSecond(). > > + > > + The function cannot handle multiple wrap-arounds of the > performance counter. > > + > > + @param[in] PerfCounterStart The value returned by > GetPerformanceCounter(), > > + called earlier in wall clock > time. > > + > > + @param[in] PerfCounterStop The value returned by > GetPerformanceCounter(), > > + called later in wall clock > time. > > + > > + @retval The number of ticks corresponding to the > conceptual difference > > + (PerfCounterStop-PerfCounterStart). > > +**/ > > +UINT64 > > +EFIAPI > > +GetTickDifference ( > > + IN UINT64 PerfCounterStart, > > + IN UINT64 PerfCounterStop > > + ); > > + > > +/** > > + From two values retrieved with TimerLib's > GetPerformanceCounter(), calculate > > + the number of nanoseconds elapsed between them. > > + > > + The function cannot handle multiple wrap-arounds of the > performance counter. > > + > > + @param[in] PerfCounterStart The value returned by > GetPerformanceCounter(), > > + called earlier in wall clock > time. > > + > > + @param[in] PerfCounterStop The value returned by > GetPerformanceCounter(), > > + called later in wall clock > time. > > + > > + @retval The number of nanoseconds corresponding to the > conceptual difference > > + (PerfCounterStop-PerfCounterStart). > > +**/ > > +UINT64 > > +EFIAPI > > +GetNanoSecondDifference ( > > + IN UINT64 PerfCounterStart, > > + IN UINT64 PerfCounterStop > > + ); > > + > > +/** > > + From two values retrieved with TimerLib's > GetPerformanceCounter(), calculate > > + the number of microseconds elapsed between them. > > + > > + The function cannot handle multiple wrap-arounds of the > performance counter. > > + > > + @param[in] PerfCounterStart The value returned by > GetPerformanceCounter(), > > + called earlier in wall clock > time. > > + > > + @param[in] PerfCounterStop The value returned by > GetPerformanceCounter(), > > + called later in wall clock > time. > > + > > + @retval The number of microseconds corresponding to the > conceptual > > + difference (PerfCounterStop-PerfCounterStart). > > +**/ > > +UINT64 > > +EFIAPI > > +GetMicroSecondDifference ( > > + IN UINT64 PerfCounterStart, > > + IN UINT64 PerfCounterStop > > + ); > > + > > +/** > > + From two values retrieved with TimerLib's > GetPerformanceCounter(), calculate > > + the number of milliseconds elapsed between them. > > + > > + The function cannot handle multiple wrap-arounds of the > performance counter. > > + > > + @param[in] PerfCounterStart The value returned by > GetPerformanceCounter(), > > + called earlier in wall clock > time. > > + > > + @param[in] PerfCounterStop The value returned by > GetPerformanceCounter(), > > + called later in wall clock > time. > > + > > + @retval The number of milliseconds corresponding to the > conceptual > > + difference (PerfCounterStop-PerfCounterStart). > > +**/ > > +UINT64 > > +EFIAPI > > +GetMilliSecondDifference ( > > + IN UINT64 PerfCounterStart, > > + IN UINT64 PerfCounterStop > > + ); > > + > > +#endif > > diff --git > a/OvmfPkg/Library/TimerTickDiffLib/TimerTickDiffLib.c > b/OvmfPkg/Library/TimerTickDiffLib/TimerTickDiffLib.c > > new file mode 100644 > > index 000000000000..03ecae8200aa > > --- /dev/null > > +++ b/OvmfPkg/Library/TimerTickDiffLib/TimerTickDiffLib.c > > @@ -0,0 +1,178 @@ > > +/** @file > > + Timer tick difference functions, to be used with TimerLib. > > + > > + Copyright (C) 2017, Red Hat, Inc. > > + > > + This program and the accompanying materials are licensed > and made available > > + under the terms and conditions of the BSD License which > accompanies this > > + distribution. The full text of the license may be found at > > + http://opensource.org/licenses/bsd-license.php > > + > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS > IS" BASIS, WITHOUT > > + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS > OR IMPLIED. > > +**/ > > + > > +#include <Library/BaseLib.h> > > +#include <Library/TimerLib.h> > > + > > +/** > > + From two values retrieved with TimerLib's > GetPerformanceCounter(), calculate > > + the number of ticks elapsed between them, such that the > difference can be > > + passed to TimerLib's GetTimeInNanoSecond(). > > + > > + The function cannot handle multiple wrap-arounds of the > performance counter. > > + > > + @param[in] PerfCounterStart The value returned by > GetPerformanceCounter(), > > + called earlier in wall clock > time. > > + > > + @param[in] PerfCounterStop The value returned by > GetPerformanceCounter(), > > + called later in wall clock > time. > > + > > + @retval The number of ticks corresponding to the > conceptual difference > > + (PerfCounterStop-PerfCounterStart). > > +**/ > > +UINT64 > > +EFIAPI > > +GetTickDifference ( > > + IN UINT64 PerfCounterStart, > > + IN UINT64 PerfCounterStop > > + ) > > +{ > > + UINT64 StartValue; > > + UINT64 EndValue; > > + UINT64 TickDifference; > > + > > + GetPerformanceCounterProperties (&StartValue, &EndValue); > > + > > + if (StartValue < EndValue) { > > + // > > + // The performance counter counts up. > > + // > > + if (PerfCounterStart < PerfCounterStop) { > > + // > > + // The counter didn't wrap around. > > + // > > + TickDifference = PerfCounterStop - PerfCounterStart; > > + } else { > > + // > > + // The counter wrapped around. > > + // > > + TickDifference = (EndValue - PerfCounterStart) + > > + (PerfCounterStop - StartValue); > > + } > > + } else { > > + // > > + // The performance counter counts down. > > + // > > + if (PerfCounterStart < PerfCounterStop) { > > + // > > + // The counter wrapped around. > > + // > > + TickDifference = (PerfCounterStart - EndValue) + > > + (StartValue - PerfCounterStop); > > + } else { > > + // > > + // The counter didn't wrap around. > > + // > > + TickDifference = PerfCounterStart - PerfCounterStop; > > + } > > + } > > + > > + return TickDifference; > > +} > > + > > +/** > > + From two values retrieved with TimerLib's > GetPerformanceCounter(), calculate > > + the number of nanoseconds elapsed between them. > > + > > + The function cannot handle multiple wrap-arounds of the > performance counter. > > + > > + @param[in] PerfCounterStart The value returned by > GetPerformanceCounter(), > > + called earlier in wall clock > time. > > + > > + @param[in] PerfCounterStop The value returned by > GetPerformanceCounter(), > > + called later in wall clock > time. > > + > > + @retval The number of nanoseconds corresponding to the > conceptual difference > > + (PerfCounterStop-PerfCounterStart). > > +**/ > > +UINT64 > > +EFIAPI > > +GetNanoSecondDifference ( > > + IN UINT64 PerfCounterStart, > > + IN UINT64 PerfCounterStop > > + ) > > +{ > > + UINT64 TickDifference; > > + UINT64 NanoSecondDifference; > > + > > + TickDifference = GetTickDifference (PerfCounterStart, > PerfCounterStop); > > + NanoSecondDifference = GetTimeInNanoSecond > (TickDifference); > > + return NanoSecondDifference; > > +} > > + > > +/** > > + From two values retrieved with TimerLib's > GetPerformanceCounter(), calculate > > + the number of microseconds elapsed between them. > > + > > + The function cannot handle multiple wrap-arounds of the > performance counter. > > + > > + @param[in] PerfCounterStart The value returned by > GetPerformanceCounter(), > > + called earlier in wall clock > time. > > + > > + @param[in] PerfCounterStop The value returned by > GetPerformanceCounter(), > > + called later in wall clock > time. > > + > > + @retval The number of microseconds corresponding to the > conceptual > > + difference (PerfCounterStop-PerfCounterStart). > > +**/ > > +UINT64 > > +EFIAPI > > +GetMicroSecondDifference ( > > + IN UINT64 PerfCounterStart, > > + IN UINT64 PerfCounterStop > > + ) > > +{ > > + UINT64 NanoSecondDifference; > > + UINT64 MicroSecondDifference; > > + > > + NanoSecondDifference = GetNanoSecondDifference ( > > + PerfCounterStart, > > + PerfCounterStop > > + ); > > + MicroSecondDifference = DivU64x32 (NanoSecondDifference, > 1000); > > + return MicroSecondDifference; > > +} > > + > > +/** > > + From two values retrieved with TimerLib's > GetPerformanceCounter(), calculate > > + the number of milliseconds elapsed between them. > > + > > + The function cannot handle multiple wrap-arounds of the > performance counter. > > + > > + @param[in] PerfCounterStart The value returned by > GetPerformanceCounter(), > > + called earlier in wall clock > time. > > + > > + @param[in] PerfCounterStop The value returned by > GetPerformanceCounter(), > > + called later in wall clock > time. > > + > > + @retval The number of milliseconds corresponding to the > conceptual > > + difference (PerfCounterStop-PerfCounterStart). > > +**/ > > +UINT64 > > +EFIAPI > > +GetMilliSecondDifference ( > > + IN UINT64 PerfCounterStart, > > + IN UINT64 PerfCounterStop > > + ) > > +{ > > + UINT64 NanoSecondDifference; > > + UINT64 MilliSecondDifference; > > + > > + NanoSecondDifference = GetNanoSecondDifference ( > > + PerfCounterStart, > > + PerfCounterStop > > + ); > > + MilliSecondDifference = DivU64x32 (NanoSecondDifference, > 1000 * 1000); > > + return MilliSecondDifference; > > +} _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

