Message ID | 20210214021616.26970-2-dmitry.kozliuk@gmail.com (mailing list archive) |
---|---|
State | Superseded, archived |
Delegated to: | Ferruh Yigit |
Headers | show |
Series | net/pcap: build on Windows | expand |
Context | Check | Description |
---|---|---|
ci/checkpatch | success | coding style OK |
> 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.
diff --git a/lib/librte_eal/include/rte_time.h b/lib/librte_eal/include/rte_time.h index 5ad7c8841..50fa4f889 100644 --- a/lib/librte_eal/include/rte_time.h +++ b/lib/librte_eal/include/rte_time.h @@ -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_ */ diff --git a/lib/librte_eal/rte_eal_exports.def b/lib/librte_eal/rte_eal_exports.def index 474cf123f..cb691f7bc 100644 --- a/lib/librte_eal/rte_eal_exports.def +++ b/lib/librte_eal/rte_eal_exports.def @@ -334,3 +334,4 @@ EXPORTS rte_mem_map rte_mem_page_size rte_mem_unmap + rte_time_get_us diff --git a/lib/librte_eal/unix/eal_unix_timer.c b/lib/librte_eal/unix/eal_unix_timer.c index cc5015910..5612fdebe 100644 --- a/lib/librte_eal/unix/eal_unix_timer.c +++ b/lib/librte_eal/unix/eal_unix_timer.c @@ -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; +} diff --git a/lib/librte_eal/version.map b/lib/librte_eal/version.map index fce90a112..405bed766 100644 --- a/lib/librte_eal/version.map +++ b/lib/librte_eal/version.map @@ -421,4 +421,5 @@ INTERNAL { rte_mem_map; rte_mem_page_size; rte_mem_unmap; + rte_time_get_us; }; diff --git a/lib/librte_eal/windows/eal_timer.c b/lib/librte_eal/windows/eal_timer.c index b070cb775..a5c42106a 100644 --- a/lib/librte_eal/windows/eal_timer.c +++ b/lib/librte_eal/windows/eal_timer.c @@ -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; +}
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(-)