1*d30ea906Sjfb8856606..  SPDX-License-Identifier: BSD-3-Clause
2*d30ea906Sjfb8856606    Copyright(c) 2010-2014 Intel Corporation.
3a9643ea8Slogwang
4a9643ea8Slogwang.. _Timer_Library:
5a9643ea8Slogwang
6a9643ea8SlogwangTimer Library
7a9643ea8Slogwang=============
8a9643ea8Slogwang
9a9643ea8SlogwangThe Timer library provides a timer service to DPDK execution units to enable execution of callback functions asynchronously.
10a9643ea8SlogwangFeatures of the library are:
11a9643ea8Slogwang
12a9643ea8Slogwang*   Timers can be periodic (multi-shot) or single (one-shot).
13a9643ea8Slogwang
14a9643ea8Slogwang*   Timers can be loaded from one core and executed on another. It has to be specified in the call to rte_timer_reset().
15a9643ea8Slogwang
16a9643ea8Slogwang*   Timers provide high precision (depends on the call frequency to rte_timer_manage() that checks timer expiration for the local core).
17a9643ea8Slogwang
18a9643ea8Slogwang*   If not required in the application, timers can be disabled at compilation time by not calling the rte_timer_manage() to increase performance.
19a9643ea8Slogwang
20a9643ea8SlogwangThe timer library uses the rte_get_timer_cycles() function that uses the High Precision Event Timer (HPET)
21a9643ea8Slogwangor the CPUs Time Stamp Counter (TSC) to provide a reliable time reference.
22a9643ea8Slogwang
23a9643ea8SlogwangThis library provides an interface to add, delete and restart a timer. The API is based on BSD callout() with a few differences.
24a9643ea8SlogwangRefer to the `callout manual <http://www.daemon-systems.org/man/callout.9.html>`_.
25a9643ea8Slogwang
26a9643ea8SlogwangImplementation Details
27a9643ea8Slogwang----------------------
28a9643ea8Slogwang
29a9643ea8SlogwangTimers are tracked on a per-lcore basis,
30a9643ea8Slogwangwith all pending timers for a core being maintained in order of timer expiry in a skiplist data structure.
31a9643ea8SlogwangThe skiplist used has ten levels and each entry in the table appears in each level with probability ¼^level.
32a9643ea8SlogwangThis means that all entries are present in level 0, 1 in every 4 entries is present at level 1,
33a9643ea8Slogwangone in every 16 at level 2 and so on up to level 9.
34a9643ea8SlogwangThis means that adding and removing entries from the timer list for a core can be done in log(n) time,
35a9643ea8Slogwangup to 4^10 entries, that is, approximately 1,000,000 timers per lcore.
36a9643ea8Slogwang
37a9643ea8SlogwangA timer structure contains a special field called status,
38a9643ea8Slogwangwhich is a union of a timer state (stopped, pending, running, config) and an owner (lcore id).
39a9643ea8SlogwangDepending on the timer state, we know if a timer is present in a list or not:
40a9643ea8Slogwang
41a9643ea8Slogwang*   STOPPED: no owner, not in a list
42a9643ea8Slogwang
43a9643ea8Slogwang*   CONFIG: owned by a core, must not be modified by another core, maybe in a list or not, depending on previous state
44a9643ea8Slogwang
45a9643ea8Slogwang*   PENDING: owned by a core, present in a list
46a9643ea8Slogwang
47a9643ea8Slogwang*   RUNNING: owned by a core, must not be modified by another core, present in a list
48a9643ea8Slogwang
49a9643ea8SlogwangResetting or stopping a timer while it is in a CONFIG or RUNNING state is not allowed.
50a9643ea8SlogwangWhen modifying the state of a timer,
51a9643ea8Slogwanga Compare And Swap instruction should be used to guarantee that the status (state+owner) is modified atomically.
52a9643ea8Slogwang
53a9643ea8SlogwangInside the rte_timer_manage() function,
54a9643ea8Slogwangthe skiplist is used as a regular list by iterating along the level 0 list, which contains all timer entries,
55a9643ea8Slogwanguntil an entry which has not yet expired has been encountered.
56a9643ea8SlogwangTo improve performance in the case where there are entries in the timer list but none of those timers have yet expired,
57a9643ea8Slogwangthe expiry time of the first list entry is maintained within the per-core timer list structure itself.
58a9643ea8SlogwangOn 64-bit platforms, this value can be checked without the need to take a lock on the overall structure.
59a9643ea8Slogwang(Since expiry times are maintained as 64-bit values,
60a9643ea8Slogwanga check on the value cannot be done on 32-bit platforms without using either a compare-and-swap (CAS) instruction or using a lock,
61a9643ea8Slogwangso this additional check is skipped in favor of checking as normal once the lock has been taken.)
62a9643ea8SlogwangOn both 64-bit and 32-bit platforms,
63a9643ea8Slogwanga call to rte_timer_manage() returns without taking a lock in the case where the timer list for the calling core is empty.
64a9643ea8Slogwang
65a9643ea8SlogwangUse Cases
66a9643ea8Slogwang---------
67a9643ea8Slogwang
68a9643ea8SlogwangThe timer library is used for periodic calls, such as garbage collectors, or some state machines (ARP, bridging, and so on).
69a9643ea8Slogwang
70a9643ea8SlogwangReferences
71a9643ea8Slogwang----------
72a9643ea8Slogwang
73a9643ea8Slogwang*   `callout manual <http://www.daemon-systems.org/man/callout.9.html>`_
74a9643ea8Slogwang    - The callout facility that provides timers with a mechanism to execute a function at a given time.
75a9643ea8Slogwang
76a9643ea8Slogwang*   `HPET <http://en.wikipedia.org/wiki/HPET>`_
77a9643ea8Slogwang    - Information about the High Precision Event Timer (HPET).
78