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