Add check for invariant TSC on x86 and use TSC is default clock if reliable
[fio.git] / arch / arch-x86-common.h
diff --git a/arch/arch-x86-common.h b/arch/arch-x86-common.h
new file mode 100644 (file)
index 0000000..1e62354
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef FIO_ARCH_X86_COMMON
+#define FIO_ARCH_X86_COMMON
+
+static inline void do_cpuid(unsigned int *eax, unsigned int *ebx,
+                           unsigned int *ecx, unsigned int *edx)
+{
+       unsigned int id = *eax;
+
+       asm("movl %4, %%eax;"
+           "cpuid;"
+           "movl %%eax, %0;"
+           "movl %%ebx, %1;"
+           "movl %%ecx, %2;"
+           "movl %%edx, %3;"
+               : "=r" (*eax), "=r" (*ebx), "=r" (*ecx), "=r" (*edx)
+               : "r" (id)
+               : "eax", "ebx", "ecx", "edx");
+}
+
+#define ARCH_HAVE_INIT
+extern int tsc_reliable;
+static inline int arch_init(char *envp[])
+{
+       unsigned int eax, ebx, ecx, edx;
+
+       /*
+        * Check for TSC
+        */
+       eax = 1;
+       do_cpuid(&eax, &ebx, &ecx, &edx);
+       if (!(edx & (1U << 4)))
+               return 0;
+
+       /*
+        * Check for constant rate and synced (across cores) TSC
+        */
+       eax = 0x80000007;
+       do_cpuid(&eax, &ebx, &ecx, &edx);
+       tsc_reliable = edx & (1U << 8);
+       return 0;
+}
+
+#endif