X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=doc%2Fguides%2Fsample_app_ug%2Ftimer.rst;h=d8c6d9a656993cccc0c108390e6145ec8bc8fee8;hb=34fd4373ce76efd0236e59397c495762c2ec9e64;hp=c572db58003456cf414c3c60db329bf4808610c7;hpb=cb056611a8ed9ab9024f3b91bf26e97255194514;p=dpdk.git diff --git a/doc/guides/sample_app_ug/timer.rst b/doc/guides/sample_app_ug/timer.rst index c572db5800..d8c6d9a656 100644 --- a/doc/guides/sample_app_ug/timer.rst +++ b/doc/guides/sample_app_ug/timer.rst @@ -21,7 +21,7 @@ To run the example in linux environment: .. code-block:: console - $ ./build/timer -l 0-3 -n 4 + $ .//examples/dpdk-timer -l 0-3 -n 4 Refer to the *DPDK Getting Started Guide* for general information on running applications and the Environment Abstraction Layer (EAL) options. @@ -36,55 +36,29 @@ Initialization and Main Loop In addition to EAL initialization, the timer subsystem must be initialized, by calling the rte_timer_subsystem_init() function. -.. code-block:: c - - /* init EAL */ - - ret = rte_eal_init(argc, argv); - if (ret < 0) - rte_panic("Cannot init EAL\n"); - - /* init RTE timer library */ - - rte_timer_subsystem_init(); +.. literalinclude:: ../../../examples/timer/main.c + :language: c + :start-after: Init EAL. 8< + :end-before: >8 End of init EAL. + :dedent: 1 After timer creation (see the next paragraph), the main loop is executed on each worker lcore using the well-known rte_eal_remote_launch() and also on the main. -.. code-block:: c - - /* call lcore_mainloop() on every worker lcore */ - RTE_LCORE_FOREACH_WORKER(lcore_id) { - rte_eal_remote_launch(lcore_mainloop, NULL, lcore_id); - } - - /* call it on main lcore too */ - - (void) lcore_mainloop(NULL); +.. literalinclude:: ../../../examples/timer/main.c + :language: c + :start-after: Call lcore_mainloop() on every worker lcore. 8< + :end-before: >8 End of call lcore_mainloop() on every worker lcore. + :dedent: 1 The main loop is very simple in this example: -.. code-block:: c - - 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 2 GHz). 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; - - if (diff_tsc > TIMER_RESOLUTION_CYCLES) { - rte_timer_manage(); - prev_tsc = cur_tsc; - } - } +.. literalinclude:: ../../../examples/timer/main.c + :language: c + :start-after: Main loop. 8< + :end-before: >8 End of main loop. + :dedent: 1 As explained in the comment, it is better to use the TSC register (as it is a per-lcore register) to check if the rte_timer_manage() function must be called or not. @@ -96,12 +70,11 @@ Managing Timers In the main() function, the two timers are initialized. This call to rte_timer_init() is necessary before doing any other operation on the timer structure. -.. code-block:: c - - /* init timer structures */ - - rte_timer_init(&timer0); - rte_timer_init(&timer1); +.. literalinclude:: ../../../examples/timer/main.c + :language: c + :start-after: Init timer structures. 8< + :end-before: >8 End of init timer structures. + :dedent: 1 Then, the two timers are configured: @@ -113,64 +86,24 @@ Then, the two timers are configured: The SINGLE flag means that the timer expires only once and must be reloaded manually if required. The callback function is timer1_cb(). -.. code-block:: c - - /* load timer0, every second, on main lcore, reloaded automatically */ - - hz = rte_get_hpet_hz(); - - lcore_id = rte_lcore_id(); - - rte_timer_reset(&timer0, hz, PERIODICAL, lcore_id, timer0_cb, NULL); - - /* load timer1, every second/3, on next lcore, reloaded manually */ - - lcore_id = rte_get_next_lcore(lcore_id, 0, 1); - - rte_timer_reset(&timer1, hz/3, SINGLE, lcore_id, timer1_cb, NULL); +.. literalinclude:: ../../../examples/timer/main.c + :language: c + :start-after: Load timer0, every second, on main lcore, reloaded automatically. 8< + :end-before: >8 End of two timers configured. + :dedent: 1 The callback for the first timer (timer0) only displays a message until a global counter reaches 20 (after 20 seconds). In this case, the timer is stopped using the rte_timer_stop() function. -.. code-block:: c - - /* timer0 callback */ - - static void - timer0_cb(__rte_unused struct rte_timer *tim, __rte_unused void *arg) - { - static unsigned counter = 0; - - unsigned lcore_id = rte_lcore_id(); - - printf("%s() on lcore %u\n", FUNCTION , lcore_id); - - /* this timer is automatically reloaded until we decide to stop it, when counter reaches 20. */ - - if ((counter ++) == 20) - rte_timer_stop(tim); - } +.. literalinclude:: ../../../examples/timer/main.c + :language: c + :start-after: timer0 callback. 8< + :end-before: >8 End of timer0 callback. The callback for the second timer (timer1) displays a message and reloads the timer on the next lcore, using the rte_timer_reset() function: -.. code-block:: c - - /* timer1 callback */ - - static void - timer1_cb(__rte_unused struct rte_timer *tim, __rte_unused void *arg) - { - unsigned lcore_id = rte_lcore_id(); - uint64_t hz; - - printf("%s() on lcore %u\\n", FUNCTION , lcore_id); - - /* reload it on another lcore */ - - hz = rte_get_hpet_hz(); - - lcore_id = rte_get_next_lcore(lcore_id, 0, 1); - - rte_timer_reset(&timer1, hz/3, SINGLE, lcore_id, timer1_cb, NULL); - } +.. literalinclude:: ../../../examples/timer/main.c + :language: c + :start-after: timer1 callback. 8< + :end-before: >8 End of timer1 callback.