Some information about timer!!!

本文介绍Linux内核中定时器的创建、初始化、激活、修改及删除等操作流程,并强调了同步删除定时器的重要性以及如何避免竞态条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Using Timers
Timers are represented by struct timer_list, which is defined in <linux/timer.h>:

struct timer_list {
        struct list_head entry;           /* entry in linked list of timers */
        unsigned long expires;            /* expiration value, in jiffies */
        spinlock_t lock;                  /* lock protecting this timer */
        void (*function)(unsigned long);  /* the timer handler function */
        unsigned long data;               /* lone argument to the handler */
        struct tvec_t_base_s *base;       /* internal timer field, do not touch */
};

 

 The kernel provides a family of timer-related interfaces to make timer management easy.

Everything is declared in <linux/timer.h>. Most of the actual implementation is in

kernel/timer.c.

The first step in creating a timer is defining it:

struct timer_list my_timer;

 

Next, the timer's internal values must be initialized. This is done via a helper function

and must be done prior to calling any timer management functions on the timer:

init_timer(&my_timer);

 

Now you fill out the remaining values as required:

my_timer.expires = jiffies + delay;    /* timer expires in delay ticks */
my_timer.data = 0;                     /* zero is passed to the timer handler */
my_timer.function = my_function;       /* function to run when timer expires */

 

The my_timer.expires value specifies the timeout value in absolute ticks. When the current

jiffies count is equal to or greater than my_timer.expires, the handler function

my_timer.function is run with the lone argument of my_timer.data. As you can see from the

timer_list definition, the function must match this prototype:

void my_timer_function(unsigned long data);

 

The data parameter enables you to register multiple timers with the same handler, and

differentiate between them via the argument. If you do not need the argument, you can

simply pass zero (or any other value).

Finally, you activate the timer:

add_timer(&my_timer);


Sometimes you might need to modify the expiration of an already active timer. The kernel

implements a function, mod_timer(), which changes the expiration of a given timer:

mod_timer(&my_timer, jiffies + new_delay);  /* new expiration */

 

The mod_timer() function can operate on timers that are initialized but not active, too. If

the timer is inactive, mod_timer() activates it. The function returns zero if the timer was

inactive and one if the timer was active. In either case, upon return from mod_timer(), the

timer is activated and set to the new expiration.(这段话关键啊!!!!)

If you need to deactivate a timer prior to its expiration, use the del_timer() function:

del_timer(&my_timer);

 

The function works on both active and inactive timers. If the timer is already inactive,

the function returns zero; otherwise, the function returns one. Note that you do not need

to call this for timers that have expired because they are automatically deactivated.

A potential race condition that must be guarded against exists when deleting timers. When

del_timer() returns, it guarantees only that the timer is no longer active (that is, that

it will not be executed in the future). On a multiprocessing machine, however, the timer

handler might already be executing on another processor. To deactivate the timer and wait

until a potentially executing handler for the timer exits, use del_timer_sync():

del_timer_sync(&my_timer);

 

Unlike del_timer(), del_timer_sync() cannot be used from interrupt context(关键!注意).

Timer Race Conditions
Because timers run asynchronously with respect to the currently executing code, several

potential race conditions exist. First, never do the following as a substitute for a mere

mod_timer(), because this is unsafe on multiprocessing machines:

del_timer(my_timer)
my_timer->expires = jiffies + new_delay;
add_timer(my_timer);
//不要用上面的方法来代替(在调用mod_timer之前,需要调用del_timer,使timer是inactive吗?)

mod_timer();

 

Second, in almost all cases, you should use del_timer_sync() over del_timer(). (但它不能用

子中断上下文)Otherwise, you cannot assume the timer is not currently running, and that is

why you made the call in the first place! Imagine if, after deleting the timer, the code

went on to free or otherwise manipulate resources used by the timer handler. Therefore, the

synchronous version is preferred.

Finally, you must make sure to protect any shared data used in the timer handler function.

The kernel runs the function asynchronously with respect to other code. Data with a timer

should be protected 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值