xref: /dpdk/doc/guides/prog_guide/eventdev/event_timer_adapter.rst (revision 41dd9a6bc2d9c6e20e139ad713cc9d172572dd43)
1*41dd9a6bSDavid Young..  SPDX-License-Identifier: BSD-3-Clause
2*41dd9a6bSDavid Young    Copyright(c) 2017 Intel Corporation. All rights reserved.
3*41dd9a6bSDavid Young
4*41dd9a6bSDavid YoungEvent Timer Adapter Library
5*41dd9a6bSDavid Young===========================
6*41dd9a6bSDavid Young
7*41dd9a6bSDavid YoungThe DPDK :doc:`Event Device library <eventdev>`
8*41dd9a6bSDavid Youngintroduces an event driven programming model which presents applications with
9*41dd9a6bSDavid Youngan alternative to the polling model traditionally used in DPDK
10*41dd9a6bSDavid Youngapplications. Event devices can be coupled with arbitrary components to provide
11*41dd9a6bSDavid Youngnew event sources by using **event adapters**. The Event Timer Adapter is one
12*41dd9a6bSDavid Youngsuch adapter; it bridges event devices and timer mechanisms.
13*41dd9a6bSDavid Young
14*41dd9a6bSDavid YoungThe Event Timer Adapter library extends the event driven model
15*41dd9a6bSDavid Youngby introducing a :ref:`new type of event <timer_expiry_event>` that represents
16*41dd9a6bSDavid Younga timer expiration, and providing an API with which adapters can be created or
17*41dd9a6bSDavid Youngdestroyed, and :ref:`event timers <event_timer>` can be armed and canceled.
18*41dd9a6bSDavid Young
19*41dd9a6bSDavid YoungThe Event Timer Adapter library is designed to interface with hardware or
20*41dd9a6bSDavid Youngsoftware implementations of the timer mechanism; it will query an eventdev PMD
21*41dd9a6bSDavid Youngto determine which implementation should be used.  The default software
22*41dd9a6bSDavid Youngimplementation manages timers using the DPDK :doc:`../timer_lib`.
23*41dd9a6bSDavid Young
24*41dd9a6bSDavid YoungExamples of using the API are presented in the `API Overview`_ and
25*41dd9a6bSDavid Young`Processing Timer Expiry Events`_ sections.  Code samples are abstracted and
26*41dd9a6bSDavid Youngare based on the example of handling a TCP retransmission.
27*41dd9a6bSDavid Young
28*41dd9a6bSDavid Young.. _event_timer:
29*41dd9a6bSDavid Young
30*41dd9a6bSDavid YoungEvent Timer struct
31*41dd9a6bSDavid Young------------------
32*41dd9a6bSDavid YoungEvent timers are timers that enqueue a timer expiration event to an event
33*41dd9a6bSDavid Youngdevice upon timer expiration.
34*41dd9a6bSDavid Young
35*41dd9a6bSDavid YoungThe Event Timer Adapter API represents each event timer with a generic struct,
36*41dd9a6bSDavid Youngwhich contains an event and user metadata.  The ``rte_event_timer`` struct is
37*41dd9a6bSDavid Youngdefined in ``rte_event_timer_adapter.h``.
38*41dd9a6bSDavid Young
39*41dd9a6bSDavid Young.. _timer_expiry_event:
40*41dd9a6bSDavid Young
41*41dd9a6bSDavid YoungTimer Expiry Event
42*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~
43*41dd9a6bSDavid Young
44*41dd9a6bSDavid YoungThe event contained by an event timer is enqueued in the event device when the
45*41dd9a6bSDavid Youngtimer expires, and the event device uses the attributes below when scheduling
46*41dd9a6bSDavid Youngit:
47*41dd9a6bSDavid Young
48*41dd9a6bSDavid Young* ``event_queue_id`` - Application should set this to specify an event queue to
49*41dd9a6bSDavid Young  which the timer expiry event should be enqueued
50*41dd9a6bSDavid Young* ``event_priority`` - Application can set this to indicate the priority of the
51*41dd9a6bSDavid Young  timer expiry event in the event queue relative to other events
52*41dd9a6bSDavid Young* ``sched_type`` - Application can set this to specify the scheduling type of
53*41dd9a6bSDavid Young  the timer expiry event
54*41dd9a6bSDavid Young* ``flow_id`` - Application can set this to indicate which flow this timer
55*41dd9a6bSDavid Young  expiry event corresponds to
56*41dd9a6bSDavid Young* ``op`` - Will be set to ``RTE_EVENT_OP_NEW`` by the event timer adapter
57*41dd9a6bSDavid Young* ``event_type`` - Will be set to ``RTE_EVENT_TYPE_TIMER`` by the event timer
58*41dd9a6bSDavid Young  adapter
59*41dd9a6bSDavid Young
60*41dd9a6bSDavid YoungTimeout Ticks
61*41dd9a6bSDavid Young~~~~~~~~~~~~~
62*41dd9a6bSDavid Young
63*41dd9a6bSDavid YoungThe number of ticks from now in which the timer will expire. The ticks value
64*41dd9a6bSDavid Younghas a resolution (``timer_tick_ns``) that is specified in the event timer
65*41dd9a6bSDavid Youngadapter configuration.
66*41dd9a6bSDavid Young
67*41dd9a6bSDavid YoungState
68*41dd9a6bSDavid Young~~~~~
69*41dd9a6bSDavid Young
70*41dd9a6bSDavid YoungBefore arming an event timer, the application should initialize its state to
71*41dd9a6bSDavid YoungRTE_EVENT_TIMER_NOT_ARMED. The event timer's state will be updated when a
72*41dd9a6bSDavid Youngrequest to arm or cancel it takes effect.
73*41dd9a6bSDavid Young
74*41dd9a6bSDavid YoungIf the application wishes to rearm the timer after it has expired, it should
75*41dd9a6bSDavid Youngreset the state back to RTE_EVENT_TIMER_NOT_ARMED before doing so.
76*41dd9a6bSDavid Young
77*41dd9a6bSDavid YoungUser Metadata
78*41dd9a6bSDavid Young~~~~~~~~~~~~~
79*41dd9a6bSDavid Young
80*41dd9a6bSDavid YoungMemory to store user specific metadata.  The event timer adapter implementation
81*41dd9a6bSDavid Youngwill not modify this area.
82*41dd9a6bSDavid Young
83*41dd9a6bSDavid YoungAPI Overview
84*41dd9a6bSDavid Young------------
85*41dd9a6bSDavid Young
86*41dd9a6bSDavid YoungThis section will introduce the reader to the event timer adapter API, showing
87*41dd9a6bSDavid Younghow to create and configure an event timer adapter and use it to manage event
88*41dd9a6bSDavid Youngtimers.
89*41dd9a6bSDavid Young
90*41dd9a6bSDavid YoungFrom a high level, the setup steps are:
91*41dd9a6bSDavid Young
92*41dd9a6bSDavid Young* rte_event_timer_adapter_create()
93*41dd9a6bSDavid Young* rte_event_timer_adapter_start()
94*41dd9a6bSDavid Young
95*41dd9a6bSDavid YoungAnd to start and stop timers:
96*41dd9a6bSDavid Young
97*41dd9a6bSDavid Young* rte_event_timer_arm_burst()
98*41dd9a6bSDavid Young* rte_event_timer_cancel_burst()
99*41dd9a6bSDavid Young
100*41dd9a6bSDavid YoungCreate and Configure an Adapter Instance
101*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
102*41dd9a6bSDavid Young
103*41dd9a6bSDavid YoungTo create an event timer adapter instance, initialize an
104*41dd9a6bSDavid Young``rte_event_timer_adapter_conf`` struct with the desired values, and pass it
105*41dd9a6bSDavid Youngto ``rte_event_timer_adapter_create()``.
106*41dd9a6bSDavid Young
107*41dd9a6bSDavid Young.. code-block:: c
108*41dd9a6bSDavid Young
109*41dd9a6bSDavid Young	#define NSECPERSEC 1E9
110*41dd9a6bSDavid Young	const struct rte_event_timer_adapter_conf adapter_config = {
111*41dd9a6bSDavid Young                .event_dev_id = event_dev_id,
112*41dd9a6bSDavid Young                .timer_adapter_id = 0,
113*41dd9a6bSDavid Young		.socket_id = rte_socket_id(),
114*41dd9a6bSDavid Young                .clk_src = RTE_EVENT_TIMER_ADAPTER_CPU_CLK,
115*41dd9a6bSDavid Young                .timer_tick_ns = NSECPERSEC / 10,
116*41dd9a6bSDavid Young                .max_tmo_ns = 180 * NSECPERSEC,
117*41dd9a6bSDavid Young                .nb_timers = 40000,
118*41dd9a6bSDavid Young                .flags = 0,
119*41dd9a6bSDavid Young	};
120*41dd9a6bSDavid Young
121*41dd9a6bSDavid Young	struct rte_event_timer_adapter *adapter;
122*41dd9a6bSDavid Young	adapter = rte_event_timer_adapter_create(&adapter_config);
123*41dd9a6bSDavid Young
124*41dd9a6bSDavid Young	if (adapter == NULL) { ... };
125*41dd9a6bSDavid Young
126*41dd9a6bSDavid YoungBefore creating an instance of a timer adapter, the application should create
127*41dd9a6bSDavid Youngand configure an event device along with its event ports. Based on the event
128*41dd9a6bSDavid Youngdevice capability, it might require creating an additional event port to be
129*41dd9a6bSDavid Youngused by the timer adapter.  If required, the
130*41dd9a6bSDavid Young``rte_event_timer_adapter_create()`` function will use a default method to
131*41dd9a6bSDavid Youngconfigure an event port;  it will examine the current event device
132*41dd9a6bSDavid Youngconfiguration, determine the next available port identifier number, and create
133*41dd9a6bSDavid Younga new event port with a default port configuration.
134*41dd9a6bSDavid Young
135*41dd9a6bSDavid YoungIf the application desires to have finer control of event port allocation
136*41dd9a6bSDavid Youngand setup, it can use the ``rte_event_timer_adapter_create_ext()`` function.
137*41dd9a6bSDavid YoungThis function is passed a callback function that will be invoked if the
138*41dd9a6bSDavid Youngadapter needs to create an event port, giving the application the opportunity
139*41dd9a6bSDavid Youngto control how it is done.
140*41dd9a6bSDavid Young
141*41dd9a6bSDavid YoungEvent device configuration for service based adapter
142*41dd9a6bSDavid Young^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
143*41dd9a6bSDavid Young
144*41dd9a6bSDavid YoungWhen ``rte_event_timer_adapter_create()`` is used for creating
145*41dd9a6bSDavid Youngadapter instance, ``rte_event_dev_config::nb_event_ports`` is
146*41dd9a6bSDavid Youngautomatically incremented, and the event device is reconfigured
147*41dd9a6bSDavid Youngwith additional event port during service initialization.
148*41dd9a6bSDavid YoungThis event device reconfigure logic also increments the
149*41dd9a6bSDavid Young``rte_event_dev_config::nb_single_link_event_port_queues``
150*41dd9a6bSDavid Youngparameter if the adapter event port config is of type
151*41dd9a6bSDavid Young``RTE_EVENT_PORT_CFG_SINGLE_LINK``.
152*41dd9a6bSDavid Young
153*41dd9a6bSDavid YoungApplication no longer needs to account for the
154*41dd9a6bSDavid Young``rte_event_dev_config::nb_event_ports`` and
155*41dd9a6bSDavid Young``rte_event_dev_config::nb_single_link_event_port_queues``
156*41dd9a6bSDavid Youngparameters required for timer adapter in event device configuration,
157*41dd9a6bSDavid Youngwhen the adapter is created using the above-mentioned API.
158*41dd9a6bSDavid Young
159*41dd9a6bSDavid YoungAdapter modes
160*41dd9a6bSDavid Young^^^^^^^^^^^^^
161*41dd9a6bSDavid YoungAn event timer adapter can be configured in either periodic or non-periodic mode
162*41dd9a6bSDavid Youngto support timers of the respective type. A periodic timer expires at a fixed
163*41dd9a6bSDavid Youngtime interval repeatedly till it is cancelled. A non-periodic timer expires only
164*41dd9a6bSDavid Youngonce. The periodic capability flag, ``RTE_EVENT_TIMER_ADAPTER_CAP_PERIODIC``,
165*41dd9a6bSDavid Youngcan be set for implementations that support periodic mode if desired. To
166*41dd9a6bSDavid Youngconfigure an adapter in periodic mode, ``flags`` of
167*41dd9a6bSDavid Young``rte_event_timer_adapter_conf`` is set to include the periodic flag
168*41dd9a6bSDavid Young``RTE_EVENT_TIMER_ADAPTER_F_PERIODIC``. Maximum timeout (``max_tmo_ns``) does
169*41dd9a6bSDavid Youngnot apply to periodic mode.
170*41dd9a6bSDavid Young
171*41dd9a6bSDavid YoungRetrieve Event Timer Adapter Contextual Information
172*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
173*41dd9a6bSDavid YoungThe event timer adapter implementation may have constraints on tick resolution
174*41dd9a6bSDavid Youngor maximum timer expiry timeout based on the given event timer adapter or
175*41dd9a6bSDavid Youngsystem.  In this case, the implementation may adjust the tick resolution or
176*41dd9a6bSDavid Youngmaximum timeout to the best possible configuration.
177*41dd9a6bSDavid Young
178*41dd9a6bSDavid YoungUpon successful event timer adapter creation, the application can get the
179*41dd9a6bSDavid Youngconfigured resolution and max timeout with
180*41dd9a6bSDavid Young``rte_event_timer_adapter_get_info()``. This function will return an
181*41dd9a6bSDavid Young``rte_event_timer_adapter_info`` struct, which contains the following members:
182*41dd9a6bSDavid Young
183*41dd9a6bSDavid Young* ``min_resolution_ns`` - Minimum timer adapter tick resolution in ns.
184*41dd9a6bSDavid Young* ``max_tmo_ns`` - Maximum timer timeout(expiry) in ns.
185*41dd9a6bSDavid Young* ``adapter_conf`` - Configured event timer adapter attributes
186*41dd9a6bSDavid Young
187*41dd9a6bSDavid YoungConfiguring the Service Component
188*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
189*41dd9a6bSDavid Young
190*41dd9a6bSDavid YoungIf the adapter uses a service component, the application is required to map
191*41dd9a6bSDavid Youngthe service to a service core before starting the adapter:
192*41dd9a6bSDavid Young
193*41dd9a6bSDavid Young.. code-block:: c
194*41dd9a6bSDavid Young
195*41dd9a6bSDavid Young        uint32_t service_id;
196*41dd9a6bSDavid Young
197*41dd9a6bSDavid Young        if (rte_event_timer_adapter_service_id_get(adapter, &service_id) == 0)
198*41dd9a6bSDavid Young                rte_service_map_lcore_set(service_id, EVTIM_CORE_ID);
199*41dd9a6bSDavid Young
200*41dd9a6bSDavid YoungAn event timer adapter uses a service component if the event device PMD
201*41dd9a6bSDavid Youngindicates that the adapter should use a software implementation.
202*41dd9a6bSDavid Young
203*41dd9a6bSDavid YoungStarting the Adapter Instance
204*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
205*41dd9a6bSDavid Young
206*41dd9a6bSDavid YoungThe application should call ``rte_event_timer_adapter_start()`` to start
207*41dd9a6bSDavid Youngrunning the event timer adapter. This function calls the start entry points
208*41dd9a6bSDavid Youngdefined by eventdev PMDs for hardware implementations or puts a service
209*41dd9a6bSDavid Youngcomponent into the running state in the software implementation.
210*41dd9a6bSDavid Young
211*41dd9a6bSDavid Young.. Note::
212*41dd9a6bSDavid Young
213*41dd9a6bSDavid Young         The eventdev to which the event_timer_adapter is connected needs to
214*41dd9a6bSDavid Young         be started before calling rte_event_timer_adapter_start().
215*41dd9a6bSDavid Young
216*41dd9a6bSDavid YoungArming Event Timers
217*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~
218*41dd9a6bSDavid Young
219*41dd9a6bSDavid YoungOnce an event timer adapter has been started, an application can begin to
220*41dd9a6bSDavid Youngmanage event timers with it.
221*41dd9a6bSDavid Young
222*41dd9a6bSDavid YoungThe application should allocate ``struct rte_event_timer`` objects from a
223*41dd9a6bSDavid Youngmempool or huge-page backed application buffers of required size. Upon
224*41dd9a6bSDavid Youngsuccessful allocation, the application should initialize the event timer, and
225*41dd9a6bSDavid Youngthen set any of the necessary event attributes described in the
226*41dd9a6bSDavid Young`Timer Expiry Event`_ section. In the following example, assume ``conn``
227*41dd9a6bSDavid Youngrepresents a TCP connection and that ``event_timer_pool`` is a mempool that
228*41dd9a6bSDavid Youngwas created previously:
229*41dd9a6bSDavid Young
230*41dd9a6bSDavid Young.. code-block:: c
231*41dd9a6bSDavid Young
232*41dd9a6bSDavid Young	rte_mempool_get(event_timer_pool, (void **)&conn->evtim);
233*41dd9a6bSDavid Young	if (conn->evtim == NULL) { ... }
234*41dd9a6bSDavid Young
235*41dd9a6bSDavid Young	/* Set up the event timer. */
236*41dd9a6bSDavid Young	conn->evtim->ev.op = RTE_EVENT_OP_NEW;
237*41dd9a6bSDavid Young	conn->evtim->ev.queue_id = event_queue_id;
238*41dd9a6bSDavid Young        conn->evtim->ev.sched_type = RTE_SCHED_TYPE_ATOMIC;
239*41dd9a6bSDavid Young        conn->evtim->ev.priority = RTE_EVENT_DEV_PRIORITY_NORMAL;
240*41dd9a6bSDavid Young        conn->evtim->ev.event_type = RTE_EVENT_TYPE_TIMER;
241*41dd9a6bSDavid Young	conn->evtim->ev.event_ptr = conn;
242*41dd9a6bSDavid Young	conn->evtim->state = RTE_EVENT_TIMER_NOT_ARMED;
243*41dd9a6bSDavid Young	conn->evtim->timeout_ticks = 30; //3 sec Per RFC1122(TCP returns)
244*41dd9a6bSDavid Young
245*41dd9a6bSDavid YoungNote that it is necessary to initialize the event timer state to
246*41dd9a6bSDavid YoungRTE_EVENT_TIMER_NOT_ARMED.  Also note that we have saved a pointer to the
247*41dd9a6bSDavid Young``conn`` object in the timer's event payload. This will allow us to locate
248*41dd9a6bSDavid Youngthe connection object again once we dequeue the timer expiry event from the
249*41dd9a6bSDavid Youngevent device later.
250*41dd9a6bSDavid Young
251*41dd9a6bSDavid YoungNow we can arm the event timer with ``rte_event_timer_arm_burst()``:
252*41dd9a6bSDavid Young
253*41dd9a6bSDavid Young.. code-block:: c
254*41dd9a6bSDavid Young
255*41dd9a6bSDavid Young	ret = rte_event_timer_arm_burst(adapter, &conn->evtim, 1);
256*41dd9a6bSDavid Young	if (ret != 1) { ... }
257*41dd9a6bSDavid Young
258*41dd9a6bSDavid YoungOnce an event timer expires, the application may free it or rearm it as
259*41dd9a6bSDavid Youngnecessary.  If the application will rearm the timer, the state should be reset
260*41dd9a6bSDavid Youngto RTE_EVENT_TIMER_NOT_ARMED by the application before rearming it. Timer expiry
261*41dd9a6bSDavid Youngevents will be generated once or periodically until the timer is cancelled based
262*41dd9a6bSDavid Youngon adapter mode.
263*41dd9a6bSDavid Young
264*41dd9a6bSDavid YoungMultiple Event Timers with Same Expiry Value
265*41dd9a6bSDavid Young^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
266*41dd9a6bSDavid Young
267*41dd9a6bSDavid YoungIn the special case that there is a set of event timers that should all expire
268*41dd9a6bSDavid Youngat the same time, the application may call
269*41dd9a6bSDavid Young``rte_event_timer_arm_tmo_tick_burst()``, which allows the implementation to
270*41dd9a6bSDavid Youngoptimize the operation if possible.
271*41dd9a6bSDavid Young
272*41dd9a6bSDavid YoungCanceling Event Timers
273*41dd9a6bSDavid Young~~~~~~~~~~~~~~~~~~~~~~
274*41dd9a6bSDavid Young
275*41dd9a6bSDavid YoungAn event timer that has been armed as described in `Arming Event Timers`_ can
276*41dd9a6bSDavid Youngbe canceled by calling ``rte_event_timer_cancel_burst()``:
277*41dd9a6bSDavid Young
278*41dd9a6bSDavid Young.. code-block:: c
279*41dd9a6bSDavid Young
280*41dd9a6bSDavid Young	/* Ack for the previous tcp data packet has been received;
281*41dd9a6bSDavid Young	 * cancel the retransmission timer
282*41dd9a6bSDavid Young         */
283*41dd9a6bSDavid Young	rte_event_timer_cancel_burst(adapter, &conn->timer, 1);
284*41dd9a6bSDavid Young
285*41dd9a6bSDavid YoungProcessing Timer Expiry Events
286*41dd9a6bSDavid Young------------------------------
287*41dd9a6bSDavid Young
288*41dd9a6bSDavid YoungOnce an event timer has successfully enqueued a timer expiry event in the event
289*41dd9a6bSDavid Youngdevice, the application will subsequently dequeue it from the event device.
290*41dd9a6bSDavid YoungThe application can use the event payload to retrieve a pointer to the object
291*41dd9a6bSDavid Youngassociated with the event timer. It can then re-arm the event timer or free the
292*41dd9a6bSDavid Youngevent timer object as desired:
293*41dd9a6bSDavid Young
294*41dd9a6bSDavid Young.. code-block:: c
295*41dd9a6bSDavid Young
296*41dd9a6bSDavid Young	void
297*41dd9a6bSDavid Young	event_processing_loop(...)
298*41dd9a6bSDavid Young	{
299*41dd9a6bSDavid Young		while (...) {
300*41dd9a6bSDavid Young			/* Receive events from the configured event port. */
301*41dd9a6bSDavid Young			rte_event_dequeue_burst(event_dev_id, event_port, &ev, 1, 0);
302*41dd9a6bSDavid Young			...
303*41dd9a6bSDavid Young			switch(ev.event_type) {
304*41dd9a6bSDavid Young				...
305*41dd9a6bSDavid Young				case RTE_EVENT_TYPE_TIMER:
306*41dd9a6bSDavid Young					process_timer_event(ev);
307*41dd9a6bSDavid Young					...
308*41dd9a6bSDavid Young					break;
309*41dd9a6bSDavid Young			}
310*41dd9a6bSDavid Young		}
311*41dd9a6bSDavid Young	}
312*41dd9a6bSDavid Young
313*41dd9a6bSDavid Young	uint8_t
314*41dd9a6bSDavid Young	process_timer_event(...)
315*41dd9a6bSDavid Young	{
316*41dd9a6bSDavid Young		/* A retransmission timeout for the connection has been received. */
317*41dd9a6bSDavid Young		conn = ev.event_ptr;
318*41dd9a6bSDavid Young		/* Retransmit last packet (e.g. TCP segment). */
319*41dd9a6bSDavid Young		...
320*41dd9a6bSDavid Young		/* Re-arm timer using original values. */
321*41dd9a6bSDavid Young		rte_event_timer_arm_burst(adapter_id, &conn->timer, 1);
322*41dd9a6bSDavid Young	}
323*41dd9a6bSDavid Young
324*41dd9a6bSDavid YoungSummary
325*41dd9a6bSDavid Young-------
326*41dd9a6bSDavid Young
327*41dd9a6bSDavid YoungThe Event Timer Adapter library extends the DPDK event-based programming model
328*41dd9a6bSDavid Youngby representing timer expirations as events in the system and allowing
329*41dd9a6bSDavid Youngapplications to use existing event processing loops to arm and cancel event
330*41dd9a6bSDavid Youngtimers or handle timer expiry events.
331