[v2,1/6] eal: add internal API for current time
Checks
Commit Message
Many PMDs use POSIX gettimeofday(). Add rte_time_get_us() function
to obtain current time with microsecond precision on all platforms.
Signed-off-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
---
lib/librte_eal/include/rte_time.h | 17 +++++++++++++++++
lib/librte_eal/rte_eal_exports.def | 1 +
lib/librte_eal/unix/eal_unix_timer.c | 13 +++++++++++++
lib/librte_eal/version.map | 1 +
lib/librte_eal/windows/eal_timer.c | 21 ++++++++++++++++++++-
5 files changed, 52 insertions(+), 1 deletion(-)
Comments
> Many PMDs use POSIX gettimeofday(). Add rte_time_get_us() function
> to obtain current time with microsecond precision on all platforms.
>
Acked-by: Nick Connolly <nick.connolly@mayadata.io>
On Sun, Feb 14, 2021 at 05:16:11AM +0300, Dmitry Kozlyuk wrote:
> Many PMDs use POSIX gettimeofday(). Add rte_time_get_us() function
> to obtain current time with microsecond precision on all platforms.
>
> Signed-off-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
> ---
> lib/librte_eal/include/rte_time.h | 17 +++++++++++++++++
> lib/librte_eal/rte_eal_exports.def | 1 +
> lib/librte_eal/unix/eal_unix_timer.c | 13 +++++++++++++
> lib/librte_eal/version.map | 1 +
> lib/librte_eal/windows/eal_timer.c | 21 ++++++++++++++++++++-
> 5 files changed, 52 insertions(+), 1 deletion(-)
>
Acked-by: Jie Zhou <jizh@linux.microsoft.com>
14/02/2021 03:16, Dmitry Kozlyuk:
> Many PMDs use POSIX gettimeofday(). Add rte_time_get_us() function
> to obtain current time with microsecond precision on all platforms.
Please could you replace the current use of gettimeofday?
On Sun, 14 Feb 2021 05:16:11 +0300
Dmitry Kozlyuk <dmitry.kozliuk@gmail.com> wrote:
> +rte_time_get_us(struct rte_time_us *now)
> +{
> + struct timeval sys;
> +
> + gettimeofday(&sys, NULL);
> + now->sec = sys.tv_sec;
> + now->usec = sys.tv_usec;
> +}
Why would drivers want the default (wall clock) time instead
of using monotonic clock. The wall clock gets changed by NTP
and that is rarely what you want except for the case of log messages.
2021-03-16 11:59 (UTC-0700), Stephen Hemminger:
> On Sun, 14 Feb 2021 05:16:11 +0300
> Dmitry Kozlyuk <dmitry.kozliuk@gmail.com> wrote:
>
> > +rte_time_get_us(struct rte_time_us *now)
> > +{
> > + struct timeval sys;
> > +
> > + gettimeofday(&sys, NULL);
> > + now->sec = sys.tv_sec;
> > + now->usec = sys.tv_usec;
> > +}
>
> Why would drivers want the default (wall clock) time instead
> of using monotonic clock. The wall clock gets changed by NTP
> and that is rarely what you want except for the case of log messages.
* gettimeofday() is mostly used to measure time (tests, hns3 PMD), so you're
right, monotonic clock is what that code really needs.
* ena PMD uses gettimeofday() with pthread_cond_timedwait() without calling
pthread_cond_setclock(), which is a bug, I believe.
* hns3 PMD actually uses gettimeofday() for logs.
For wall clock time there is C11 timespec_get(), so I agree this API should
be changed to monotonic, thanks.
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Dmitry Kozlyuk
> Sent: Tuesday, March 16, 2021 9:08 PM
>
> 2021-03-16 11:59 (UTC-0700), Stephen Hemminger:
> > On Sun, 14 Feb 2021 05:16:11 +0300
> > Dmitry Kozlyuk <dmitry.kozliuk@gmail.com> wrote:
> >
> > > +rte_time_get_us(struct rte_time_us *now)
> > > +{
> > > + struct timeval sys;
> > > +
> > > + gettimeofday(&sys, NULL);
> > > + now->sec = sys.tv_sec;
> > > + now->usec = sys.tv_usec;
> > > +}
> >
> > Why would drivers want the default (wall clock) time instead
> > of using monotonic clock. The wall clock gets changed by NTP
> > and that is rarely what you want except for the case of log messages.
>
> * gettimeofday() is mostly used to measure time (tests, hns3 PMD), so
> you're
> right, monotonic clock is what that code really needs.
If using monotonic time here, we don't need a struct. A single 64 bit integer counting microseconds can hold thousands of years.
>
> * ena PMD uses gettimeofday() with pthread_cond_timedwait() without
> calling
> pthread_cond_setclock(), which is a bug, I believe.
>
> * hns3 PMD actually uses gettimeofday() for logs.
>
> For wall clock time there is C11 timespec_get(), so I agree this API
> should
> be changed to monotonic, thanks.
@@ -8,6 +8,8 @@
#include <stdint.h>
#include <time.h>
+#include <rte_compat.h>
+
#define NSEC_PER_SEC 1000000000L
/**
@@ -98,4 +100,19 @@ rte_ns_to_timespec(uint64_t nsec)
return ts;
}
+/* Point of time with microsecond precision. */
+struct rte_time_us {
+ int64_t sec; /**< Number of whole seconds. */
+ int64_t usec; /**< Fractional part of second in [0, 999999]. */
+};
+
+/**
+ * Get current system time.
+ *
+ * @param now
+ * Receives current system time.
+ */
+__rte_internal
+void rte_time_get_us(struct rte_time_us *now);
+
#endif /* _RTE_TIME_H_ */
@@ -334,3 +334,4 @@ EXPORTS
rte_mem_map
rte_mem_page_size
rte_mem_unmap
+ rte_time_get_us
@@ -4,7 +4,10 @@
#include <time.h>
+#include <sys/time.h>
+
#include <rte_cycles.h>
+#include <rte_time.h>
void
rte_delay_us_sleep(unsigned int us)
@@ -27,3 +30,13 @@ rte_delay_us_sleep(unsigned int us)
ind = 1 - ind;
}
}
+
+void
+rte_time_get_us(struct rte_time_us *now)
+{
+ struct timeval sys;
+
+ gettimeofday(&sys, NULL);
+ now->sec = sys.tv_sec;
+ now->usec = sys.tv_usec;
+}
@@ -421,4 +421,5 @@ INTERNAL {
rte_mem_map;
rte_mem_page_size;
rte_mem_unmap;
+ rte_time_get_us;
};
@@ -9,6 +9,7 @@
#include <rte_cycles.h>
#include <rte_eal.h>
#include <rte_errno.h>
+#include <rte_time.h>
#include "eal_private.h"
#define US_PER_SEC 1E6
@@ -85,10 +86,28 @@ get_tsc_freq(void)
return RTE_ALIGN_MUL_NEAR(tsc_hz, CYC_PER_10MHZ);
}
-
int
rte_eal_timer_init(void)
{
set_tsc_freq();
return 0;
}
+
+void
+rte_time_get_us(struct rte_time_us *now)
+{
+ /* 100ns ticks from 1601-01-01 to 1970-01-01 */
+ static const uint64_t EPOCH = 116444736000000000ULL;
+ static const uint64_t TICKS_PER_USEC = 10;
+ static const uint64_t USEC_PER_SEC = 1000000;
+
+ FILETIME ft;
+ uint64_t ticks, sec;
+
+ GetSystemTimePreciseAsFileTime(&ft);
+ ticks = ((uint64_t)ft.dwHighDateTime << 32) | ft.dwLowDateTime;
+ ticks -= EPOCH;
+ sec = ticks / (TICKS_PER_USEC * USEC_PER_SEC);
+ now->sec = sec;
+ now->usec = ticks / TICKS_PER_USEC - sec * USEC_PER_SEC;
+}