/* * Copyright (C) by Argonne National Laboratory * See COPYRIGHT in top-level directory */ #ifndef MPL_TIMER_LINUX86_CYCLE_H_INCLUDED #define MPL_TIMER_LINUX86_CYCLE_H_INCLUDED static inline int MPL_wtime(MPL_time_t * timeval) { /* The rdtsc instruction is not a "serializing" instruction, so the processor is free to reorder it. In order to get more accurate timing numbers with rdtsc, we need to put a serializing instruction, like cpuid, before rdtsc. X86_64 architectures have the rdtscp instruction which is synchronizing, we use this when we can. */ #ifdef MPL_LINUX86_CYCLE_RDTSCP unsigned long long lower, upper, extra; __asm__ __volatile__("rdtscp\n":"=a"(lower), "=d"(upper), "=c"(extra)); *timeval = (upper << 32) + lower; #elif defined(MPL_LINUX86_CYCLE_CPUID_RDTSC64) unsigned long long lower, upper; __asm__ __volatile__("cpuid ; rdtsc":"=a"(lower), "=d"(upper)::"ebx", "ecx"); *timeval = (upper << 32) + lower; #elif defined(MPL_LINUX86_CYCLE_CPUID_RDTSC32) __asm__ __volatile__("cpuid ; rdtsc":"=A"(*timeval)::"ebx", "ecx"); #elif defined(MPL_LINUX86_CYCLE_RDTSC) /* The configure test using cpuid must have failed, try just rdtsc by itself */ __asm__ __volatile__("rdtsc":"=A"(*timeval)); #else #error Dont know which Linux timer to use #endif return MPL_SUCCESS; } #endif /* MPL_TIMER_LINUX86_CYCLE_H_INCLUDED */