本文共 3025 字,大约阅读时间需要 10 分钟。
dpdk 中有提供time没看负责定时操作,同时在example/timer中有提供一个测试code可以告知大家如何使用time 没看从meson.build中可以看出源文件只有一个main.cdeps += 'timer'sources = files( 'main.c')从makefile中可以看出binary的名字叫timer,这个main.c 可以同时被build 为动态链接库和静态链接库# binary nameAPP = timer# all source are stored in SRCS-ySRCS-y := main.c# Build using pkg-config variables if possible$(shell pkg-config --exists libdpdk)ifeq ($(.SHELLSTATUS),0)all: shared.PHONY: shared staticshared: build/$(APP)-shared ln -sf $(APP)-shared build/$(APP)static: build/$(APP)-static ln -sf $(APP)-static build/$(APP)CFLAGS += -O3CFLAGS += $(WERROR_FLAGS)与此同时可以看到优化级别是O3timer的入口函数为main函数intmain(int argc, char **argv){ int ret; uint64_t hz; unsigned lcore_id; /* init EAL */ #初始化running time 环境 ret = rte_eal_init(argc, argv); if (ret < 0) rte_panic("Cannot init EAL\n"); #由于我们是测试timer,因此要用到rte提供的time子系统 /* init RTE timer library */ rte_timer_subsystem_init(); /* init timer structures */ #初始化两个timer的回调函数 rte_timer_init(&timer0); rte_timer_init(&timer1); /* load timer0, every second, on master lcore, reloaded automatically */ #timer 0在主核上(本例中是当前cpu),不一定是cpu0,自动状态 hz = rte_get_timer_hz(); #获取当前cpu lcore_id = rte_lcore_id(); #设置timer运行的模式,例如这里就是周期运行PERIODICAL,周期是1s rte_timer_reset(&timer0, hz, PERIODICAL, lcore_id, timer0_cb, NULL); /* load timer1, every second/3, on next lcore, reloaded manually */ #timer1 在主cpu的下一个cpu上,如果主cpu 是0 的话,则下一个cpu可能是1 lcore_id = rte_get_next_lcore(lcore_id, 0, 1); #设置timer运行的模式,例如这里就是单次运行,如果要周期运行的话,需要在timer1的回调函数中继续调用rte_timer_reset #设置timer,运行周期是0.33s rte_timer_reset(&timer1, hz/3, SINGLE, lcore_id, timer1_cb, NULL); /* call lcore_mainloop() on every slave lcore */ #再出了当前cpu上外的cpu上跑lcore_mainloop RTE_LCORE_FOREACH_SLAVE(lcore_id) { rte_eal_remote_launch(lcore_mainloop, NULL, lcore_id); } /* call it on master lcore too */ #在当前cpu上跑 (void) lcore_mainloop(NULL); return 0;}static voidtimer0_cb(__attribute__((unused)) struct rte_timer *tim, __attribute__((unused)) void *arg){ static unsigned counter = 0; unsigned lcore_id = rte_lcore_id(); printf("%s() on lcore %u\n", __func__, lcore_id); /* this timer is automatically reloaded until we decide to * stop it, when counter reaches 20. */ if ((counter ++) == 20) rte_timer_stop(tim);}我们看一下timer0_cb的实现,运行20次就到期了,每次一秒的话,则20s后这个timer就停止了我们看看lcore_mainloop的实现,如上所示每个cpu上都会跑一个lcore_mainloopstatic __attribute__((noreturn)) intlcore_mainloop(__attribute__((unused)) void *arg){ uint64_t prev_tsc = 0, cur_tsc, diff_tsc; unsigned lcore_id; lcore_id = rte_lcore_id(); printf("Starting mainloop on core %u\n", lcore_id); while (1) { /* * Call the timer handler on each core: as we don't * need a very precise timer, so only call * rte_timer_manage() every ~10ms (at 2Ghz). In a real * application, this will enhance performances as * reading the HPET timer is not efficient. */ cur_tsc = rte_rdtsc(); diff_tsc = cur_tsc - prev_tsc; #从这里知道dpdk中通过rte_timer_manage来管理当前core上的定时器,并且定时器的分辨率是TIMER_RESOLUTION_CYCLES if (diff_tsc > TIMER_RESOLUTION_CYCLES) { rte_timer_manage(); prev_tsc = cur_tsc; } }}
转载地址:http://ynnmi.baihongyu.com/