diff mbox series

[XTF,1/6] time: introduce time managment in xtf

Message ID 20200417070528.48329-2-wipawel@amazon.de (mailing list archive)
State New, archived
Headers show
Series Add time management functionality | expand

Commit Message

Wieczorkiewicz, Pawel April 17, 2020, 7:05 a.m. UTC
From: Paul Semel <phentex@amazon.de>

This commit introduces basic time management functionality.
For synchronization purpose, we do really want to be able to
"control" time.

Add since_boot_time() that gets the time in nanoseconds from the
moment the VM has booted.

Signed-off-by: Paul Semel <phentex@amazon.de>
Signed-off-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
---
 build/files.mk     |  1 +
 common/time.c      | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/xtf/lib.h  | 18 ++++++++++++
 include/xtf/time.h | 28 ++++++++++++++++++
 4 files changed, 132 insertions(+)
 create mode 100644 common/time.c
 create mode 100644 include/xtf/time.h
diff mbox series

Patch

diff --git a/build/files.mk b/build/files.mk
index dfa27e4..6286317 100644
--- a/build/files.mk
+++ b/build/files.mk
@@ -16,6 +16,7 @@  obj-perarch += $(ROOT)/common/libc/vsnprintf.o
 obj-perarch += $(ROOT)/common/report.o
 obj-perarch += $(ROOT)/common/setup.o
 obj-perarch += $(ROOT)/common/xenbus.o
+obj-perarch += $(ROOT)/common/time.o
 
 obj-perenv += $(ROOT)/arch/x86/decode.o
 obj-perenv += $(ROOT)/arch/x86/desc.o
diff --git a/common/time.c b/common/time.c
new file mode 100644
index 0000000..b9a6531
--- /dev/null
+++ b/common/time.c
@@ -0,0 +1,85 @@ 
+#include <xtf/types.h>
+#include <xtf/traps.h>
+#include <xtf/time.h>
+#include <xtf/atomic.h>
+
+/* This function was taken from mini-os source code */
+/* It returns ((delta << shift) * mul_frac) >> 32 */
+static inline uint64_t scale_delta(uint64_t delta, uint32_t mul_frac, int shift)
+{
+    uint64_t product;
+#ifdef __i386__
+    uint32_t tmp1, tmp2;
+#endif
+
+    if ( shift < 0 )
+        delta >>= -shift;
+    else
+        delta <<= shift;
+
+#ifdef __i386__
+    __asm__ (
+            "mul  %5       ; "
+            "mov  %4,%%eax ; "
+            "mov  %%edx,%4 ; "
+            "mul  %5       ; "
+            "add  %4,%%eax ; "
+            "xor  %5,%5    ; "
+            "adc  %5,%%edx ; "
+            : "=A" (product), "=r" (tmp1), "=r" (tmp2)
+            : "a" ((uint32_t)delta), "1" ((uint32_t)(delta >> 32)), "2" (mul_frac) );
+#else
+    __asm__ (
+            "mul %%rdx ; shrd $32,%%rdx,%%rax"
+            : "=a" (product) : "0" (delta), "d" ((uint64_t)mul_frac) );
+#endif
+
+    return product;
+}
+
+
+#if defined(__i386__)
+uint32_t since_boot_time(void)
+#else
+uint64_t since_boot_time(void)
+#endif
+{
+    unsigned long old_tsc, tsc;
+#if defined(__i386__)
+    uint32_t system_time;
+#else
+    uint64_t system_time;
+#endif
+    uint32_t ver1, ver2;
+
+    do {
+        do {
+            ver1 = shared_info.vcpu_info[0].time.version;
+            smp_rmb();
+        } while ( (ver1 & 1) == 1 );
+
+        system_time = shared_info.vcpu_info[0].time.system_time;
+        old_tsc = shared_info.vcpu_info[0].time.tsc_timestamp;
+
+        smp_rmb();
+        tsc = rdtscp();
+        ver2 = ACCESS_ONCE(shared_info.vcpu_info[0].time.version);
+        smp_rmb();
+    } while ( ver1 != ver2 );
+
+    system_time += scale_delta(tsc - old_tsc,
+                               shared_info.vcpu_info[0].time.tsc_to_system_mul,
+                               shared_info.vcpu_info[0].time.tsc_shift);
+
+    return system_time;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/include/xtf/lib.h b/include/xtf/lib.h
index 3348464..c3eb10c 100644
--- a/include/xtf/lib.h
+++ b/include/xtf/lib.h
@@ -54,6 +54,24 @@  void __noreturn panic(const char *fmt, ...) __printf(1, 2);
 
 #define ROUNDUP(x, a) (((x) + (a) - 1) & ~((a) - 1))
 
+#ifdef __GCC_ASM_FLAG_OUTPUTS__
+# define ASM_FLAG_OUT(yes, no) yes
+#else
+# define ASM_FLAG_OUT(yes, no) no
+#endif
+
+static inline uint64_t rdtsc (void) {
+  unsigned int low, high;
+  asm volatile ("rdtsc" : "=a" (low), "=d" (high));
+  return ((uint64_t) high << 32) | low;
+}
+
+static inline uint64_t rdtscp (void) {
+  unsigned int low, high;
+  asm volatile ("rdtscp" : "=a" (low), "=d" (high) :: "ecx");
+  return ((uint64_t) high << 32) | low;
+}
+
 void heapsort(void *base, size_t nmemb, size_t size,
               int (*compar)(const void *, const void *),
               void (*swap)(void *, void *));
diff --git a/include/xtf/time.h b/include/xtf/time.h
new file mode 100644
index 0000000..e30d109
--- /dev/null
+++ b/include/xtf/time.h
@@ -0,0 +1,28 @@ 
+/**
+ * @file include/xtf/time.h
+ *
+ * Time management
+ */
+#ifndef XTF_TIME_H
+# define XTF_TIME_H
+
+#include <xtf/types.h>
+
+#if defined(__i386__)
+/* Time from boot in nanoseconds */
+uint32_t since_boot_time(void);
+#else
+uint64_t since_boot_time(void);
+#endif
+
+#endif /* XTF_TIME_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */