13998e2a0SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 23998e2a0SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation 3af75078fSIntel */ 4af75078fSIntel 5af75078fSIntel #include <stdio.h> 6af75078fSIntel #include <string.h> 7af75078fSIntel #include <stdint.h> 8af75078fSIntel #include <errno.h> 9af75078fSIntel #include <sys/queue.h> 10af75078fSIntel 11af75078fSIntel #include <rte_common.h> 12af75078fSIntel #include <rte_memory.h> 13af75078fSIntel #include <rte_launch.h> 14af75078fSIntel #include <rte_eal.h> 15af75078fSIntel #include <rte_per_lcore.h> 16af75078fSIntel #include <rte_lcore.h> 17af75078fSIntel #include <rte_cycles.h> 18af75078fSIntel #include <rte_timer.h> 19af75078fSIntel #include <rte_debug.h> 20af75078fSIntel 21af75078fSIntel #define TIMER_RESOLUTION_CYCLES 20000000ULL /* around 10ms at 2 Ghz */ 22af75078fSIntel 23af75078fSIntel static struct rte_timer timer0; 24af75078fSIntel static struct rte_timer timer1; 25af75078fSIntel 26af75078fSIntel /* timer0 callback */ 27af75078fSIntel static void 28f2fc83b4SThomas Monjalon timer0_cb(__rte_unused struct rte_timer *tim, 29f2fc83b4SThomas Monjalon __rte_unused void *arg) 30af75078fSIntel { 31af75078fSIntel static unsigned counter = 0; 32af75078fSIntel unsigned lcore_id = rte_lcore_id(); 33af75078fSIntel 34af75078fSIntel printf("%s() on lcore %u\n", __func__, lcore_id); 35af75078fSIntel 36af75078fSIntel /* this timer is automatically reloaded until we decide to 37af75078fSIntel * stop it, when counter reaches 20. */ 38af75078fSIntel if ((counter ++) == 20) 39af75078fSIntel rte_timer_stop(tim); 40af75078fSIntel } 41af75078fSIntel 42af75078fSIntel /* timer1 callback */ 43af75078fSIntel static void 44f2fc83b4SThomas Monjalon timer1_cb(__rte_unused struct rte_timer *tim, 45f2fc83b4SThomas Monjalon __rte_unused void *arg) 46af75078fSIntel { 47af75078fSIntel unsigned lcore_id = rte_lcore_id(); 48af75078fSIntel uint64_t hz; 49af75078fSIntel 50af75078fSIntel printf("%s() on lcore %u\n", __func__, lcore_id); 51af75078fSIntel 52af75078fSIntel /* reload it on another lcore */ 53e987449cSIntel hz = rte_get_timer_hz(); 54af75078fSIntel lcore_id = rte_get_next_lcore(lcore_id, 0, 1); 55af75078fSIntel rte_timer_reset(tim, hz/3, SINGLE, lcore_id, timer1_cb, NULL); 56af75078fSIntel } 57af75078fSIntel 58*ddcd7640SThomas Monjalon static __rte_noreturn int 59f2fc83b4SThomas Monjalon lcore_mainloop(__rte_unused void *arg) 60af75078fSIntel { 61af75078fSIntel uint64_t prev_tsc = 0, cur_tsc, diff_tsc; 62af75078fSIntel unsigned lcore_id; 63af75078fSIntel 64af75078fSIntel lcore_id = rte_lcore_id(); 65af75078fSIntel printf("Starting mainloop on core %u\n", lcore_id); 66af75078fSIntel 67af75078fSIntel while (1) { 68af75078fSIntel /* 69af75078fSIntel * Call the timer handler on each core: as we don't 70af75078fSIntel * need a very precise timer, so only call 71af75078fSIntel * rte_timer_manage() every ~10ms (at 2Ghz). In a real 72af75078fSIntel * application, this will enhance performances as 73af75078fSIntel * reading the HPET timer is not efficient. 74af75078fSIntel */ 75af75078fSIntel cur_tsc = rte_rdtsc(); 76af75078fSIntel diff_tsc = cur_tsc - prev_tsc; 77af75078fSIntel if (diff_tsc > TIMER_RESOLUTION_CYCLES) { 78af75078fSIntel rte_timer_manage(); 79af75078fSIntel prev_tsc = cur_tsc; 80af75078fSIntel } 81af75078fSIntel } 82af75078fSIntel } 83af75078fSIntel 84af75078fSIntel int 8598a16481SDavid Marchand main(int argc, char **argv) 86af75078fSIntel { 87af75078fSIntel int ret; 88af75078fSIntel uint64_t hz; 89af75078fSIntel unsigned lcore_id; 90af75078fSIntel 91af75078fSIntel /* init EAL */ 92af75078fSIntel ret = rte_eal_init(argc, argv); 93af75078fSIntel if (ret < 0) 94af75078fSIntel rte_panic("Cannot init EAL\n"); 95af75078fSIntel 96af75078fSIntel /* init RTE timer library */ 97af75078fSIntel rte_timer_subsystem_init(); 98af75078fSIntel 99af75078fSIntel /* init timer structures */ 100af75078fSIntel rte_timer_init(&timer0); 101af75078fSIntel rte_timer_init(&timer1); 102af75078fSIntel 103af75078fSIntel /* load timer0, every second, on master lcore, reloaded automatically */ 104e987449cSIntel hz = rte_get_timer_hz(); 105af75078fSIntel lcore_id = rte_lcore_id(); 106af75078fSIntel rte_timer_reset(&timer0, hz, PERIODICAL, lcore_id, timer0_cb, NULL); 107af75078fSIntel 108af75078fSIntel /* load timer1, every second/3, on next lcore, reloaded manually */ 109af75078fSIntel lcore_id = rte_get_next_lcore(lcore_id, 0, 1); 110af75078fSIntel rte_timer_reset(&timer1, hz/3, SINGLE, lcore_id, timer1_cb, NULL); 111af75078fSIntel 112af75078fSIntel /* call lcore_mainloop() on every slave lcore */ 113af75078fSIntel RTE_LCORE_FOREACH_SLAVE(lcore_id) { 114af75078fSIntel rte_eal_remote_launch(lcore_mainloop, NULL, lcore_id); 115af75078fSIntel } 116af75078fSIntel 117af75078fSIntel /* call it on master lcore too */ 118af75078fSIntel (void) lcore_mainloop(NULL); 119af75078fSIntel 120af75078fSIntel return 0; 121af75078fSIntel } 122