机器时钟实现高精度定时

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 +++

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值