From: "Kinney, Michael D" <michael.d.kinney@intel.com>
To: Laszlo Ersek <lersek@redhat.com>,
"Gao, Liming" <liming.gao@intel.com>,
"Kinney, Michael D" <michael.d.kinney@intel.com>
Cc: edk2-devel-01 <edk2-devel@lists.01.org>
Subject: Re: TimerTickDiffLib for MdePkg?
Date: Wed, 16 Aug 2017 15:41:37 +0000 [thread overview]
Message-ID: <E92EE9817A31E24EB0585FDF735412F5A7D8086D@ORSMSX113.amr.corp.intel.com> (raw)
In-Reply-To: <8cba2a58-1333-7733-031d-0883dbd844c6@redhat.com>
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:lersek@redhat.com]
> Sent: Wednesday, August 16, 2017 4:46 AM
> To: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> <liming.gao@intel.com>
> Cc: edk2-devel-01 <edk2-devel@lists.01.org>
> 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 <lersek@redhat.com>
> > Date: Tue Aug 8 22:46:47 2017 +0200
> >
> > OvmfPkg: add TimerTickDiffLib
> >
> > Contributed-under: TianoCore Contribution Agreement 1.1
> > Signed-off-by: Laszlo Ersek <lersek@redhat.com>
> >
> > 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;
> > +}
next prev parent reply other threads:[~2017-08-16 15:39 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-16 11:45 TimerTickDiffLib for MdePkg? Laszlo Ersek
2017-08-16 15:41 ` Kinney, Michael D [this message]
2017-08-16 16:08 ` Laszlo Ersek
2017-08-16 18:01 ` Kinney, Michael D
2017-08-16 18:24 ` Laszlo Ersek
2017-08-16 18:33 ` Kinney, Michael D
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=E92EE9817A31E24EB0585FDF735412F5A7D8086D@ORSMSX113.amr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox