aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatias Elo <matias.elo@nokia.com>2023-06-13 16:55:57 +0300
committerMatias Elo <matias.elo@nokia.com>2023-06-21 08:32:02 +0300
commit72683c2804d9a3c3e63d92c45d1e8cab95ef8be8 (patch)
tree42a8661ab8dfcf71a358ea8e1a994b1173cf734e
parenta61183da473f281eaaceabd856703027fe75804e (diff)
linux-gen: time: refactor implementation
Refactor time codebase to enable more optimized architecture specific implementations. After this commit x86 and aarch64 architectures are assumed to always have support for HW time. The fallback to POSIX time functions has been removed from these architectures for improved performance. Signed-off-by: Matias Elo <matias.elo@nokia.com> Reviewed-by: Petri Savolainen <petri.savolainen@nokia.com>
-rw-r--r--Makefile.inc1
-rw-r--r--platform/linux-generic/Makefile.am57
-rw-r--r--platform/linux-generic/arch/aarch64/odp/api/abi/time_cpu.h (renamed from platform/linux-generic/arch/aarch64/odp/api/abi/cpu_time.h)15
-rw-r--r--platform/linux-generic/arch/aarch64/odp/api/abi/time_inlines.h7
-rw-r--r--platform/linux-generic/arch/aarch64/odp_global_time.c25
-rw-r--r--platform/linux-generic/arch/common/odp/api/abi/time_cpu_inlines.h93
-rw-r--r--platform/linux-generic/arch/common/odp_time_cpu.c48
-rw-r--r--platform/linux-generic/arch/default/odp/api/abi/cpu_time.h25
-rw-r--r--platform/linux-generic/arch/default/odp/api/abi/time_inlines.h45
-rw-r--r--platform/linux-generic/arch/default/odp_global_time.c31
-rw-r--r--platform/linux-generic/arch/default/odp_time.c102
-rw-r--r--platform/linux-generic/arch/x86/cpu_flags.c9
-rw-r--r--platform/linux-generic/arch/x86/odp/api/abi/time_cpu.h (renamed from platform/linux-generic/arch/x86/odp/api/abi/cpu_time.h)12
-rw-r--r--platform/linux-generic/arch/x86/odp/api/abi/time_inlines.h7
-rw-r--r--platform/linux-generic/arch/x86/odp_time_cpu.c (renamed from platform/linux-generic/arch/x86/odp_global_time.c)29
-rw-r--r--platform/linux-generic/include/odp/api/plat/time_inlines.h127
-rw-r--r--platform/linux-generic/odp_time.c215
17 files changed, 423 insertions, 425 deletions
diff --git a/Makefile.inc b/Makefile.inc
index e3c100e96..26588e812 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -14,6 +14,7 @@ ODP_INCLUDES += \
-I$(top_srcdir)/platform/@with_platform@/include \
-I$(top_srcdir)/platform/@with_platform@/arch/@ARCH_DIR@ \
-I$(top_srcdir)/platform/@with_platform@/arch/default \
+ -I$(top_srcdir)/platform/@with_platform@/arch/common \
-I$(top_srcdir)/platform/@with_platform@/include-abi
endif
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 6565e18da..4c02c56fa 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -10,6 +10,7 @@ AM_CPPFLAGS += -I$(top_builddir)/platform/$(with_platform)/include
AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/arch
AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/arch/@ARCH_DIR@
AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/arch/default
+AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/arch/common
AM_CPPFLAGS += $(OPENSSL_CPPFLAGS)
@@ -257,7 +258,6 @@ __LIB__libodp_linux_la_SOURCES = \
odp_pcapng.c \
odp_thread.c \
odp_thrmask.c \
- odp_time.c \
odp_timer.c \
odp_timer_wheel.c \
odp_traffic_mngr.c \
@@ -328,18 +328,18 @@ endif
if ARCH_IS_ARM
__LIB__libodp_linux_la_SOURCES += arch/default/odp_atomic.c \
arch/default/odp_cpu_cycles.c \
- arch/default/odp_global_time.c \
arch/default/odp_hash_crc32.c \
arch/default/odp_random.c \
- arch/arm/odp_sysinfo_parse.c
-odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/cpu_time.h \
- arch/default/odp/api/abi/hash_crc32.h
+ arch/arm/odp_sysinfo_parse.c \
+ arch/default/odp_time.c
+odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/hash_crc32.h
if !ODP_ABI_COMPAT
odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \
arch/default/odp/api/abi/atomic_inlines.h \
arch/default/odp/api/abi/cpu_generic.h \
arch/arm/odp/api/abi/cpu_inlines.h \
- arch/arm/odp/api/abi/cpu.h
+ arch/arm/odp/api/abi/cpu.h \
+ arch/default/odp/api/abi/time_inlines.h
endif
noinst_HEADERS += arch/arm/odp_atomic.h \
arch/arm/odp_cpu.h \
@@ -354,19 +354,21 @@ if ARCH_IS_AARCH64
__LIB__libodp_linux_la_SOURCES += arch/aarch64/odp_atomic.c \
arch/default/odp_cpu_cycles.c \
arch/aarch64/cpu_flags.c \
- arch/aarch64/odp_global_time.c \
arch/default/odp_hash_crc32.c \
arch/default/odp_random.c \
- arch/aarch64/odp_sysinfo_parse.c
-odpapiabiarchinclude_HEADERS += arch/aarch64/odp/api/abi/cpu_time.h \
- arch/aarch64/odp/api/abi/hash_crc32.h
+ arch/aarch64/odp_sysinfo_parse.c \
+ arch/common/odp_time_cpu.c
+odpapiabiarchinclude_HEADERS += arch/aarch64/odp/api/abi/hash_crc32.h \
+ arch/aarch64/odp/api/abi/time_cpu.h
if !ODP_ABI_COMPAT
odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \
arch/aarch64/odp/api/abi/atomic_inlines.h \
arch/aarch64/odp/api/abi/atomic.h \
arch/default/odp/api/abi/cpu_generic.h \
arch/aarch64/odp/api/abi/cpu_inlines.h \
- arch/aarch64/odp/api/abi/cpu.h
+ arch/aarch64/odp/api/abi/cpu.h \
+ arch/common/odp/api/abi/time_cpu_inlines.h \
+ arch/aarch64/odp/api/abi/time_inlines.h
endif
noinst_HEADERS += arch/aarch64/odp_atomic.h \
arch/aarch64/odp_cpu.h \
@@ -378,18 +380,18 @@ endif
if ARCH_IS_DEFAULT
__LIB__libodp_linux_la_SOURCES += arch/default/odp_atomic.c \
arch/default/odp_cpu_cycles.c \
- arch/default/odp_global_time.c \
arch/default/odp_hash_crc32.c \
arch/default/odp_random.c \
- arch/default/odp_sysinfo_parse.c
-odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/cpu_time.h \
- arch/default/odp/api/abi/hash_crc32.h
+ arch/default/odp_sysinfo_parse.c \
+ arch/default/odp_time.c
+odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/hash_crc32.h
if !ODP_ABI_COMPAT
odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \
arch/default/odp/api/abi/atomic_inlines.h \
arch/default/odp/api/abi/cpu_generic.h \
arch/default/odp/api/abi/cpu_inlines.h \
- arch/default/odp/api/abi/cpu.h
+ arch/default/odp/api/abi/cpu.h \
+ arch/default/odp/api/abi/time_inlines.h
endif
noinst_HEADERS += arch/default/odp_atomic.h \
arch/default/odp_cpu.h \
@@ -399,18 +401,18 @@ endif
if ARCH_IS_POWERPC
__LIB__libodp_linux_la_SOURCES += arch/default/odp_atomic.c \
arch/default/odp_cpu_cycles.c \
- arch/default/odp_global_time.c \
arch/default/odp_hash_crc32.c \
arch/default/odp_random.c \
- arch/powerpc/odp_sysinfo_parse.c
-odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/cpu_time.h \
- arch/default/odp/api/abi/hash_crc32.h
+ arch/powerpc/odp_sysinfo_parse.c \
+ arch/default/odp_time.c
+odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/hash_crc32.h
if !ODP_ABI_COMPAT
odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \
arch/default/odp/api/abi/atomic_inlines.h \
arch/default/odp/api/abi/cpu_generic.h \
arch/default/odp/api/abi/cpu_inlines.h \
- arch/powerpc/odp/api/abi/cpu.h
+ arch/powerpc/odp/api/abi/cpu.h \
+ arch/default/odp/api/abi/time_inlines.h
endif
noinst_HEADERS += arch/default/odp_atomic.h \
arch/default/odp_cpu.h \
@@ -421,18 +423,21 @@ if ARCH_IS_X86
__LIB__libodp_linux_la_SOURCES += arch/default/odp_atomic.c \
arch/x86/cpu_flags.c \
arch/x86/odp_cpu_cycles.c \
- arch/x86/odp_global_time.c \
arch/default/odp_hash_crc32.c \
arch/default/odp_random.c \
- arch/x86/odp_sysinfo_parse.c
+ arch/x86/odp_sysinfo_parse.c \
+ arch/x86/odp_time_cpu.c \
+ arch/common/odp_time_cpu.c
odpapiabiarchinclude_HEADERS += arch/x86/odp/api/abi/cpu_rdtsc.h \
- arch/x86/odp/api/abi/cpu_time.h \
- arch/x86/odp/api/abi/hash_crc32.h
+ arch/x86/odp/api/abi/hash_crc32.h \
+ arch/x86/odp/api/abi/time_cpu.h
if !ODP_ABI_COMPAT
odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \
arch/default/odp/api/abi/atomic_inlines.h \
arch/x86/odp/api/abi/cpu_inlines.h \
- arch/x86/odp/api/abi/cpu.h
+ arch/x86/odp/api/abi/cpu.h \
+ arch/common/odp/api/abi/time_cpu_inlines.h \
+ arch/x86/odp/api/abi/time_inlines.h
endif
noinst_HEADERS += arch/x86/cpu_flags.h \
arch/x86/odp_cpu.h \
diff --git a/platform/linux-generic/arch/aarch64/odp/api/abi/cpu_time.h b/platform/linux-generic/arch/aarch64/odp/api/abi/time_cpu.h
index 781ee683c..aba2799c7 100644
--- a/platform/linux-generic/arch/aarch64/odp/api/abi/cpu_time.h
+++ b/platform/linux-generic/arch/aarch64/odp/api/abi/time_cpu.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef ODP_API_ABI_CPU_TIME_H_
-#define ODP_API_ABI_CPU_TIME_H_
+#ifndef ODP_API_ABI_TIME_CPU_H_
+#define ODP_API_ABI_TIME_CPU_H_
#ifdef __cplusplus
extern "C" {
@@ -13,7 +13,7 @@ extern "C" {
#include <stdint.h>
-static inline uint64_t _odp_cpu_global_time(void)
+static inline uint64_t _odp_time_cpu_global(void)
{
uint64_t cntvct;
@@ -22,7 +22,7 @@ static inline uint64_t _odp_cpu_global_time(void)
return cntvct;
}
-static inline uint64_t _odp_cpu_global_time_strict(void)
+static inline uint64_t _odp_time_cpu_global_strict(void)
{
uint64_t cntvct;
@@ -32,7 +32,7 @@ static inline uint64_t _odp_cpu_global_time_strict(void)
return cntvct;
}
-static inline uint64_t _odp_cpu_global_time_freq(void)
+static inline uint64_t _odp_time_cpu_global_freq(void)
{
uint64_t cntfrq;
@@ -41,7 +41,10 @@ static inline uint64_t _odp_cpu_global_time_freq(void)
return cntfrq;
}
-int _odp_cpu_has_global_time(void);
+static inline int _odp_time_cpu_global_freq_is_const(void)
+{
+ return 1;
+}
#ifdef __cplusplus
}
diff --git a/platform/linux-generic/arch/aarch64/odp/api/abi/time_inlines.h b/platform/linux-generic/arch/aarch64/odp/api/abi/time_inlines.h
new file mode 100644
index 000000000..331d1996f
--- /dev/null
+++ b/platform/linux-generic/arch/aarch64/odp/api/abi/time_inlines.h
@@ -0,0 +1,7 @@
+/* Copyright (c) 2023, Nokia
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp/api/abi/time_cpu_inlines.h>
diff --git a/platform/linux-generic/arch/aarch64/odp_global_time.c b/platform/linux-generic/arch/aarch64/odp_global_time.c
deleted file mode 100644
index 53561b00c..000000000
--- a/platform/linux-generic/arch/aarch64/odp_global_time.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (c) 2015-2018, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <odp/api/abi/cpu_time.h>
-
-int _odp_cpu_has_global_time(void)
-{
- uint64_t hz = _odp_cpu_global_time_freq();
-
- /*
- * The system counter portion of the architected timer must
- * provide a uniform view of system time to all processing
- * elements in the system. This should hold true even for
- * heterogeneous SoCs.
- *
- * Determine whether the system has 'global time' by checking
- * whether a read of the architected timer frequency sys reg
- * returns a sane value. Sane is considered to be within
- * 1MHz and 6GHz (1us and .1667ns period).
- */
- return hz >= 1000000 && hz <= 6000000000;
-}
diff --git a/platform/linux-generic/arch/common/odp/api/abi/time_cpu_inlines.h b/platform/linux-generic/arch/common/odp/api/abi/time_cpu_inlines.h
new file mode 100644
index 000000000..c154c5f1a
--- /dev/null
+++ b/platform/linux-generic/arch/common/odp/api/abi/time_cpu_inlines.h
@@ -0,0 +1,93 @@
+/* Copyright (c) 2013-2018, Linaro Limited
+ * Copyright (c) 2020-2023, Nokia
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ODP_ARCH_TIME_CPU_INLINES_H_
+#define ODP_ARCH_TIME_CPU_INLINES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/api/time_types.h>
+
+#include <odp/api/abi/time_cpu.h>
+
+#include <stdint.h>
+
+#define _ODP_TIME_GIGA_HZ 1000000000ULL
+
+typedef struct _odp_time_global_t {
+ uint64_t start_time;
+ uint64_t freq_hz;
+
+} _odp_time_global_t;
+
+extern _odp_time_global_t _odp_time_glob;
+
+static inline odp_time_t _odp_time_cur(void)
+{
+ odp_time_t time;
+
+ time.count = _odp_time_cpu_global() - _odp_time_glob.start_time;
+ return time;
+}
+
+static inline odp_time_t _odp_time_cur_strict(void)
+{
+ odp_time_t time;
+
+ time.count = _odp_time_cpu_global_strict() - _odp_time_glob.start_time;
+ return time;
+}
+
+static inline uint64_t _odp_time_to_ns(odp_time_t time)
+{
+ uint64_t nsec;
+ uint64_t freq_hz = _odp_time_glob.freq_hz;
+ uint64_t count = time.count;
+ uint64_t sec = 0;
+
+ if (count >= freq_hz) {
+ sec = count / freq_hz;
+ count = count - sec * freq_hz;
+ }
+
+ nsec = (_ODP_TIME_GIGA_HZ * count) / freq_hz;
+
+ return (sec * _ODP_TIME_GIGA_HZ) + nsec;
+}
+
+static inline odp_time_t _odp_time_from_ns(uint64_t ns)
+{
+ odp_time_t time;
+ uint64_t count;
+ uint64_t freq_hz = _odp_time_glob.freq_hz;
+ uint64_t sec = 0;
+
+ if (ns >= ODP_TIME_SEC_IN_NS) {
+ sec = ns / ODP_TIME_SEC_IN_NS;
+ ns = ns - sec * ODP_TIME_SEC_IN_NS;
+ }
+
+ count = sec * freq_hz;
+ count += (ns * freq_hz) / ODP_TIME_SEC_IN_NS;
+
+ time.count = count;
+
+ return time;
+}
+
+static inline uint64_t _odp_time_res(void)
+{
+ return _odp_time_glob.freq_hz;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/arch/common/odp_time_cpu.c b/platform/linux-generic/arch/common/odp_time_cpu.c
new file mode 100644
index 000000000..bbfe82e21
--- /dev/null
+++ b/platform/linux-generic/arch/common/odp_time_cpu.c
@@ -0,0 +1,48 @@
+/* Copyright (c) 2013-2018, Linaro Limited
+ * Copyright (c) 2020-2023, Nokia
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp/api/time_types.h>
+
+#include <odp/api/abi/time_cpu.h>
+#include <odp/api/abi/time_cpu_inlines.h>
+
+#include <odp_debug_internal.h>
+#include <odp_init_internal.h>
+
+#include <inttypes.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <odp/visibility_begin.h>
+
+_odp_time_global_t _odp_time_glob;
+
+#include <odp/visibility_end.h>
+
+int _odp_time_init_global(void)
+{
+ _odp_time_global_t *global = &_odp_time_glob;
+
+ memset(global, 0, sizeof(_odp_time_global_t));
+
+ if (!_odp_time_cpu_global_freq_is_const())
+ return -1;
+
+ global->freq_hz = _odp_time_cpu_global_freq();
+ if (global->freq_hz == 0)
+ return -1;
+
+ _ODP_PRINT("HW time counter freq: %" PRIu64 " hz\n\n", global->freq_hz);
+
+ global->start_time = _odp_time_cpu_global();
+ return 0;
+}
+
+int _odp_time_term_global(void)
+{
+ return 0;
+}
diff --git a/platform/linux-generic/arch/default/odp/api/abi/cpu_time.h b/platform/linux-generic/arch/default/odp/api/abi/cpu_time.h
deleted file mode 100644
index 24e1c7d33..000000000
--- a/platform/linux-generic/arch/default/odp/api/abi/cpu_time.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (c) 2018, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef ODP_ARCH_CPU_TIME_H_
-#define ODP_ARCH_CPU_TIME_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-
-int _odp_cpu_has_global_time(void);
-uint64_t _odp_cpu_global_time(void);
-uint64_t _odp_cpu_global_time_strict(void);
-uint64_t _odp_cpu_global_time_freq(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/platform/linux-generic/arch/default/odp/api/abi/time_inlines.h b/platform/linux-generic/arch/default/odp/api/abi/time_inlines.h
new file mode 100644
index 000000000..b38e52dac
--- /dev/null
+++ b/platform/linux-generic/arch/default/odp/api/abi/time_inlines.h
@@ -0,0 +1,45 @@
+/* Copyright (c) 2013-2018, Linaro Limited
+ * Copyright (c) 2020-2023, Nokia
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ODP_ARCH_TIME_INLINES_H_
+#define ODP_ARCH_TIME_INLINES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/api/time_types.h>
+
+#include <stdint.h>
+
+odp_time_t _odp_time_cur(void);
+uint64_t _odp_time_res(void);
+
+static inline odp_time_t _odp_time_cur_strict(void)
+{
+ return _odp_time_cur();
+}
+
+static inline uint64_t _odp_time_to_ns(odp_time_t time)
+{
+ return time.nsec;
+}
+
+static inline odp_time_t _odp_time_from_ns(uint64_t ns)
+{
+ odp_time_t time;
+
+ time.nsec = ns;
+
+ return time;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/arch/default/odp_global_time.c b/platform/linux-generic/arch/default/odp_global_time.c
deleted file mode 100644
index ee835413f..000000000
--- a/platform/linux-generic/arch/default/odp_global_time.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (c) 2015-2018, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <odp/api/abi/cpu_time.h>
-
-#include <odp/visibility_begin.h>
-
-uint64_t _odp_cpu_global_time(void)
-{
- return 0;
-}
-
-uint64_t _odp_cpu_global_time_strict(void)
-{
- return 0;
-}
-
-#include <odp/visibility_end.h>
-
-int _odp_cpu_has_global_time(void)
-{
- return 0;
-}
-
-uint64_t _odp_cpu_global_time_freq(void)
-{
- return 0;
-}
diff --git a/platform/linux-generic/arch/default/odp_time.c b/platform/linux-generic/arch/default/odp_time.c
new file mode 100644
index 000000000..919a3ba68
--- /dev/null
+++ b/platform/linux-generic/arch/default/odp_time.c
@@ -0,0 +1,102 @@
+/* Copyright (c) 2013-2018, Linaro Limited
+ * Copyright (c) 2020-2023, Nokia
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp_posix_extensions.h>
+
+#include <odp/api/align.h>
+#include <odp/api/hints.h>
+#include <odp/api/time_types.h>
+
+#include <odp/api/abi/time_inlines.h>
+
+#include <odp_debug_internal.h>
+#include <odp_init_internal.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+
+typedef struct _odp_time_global_t {
+ struct timespec start_time;
+
+} _odp_time_global_t;
+
+_odp_time_global_t _odp_time_glob;
+
+static inline uint64_t time_diff_nsec(struct timespec *t2, struct timespec *t1)
+{
+ struct timespec diff;
+ uint64_t nsec;
+
+ diff.tv_sec = t2->tv_sec - t1->tv_sec;
+ diff.tv_nsec = t2->tv_nsec - t1->tv_nsec;
+
+ if (diff.tv_nsec < 0) {
+ diff.tv_nsec += ODP_TIME_SEC_IN_NS;
+ diff.tv_sec -= 1;
+ }
+
+ nsec = (diff.tv_sec * ODP_TIME_SEC_IN_NS) + diff.tv_nsec;
+
+ return nsec;
+}
+
+#include <odp/visibility_begin.h>
+
+odp_time_t _odp_time_cur(void)
+{
+ int ret;
+ odp_time_t time;
+ struct timespec sys_time;
+ struct timespec *start_time = &_odp_time_glob.start_time;
+
+ ret = clock_gettime(CLOCK_MONOTONIC_RAW, &sys_time);
+ if (odp_unlikely(ret != 0))
+ _ODP_ABORT("clock_gettime() failed\n");
+
+ time.nsec = time_diff_nsec(&sys_time, start_time);
+
+ return time;
+}
+
+uint64_t _odp_time_res(void)
+{
+ int ret;
+ struct timespec tres;
+
+ ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres);
+ if (odp_unlikely(ret != 0))
+ _ODP_ABORT("clock_getres() failed\n");
+
+ return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec;
+}
+
+#include <odp/visibility_end.h>
+
+int _odp_time_init_global(void)
+{
+ struct timespec *start_time;
+ int ret = 0;
+ _odp_time_global_t *global = &_odp_time_glob;
+
+ memset(global, 0, sizeof(_odp_time_global_t));
+
+ start_time = &global->start_time;
+ start_time->tv_sec = 0;
+ start_time->tv_nsec = 0;
+
+ ret = clock_gettime(CLOCK_MONOTONIC_RAW, start_time);
+ if (ret)
+ _ODP_ERR("clock_gettime() failed: %d\n", ret);
+
+ return ret;
+}
+
+int _odp_time_term_global(void)
+{
+ return 0;
+}
diff --git a/platform/linux-generic/arch/x86/cpu_flags.c b/platform/linux-generic/arch/x86/cpu_flags.c
index 13753febb..482c25739 100644
--- a/platform/linux-generic/arch/x86/cpu_flags.c
+++ b/platform/linux-generic/arch/x86/cpu_flags.c
@@ -11,7 +11,7 @@
#include "cpu_flags.h"
#include <odp_debug_internal.h>
-#include <odp/api/abi/cpu_time.h>
+#include <odp/api/abi/time_cpu.h>
#include <cpuid.h>
#include <errno.h>
@@ -354,12 +354,15 @@ void _odp_cpu_flags_print_all(void)
_ODP_PRINT("%s", str);
}
-int _odp_cpu_has_global_time(void)
+int _odp_time_cpu_global_freq_is_const(void)
{
if (cpu_get_flag_enabled(RTE_CPUFLAG_INVTSC) > 0)
return 1;
- return 0;
+ _ODP_ERR("WARN: assuming constant TSC based on CPU arch, but could not confirm from CPU "
+ "flags\n");
+
+ return 1;
}
int _odp_cpu_flags_has_rdtsc(void)
diff --git a/platform/linux-generic/arch/x86/odp/api/abi/cpu_time.h b/platform/linux-generic/arch/x86/odp/api/abi/time_cpu.h
index c74c4d606..baf79ad3f 100644
--- a/platform/linux-generic/arch/x86/odp/api/abi/cpu_time.h
+++ b/platform/linux-generic/arch/x86/odp/api/abi/time_cpu.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef ODP_ARCH_CPU_TIME_H_
-#define ODP_ARCH_CPU_TIME_H_
+#ifndef ODP_ARCH_TIME_CPU_H_
+#define ODP_ARCH_TIME_CPU_H_
#ifdef __cplusplus
extern "C" {
@@ -14,19 +14,19 @@ extern "C" {
#include <stdint.h>
#include <odp/api/abi/cpu_rdtsc.h>
-static inline uint64_t _odp_cpu_global_time(void)
+static inline uint64_t _odp_time_cpu_global(void)
{
return _odp_cpu_rdtsc();
}
-static inline uint64_t _odp_cpu_global_time_strict(void)
+static inline uint64_t _odp_time_cpu_global_strict(void)
{
__atomic_thread_fence(__ATOMIC_SEQ_CST);
return _odp_cpu_rdtsc();
}
-int _odp_cpu_has_global_time(void);
-uint64_t _odp_cpu_global_time_freq(void);
+int _odp_time_cpu_global_freq_is_const(void);
+uint64_t _odp_time_cpu_global_freq(void);
#ifdef __cplusplus
}
diff --git a/platform/linux-generic/arch/x86/odp/api/abi/time_inlines.h b/platform/linux-generic/arch/x86/odp/api/abi/time_inlines.h
new file mode 100644
index 000000000..331d1996f
--- /dev/null
+++ b/platform/linux-generic/arch/x86/odp/api/abi/time_inlines.h
@@ -0,0 +1,7 @@
+/* Copyright (c) 2023, Nokia
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp/api/abi/time_cpu_inlines.h>
diff --git a/platform/linux-generic/arch/x86/odp_global_time.c b/platform/linux-generic/arch/x86/odp_time_cpu.c
index 00e3a1ac1..aa00ac04e 100644
--- a/platform/linux-generic/arch/x86/odp_global_time.c
+++ b/platform/linux-generic/arch/x86/odp_time_cpu.c
@@ -6,17 +6,18 @@
#include <odp_posix_extensions.h>
-#include <time.h>
-
#include <odp/api/hints.h>
+#include <odp/api/time_types.h>
+
+#include <odp/api/abi/time_cpu.h>
+
#include <odp_debug_internal.h>
-#include <odp/api/abi/cpu_time.h>
-#define SEC_IN_NS 1000000000ULL
+#include <time.h>
/* Measure TSC frequency. Frequency information registers are defined for x86,
* but those are often not enumerated. */
-uint64_t _odp_cpu_global_time_freq(void)
+uint64_t _odp_time_cpu_global_freq(void)
{
struct timespec sleep, ts1, ts2;
uint64_t t1, t2, ts_nsec, cycles, hz;
@@ -29,35 +30,35 @@ uint64_t _odp_cpu_global_time_freq(void)
sleep.tv_sec = 0;
if (warm_up)
- sleep.tv_nsec = SEC_IN_NS / 1000;
+ sleep.tv_nsec = ODP_TIME_SEC_IN_NS / 1000;
else
- sleep.tv_nsec = SEC_IN_NS / 4;
+ sleep.tv_nsec = ODP_TIME_SEC_IN_NS / 4;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts1)) {
- _ODP_DBG("clock_gettime failed\n");
+ _ODP_ERR("clock_gettime() failed\n");
return 0;
}
- t1 = _odp_cpu_global_time();
+ t1 = _odp_time_cpu_global();
if (nanosleep(&sleep, NULL) < 0) {
- _ODP_DBG("nanosleep failed\n");
+ _ODP_ERR("nanosleep() failed\n");
return 0;
}
if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts2)) {
- _ODP_DBG("clock_gettime failed\n");
+ _ODP_ERR("clock_gettime() failed\n");
return 0;
}
- t2 = _odp_cpu_global_time();
+ t2 = _odp_time_cpu_global();
- ts_nsec = (ts2.tv_sec - ts1.tv_sec) * SEC_IN_NS;
+ ts_nsec = (ts2.tv_sec - ts1.tv_sec) * ODP_TIME_SEC_IN_NS;
ts_nsec += ts2.tv_nsec - ts1.tv_nsec;
cycles = t2 - t1;
- hz = (cycles * SEC_IN_NS) / ts_nsec;
+ hz = (cycles * ODP_TIME_SEC_IN_NS) / ts_nsec;
if (warm_up)
warm_up = 0;
diff --git a/platform/linux-generic/include/odp/api/plat/time_inlines.h b/platform/linux-generic/include/odp/api/plat/time_inlines.h
index f8f4bee89..35a35c72e 100644
--- a/platform/linux-generic/include/odp/api/plat/time_inlines.h
+++ b/platform/linux-generic/include/odp/api/plat/time_inlines.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2018, Linaro Limited
- * Copyright (c) 2020-2022, Nokia
+ * Copyright (c) 2020-2023, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -12,79 +12,12 @@
#include <odp/api/hints.h>
#include <odp/api/time_types.h>
-#include <odp/api/abi/cpu_time.h>
+#include <odp/api/abi/time_inlines.h>
#include <stdint.h>
/** @cond _ODP_HIDE_FROM_DOXYGEN_ */
-#define _ODP_TIMESPEC_SIZE 16
-#define _ODP_TIME_GIGA_HZ 1000000000ULL
-
-typedef struct _odp_time_global_t {
- /* Storage space for struct timespec. Posix headers are not included
- * here to avoid application exposure. */
- uint8_t timespec[_ODP_TIMESPEC_SIZE] ODP_ALIGNED(_ODP_TIMESPEC_SIZE);
-
- int use_hw;
- uint64_t hw_start;
- uint64_t hw_freq_hz;
-
-} _odp_time_global_t;
-
-extern _odp_time_global_t _odp_time_glob;
-
-odp_time_t _odp_timespec_cur(void);
-
-static inline odp_time_t _odp_time_cur(void)
-{
- if (_odp_time_glob.use_hw) {
- odp_time_t time;
-
- time.count = _odp_cpu_global_time() - _odp_time_glob.hw_start;
- return time;
- }
-
- return _odp_timespec_cur();
-}
-
-static inline odp_time_t _odp_time_cur_strict(void)
-{
- if (_odp_time_glob.use_hw) {
- odp_time_t time;
-
- time.count = _odp_cpu_global_time_strict() - _odp_time_glob.hw_start;
- return time;
- }
-
- return _odp_timespec_cur();
-}
-
-static inline uint64_t _odp_time_hw_to_ns(odp_time_t time)
-{
- uint64_t nsec;
- uint64_t freq_hz = _odp_time_glob.hw_freq_hz;
- uint64_t count = time.count;
- uint64_t sec = 0;
-
- if (count >= freq_hz) {
- sec = count / freq_hz;
- count = count - sec * freq_hz;
- }
-
- nsec = (_ODP_TIME_GIGA_HZ * count) / freq_hz;
-
- return (sec * _ODP_TIME_GIGA_HZ) + nsec;
-}
-
-static inline uint64_t _odp_time_convert_to_ns(odp_time_t time)
-{
- if (_odp_time_glob.use_hw)
- return _odp_time_hw_to_ns(time);
-
- return time.nsec;
-}
-
#ifndef _ODP_NO_INLINE
/* Inline functions by default */
#define _ODP_INLINE static inline
@@ -104,6 +37,14 @@ static inline uint64_t _odp_time_convert_to_ns(odp_time_t time)
#define odp_time_diff_ns __odp_time_diff_ns
#define odp_time_sum __odp_time_sum
+ #define odp_time_local_from_ns __odp_time_local_from_ns
+ #define odp_time_global_from_ns __odp_time_global_from_ns
+
+ #define odp_time_local_res __odp_time_local_res
+ #define odp_time_global_res __odp_time_global_res
+
+ #define odp_time_wait_ns __odp_time_wait_ns
+ #define odp_time_wait_until __odp_time_wait_until
#else
#define _ODP_INLINE
#endif
@@ -130,27 +71,27 @@ _ODP_INLINE odp_time_t odp_time_global_strict(void)
_ODP_INLINE uint64_t odp_time_local_ns(void)
{
- return _odp_time_convert_to_ns(_odp_time_cur());
+ return _odp_time_to_ns(_odp_time_cur());
}
_ODP_INLINE uint64_t odp_time_global_ns(void)
{
- return _odp_time_convert_to_ns(_odp_time_cur());
+ return _odp_time_to_ns(_odp_time_cur());
}
_ODP_INLINE uint64_t odp_time_local_strict_ns(void)
{
- return _odp_time_convert_to_ns(_odp_time_cur_strict());
+ return _odp_time_to_ns(_odp_time_cur_strict());
}
_ODP_INLINE uint64_t odp_time_global_strict_ns(void)
{
- return _odp_time_convert_to_ns(_odp_time_cur_strict());
+ return _odp_time_to_ns(_odp_time_cur_strict());
}
_ODP_INLINE uint64_t odp_time_to_ns(odp_time_t time)
{
- return _odp_time_convert_to_ns(time);
+ return _odp_time_to_ns(time);
}
_ODP_INLINE int odp_time_cmp(odp_time_t t2, odp_time_t t1)
@@ -191,6 +132,44 @@ _ODP_INLINE odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2)
return time;
}
+_ODP_INLINE odp_time_t odp_time_local_from_ns(uint64_t ns)
+{
+ return _odp_time_from_ns(ns);
+}
+
+_ODP_INLINE odp_time_t odp_time_global_from_ns(uint64_t ns)
+{
+ return _odp_time_from_ns(ns);
+}
+
+_ODP_INLINE uint64_t odp_time_local_res(void)
+{
+ return _odp_time_res();
+}
+
+_ODP_INLINE uint64_t odp_time_global_res(void)
+{
+ return _odp_time_res();
+}
+
+_ODP_INLINE void odp_time_wait_until(odp_time_t time)
+{
+ odp_time_t cur;
+
+ do {
+ cur = _odp_time_cur();
+ } while (odp_time_cmp(time, cur) > 0);
+}
+
+_ODP_INLINE void odp_time_wait_ns(uint64_t ns)
+{
+ odp_time_t cur = _odp_time_cur();
+ odp_time_t wait = _odp_time_from_ns(ns);
+ odp_time_t end_time = odp_time_sum(cur, wait);
+
+ odp_time_wait_until(end_time);
+}
+
/** @endcond */
#endif
diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c
deleted file mode 100644
index 3498008f1..000000000
--- a/platform/linux-generic/odp_time.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/* Copyright (c) 2013-2018, Linaro Limited
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <odp_posix_extensions.h>
-
-#include <time.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include <odp/api/time.h>
-#include <odp/api/hints.h>
-#include <odp_debug_internal.h>
-#include <odp_init_internal.h>
-#include <odp/api/plat/time_inlines.h>
-
-ODP_STATIC_ASSERT(_ODP_TIMESPEC_SIZE >= (sizeof(struct timespec)),
- "_ODP_TIMESPEC_SIZE too small");
-
-#include <odp/visibility_begin.h>
-
-_odp_time_global_t _odp_time_glob;
-
-/*
- * Posix timespec based functions
- */
-
-static inline uint64_t time_spec_diff_nsec(struct timespec *t2,
- struct timespec *t1)
-{
- struct timespec diff;
- uint64_t nsec;
-
- diff.tv_sec = t2->tv_sec - t1->tv_sec;
- diff.tv_nsec = t2->tv_nsec - t1->tv_nsec;
-
- if (diff.tv_nsec < 0) {
- diff.tv_nsec += ODP_TIME_SEC_IN_NS;
- diff.tv_sec -= 1;
- }
-
- nsec = (diff.tv_sec * ODP_TIME_SEC_IN_NS) + diff.tv_nsec;
-
- return nsec;
-}
-
-odp_time_t _odp_timespec_cur(void)
-{
- int ret;
- odp_time_t time;
- struct timespec sys_time;
- struct timespec *start_time;
-
- start_time = (struct timespec *)(uintptr_t)&_odp_time_glob.timespec;
-
- ret = clock_gettime(CLOCK_MONOTONIC_RAW, &sys_time);
- if (odp_unlikely(ret != 0))
- _ODP_ABORT("clock_gettime failed\n");
-
- time.nsec = time_spec_diff_nsec(&sys_time, start_time);
-
- return time;
-}
-
-#include <odp/visibility_end.h>
-
-static inline uint64_t time_spec_res(void)
-{
- int ret;
- struct timespec tres;
-
- ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres);
- if (odp_unlikely(ret != 0))
- _ODP_ABORT("clock_getres failed\n");
-
- return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec;
-}
-
-static inline odp_time_t time_spec_from_ns(uint64_t ns)
-{
- odp_time_t time;
-
- time.nsec = ns;
-
- return time;
-}
-
-/*
- * HW time counter based functions
- */
-
-static inline uint64_t time_hw_res(void)
-{
- return _odp_time_glob.hw_freq_hz;
-}
-
-static inline odp_time_t time_hw_from_ns(uint64_t ns)
-{
- odp_time_t time;
- uint64_t count;
- uint64_t freq_hz = _odp_time_glob.hw_freq_hz;
- uint64_t sec = 0;
-
- if (ns >= ODP_TIME_SEC_IN_NS) {
- sec = ns / ODP_TIME_SEC_IN_NS;
- ns = ns - sec * ODP_TIME_SEC_IN_NS;
- }
-
- count = sec * freq_hz;
- count += (ns * freq_hz) / ODP_TIME_SEC_IN_NS;
-
- time.count = count;
-
- return time;
-}
-
-/*
- * Common functions
- */
-
-static inline uint64_t time_res(void)
-{
- if (_odp_time_glob.use_hw)
- return time_hw_res();
-
- return time_spec_res();
-}
-
-static inline odp_time_t time_from_ns(uint64_t ns)
-{
- if (_odp_time_glob.use_hw)
- return time_hw_from_ns(ns);
-
- return time_spec_from_ns(ns);
-}
-
-static inline void time_wait_until(odp_time_t time)
-{
- odp_time_t cur;
-
- do {
- cur = _odp_time_cur();
- } while (odp_time_cmp(time, cur) > 0);
-}
-
-odp_time_t odp_time_local_from_ns(uint64_t ns)
-{
- return time_from_ns(ns);
-}
-
-odp_time_t odp_time_global_from_ns(uint64_t ns)
-{
- return time_from_ns(ns);
-}
-
-uint64_t odp_time_local_res(void)
-{
- return time_res();
-}
-
-uint64_t odp_time_global_res(void)
-{
- return time_res();
-}
-
-void odp_time_wait_ns(uint64_t ns)
-{
- odp_time_t cur = _odp_time_cur();
- odp_time_t wait = time_from_ns(ns);
- odp_time_t end_time = odp_time_sum(cur, wait);
-
- time_wait_until(end_time);
-}
-
-void odp_time_wait_until(odp_time_t time)
-{
- time_wait_until(time);
-}
-
-int _odp_time_init_global(void)
-{
- struct timespec *timespec;
- int ret = 0;
- _odp_time_global_t *global = &_odp_time_glob;
-
- memset(global, 0, sizeof(_odp_time_global_t));
-
- if (_odp_cpu_has_global_time()) {
- global->use_hw = 1;
- global->hw_freq_hz = _odp_cpu_global_time_freq();
-
- if (global->hw_freq_hz == 0)
- return -1;
-
- _ODP_PRINT("HW time counter freq: %" PRIu64 " hz\n\n", global->hw_freq_hz);
-
- global->hw_start = _odp_cpu_global_time();
- return 0;
- }
-
- timespec = (struct timespec *)(uintptr_t)global->timespec;
- timespec->tv_sec = 0;
- timespec->tv_nsec = 0;
-
- ret = clock_gettime(CLOCK_MONOTONIC_RAW, timespec);
-
- return ret;
-}
-
-int _odp_time_term_global(void)
-{
- return 0;
-}