Linux系统使用usleep()以及nanosleep(),受内核时钟频率的影响,如x86默认是100Hz,这样精度只能到0.01s,也就是10ms。
timer_use.c
/* According to POSIX.1-2001 */
#include <sys/select.h>
/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#define RTE_STD_C11
typedef unsigned long int uint64_t;
typedef unsigned int uint32_t;
static inline uint64_t
ipv4_rte_rdtsc(void)
{
union {
uint64_t tsc_64;
RTE_STD_C11
struct {
uint32_t lo_32;
uint32_t hi_32;
};
} tsc;
asm volatile("rdtsc" :
"=a" (tsc.lo_32),
"=d" (tsc.hi_32));
return tsc.tsc_64;
}
int main() {
uint64_t ret, tsc_start, tsc_end, tsc_second, tsc_usecond, tsc_old;
ret = ipv4_rte_rdtsc();
printf("ret:%lu\n", ret);
/* get tsc for second */
tsc_start = ipv4_rte_rdtsc();
sleep(1);
tsc_end = ipv4_rte_rdtsc();
/* get tsc for microsecond */
tsc_second = tsc_end - tsc_start;
tsc_usecond = tsc_second / 1000000;
printf("tsc_start:%lu, tsc_end:%lu, tsc_second:%lu, tsc_usecond:%lu\n", ret, tsc_start, tsc_end, tsc_second, tsc_usecond);
uint64_t tsc_current;
tsc_old = ipv4_rte_rdtsc();
int i;
for (i = 0; i < 5; ) {
tsc_current = ipv4_rte_rdtsc();
if (tsc_current - tsc_old > tsc_usecond) {
i++;
/* usecond timer */
tsc_old = tsc_current;
printf("handle something\n");
}
}
}
测试
gcc timer_use.c -o timer_use
strace -tt ./timer_use
03:53:46.526131 execve("./timer_use", ["./timer_use"], [/* 14 vars */]) = 0
03:53:46.526272 brk(NULL) = 0x602000
03:53:46.526315 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff6000
03:53:46.526360 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
03:53:46.526404 open("tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
03:53:46.526444 open("tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
03:53:46.526479 open("x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
03:53:46.526514 open("libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
03:53:46.526549 open("/usr/local/postgres/pglib/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
03:53:46.526588 stat("/usr/local/postgres/pglib/tls/x86_64", 0x7fffffffd220) = -1 ENOENT (No such file or directory)
03:53:46.526624 open("/usr/local/postgres/pglib/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
03:53:46.526662 stat("/usr/local/postgres/pglib/tls", 0x7fffffffd220) = -1 ENOENT (No such file or directory)
03:53:46.526698 open("/usr/local/postgres/pglib/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
03:53:46.526736 stat("/usr/local/postgres/pglib/x86_64", 0x7fffffffd220) = -1 ENOENT (No such file or directory)
03:53:46.526772 open("/usr/local/postgres/pglib/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
03:53:46.526808 stat("/usr/local/postgres/pglib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
03:53:46.526849 open("/sdd/tmp/extlib/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
03:53:46.526886 stat("/sdd/tmp/extlib/tls/x86_64", 0x7fffffffd220) = -1 ENOENT (No such file or directory)
03:53:46.526922 open("/sdd/tmp/extlib/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
03:53:46.526957 stat("/sdd/tmp/extlib/tls", 0x7fffffffd220) = -1 ENOENT (No such file or directory)
03:53:46.526992 open("/sdd/tmp/extlib/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
03:53:46.527028 stat("/sdd/tmp/extlib/x86_64", 0x7fffffffd220) = -1 ENOENT (No such file or directory)
03:53:46.527063 open("/sdd/tmp/extlib/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
03:53:46.527100 stat("/sdd/tmp/extlib", {st_mode=S_IFDIR|0755, st_size=8192, ...}) = 0
03:53:46.527136 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
03:53:46.527172 fstat(3, {st_mode=S_IFREG|0644, st_size=9993, ...}) = 0
03:53:46.527206 mmap(NULL, 9993, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffff7ff3000
03:53:46.527240 close(3) = 0
03:53:46.527274 open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
03:53:46.527310 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\35\2\0\0\0\0\0"..., 832) = 832
03:53:46.527347 fstat(3, {st_mode=S_IFREG|0755, st_size=2127336, ...}) = 0
03:53:46.527383 mmap(NULL, 3940800, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff7a18000
03:53:46.527420 mprotect(0x7ffff7bd0000, 2097152, PROT_NONE) = 0
03:53:46.527455 mmap(0x7ffff7dd0000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b8000) = 0x7ffff7dd0000
03:53:46.527497 mmap(0x7ffff7dd6000, 16832, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffff7dd6000
03:53:46.527539 close(3) = 0
03:53:46.527577 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff2000
03:53:46.527615 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff0000
03:53:46.527653 arch_prctl(ARCH_SET_FS, 0x7ffff7ff0740) = 0
03:53:46.527710 mprotect(0x7ffff7dd0000, 16384, PROT_READ) = 0
03:53:46.527747 mprotect(0x600000, 4096, PROT_READ) = 0
03:53:46.527782 mprotect(0x7ffff7ffc000, 4096, PROT_READ) = 0
03:53:46.527816 munmap(0x7ffff7ff3000, 9993) = 0
03:53:46.527868 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
03:53:46.527905 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff5000
03:53:46.527943 write(1, "ret:14282334634150\n", 19ret:14282334634150
) = 19
03:53:46.527981 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
03:53:46.528016 rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
03:53:46.528050 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
03:53:46.528096 nanosleep({1, 0}, 0x7fffffffe870) = 0
03:53:47.528230 write(1, "tsc_start:14282334634150, tsc_en"..., 100tsc_start:14282334634150, tsc_end:14282335028144, tsc_second:14285743869122, tsc_usecond:3408840978
) = 100
03:53:47.528279 write(1, "handle something\n", 17handle something
) = 17
03:53:47.528307 write(1, "handle something\n", 17handle something
) = 17
03:53:47.528333 write(1, "handle something\n", 17handle something
) = 17
03:53:47.528367 write(1, "handle something\n", 17handle something
) = 17
03:53:47.528393 write(1, "handle something\n", 17handle something
) = 17
03:53:47.528419 exit_group(17) = ?
03:53:47.528468 +++ exited with 17 +++