We are also able to change the expires value of a timer when it has been inserted into the list of dynamic timers in the kernel. function Mod_timer () to achieve this
Change the start time of the handler of the register into the timer list
int Mod_timer (struct timer_list *timer, unsigned long expires)
{
int ret;
unsigned long flags;
Spin_lock_irqsave (&timerlist_lock, flags);
Timer->expires = expires;
ret = Detach_timer (timer);
Internal_add_timer (timer);
Spin_unlock_irqrestore (&timerlist_lock, flags);
return ret;
}
The kernel uses the function Mod_timer to implement the timer timeout time that has been activated:
Mod_timer (&my_timer, Jiffies+new_delay);
The Mod_timer function can also operate a timer that has been initialized but has not yet been activated, assuming that the timer is not activated and Mod_timer activates it. Assuming that the timer is not activated at the time of invocation, the function returns 0, otherwise 1 is returned. Once returned from the Mod_timer function, the timer is activated and a new timing value is set.
Suppose you need to stop the timer before the timer times out, you can use the Del_timer function:
Del_timer (&my_timer);
The function can be used by a timer that is activated or not activated, assuming that the timer has not been activated, and that the function returns 0; otherwise 1 is returned. When removing timers, one must be careful of a potential competitive condition . When Del_timer returns, the only guarantee is that the timer will not be reactivated, but the timer interrupt on the multiprocessor may have been executed on the other processing, so it is necessary to wait for the timer handlers that may be executing on the other processors to exit, which requires the use of Del_timer_ The sync function performs the removal work:
Del_timer_sync (&my_timer);
Unlike the Del_timer function, the Del_timer_sync number cannot be used in the context of an interrupt.
The timer API contains a few other features than those described above. The following collection is a complete list of the kernel-provided functions:
-
-
int Mod_timer (struct timer_list *timer, unsigned long expires);
-
-
To update a timer's timeout, use a time-out timer for a common task (again, the off-motor floppy timer is a typical example). Mod_timer can also be used for inactive timers where you normally use Add_timer.
-
-
int Del_timer_sync (struct timer_list *timer);
-
-
Works like Del_timer, but also guarantees that when it returns, the timer function is not executed on any CPU. Del_timer_sync is used to avoid competitive situations on SMP systems, and in the up kernel and del_timer the same. This function should be used more first than del_timer in most cases. This function may sleep assuming it is called from a non-atomic context, but in other cases it will be busy waiting. Be very careful to call Del_timer_sync when holding a lock; Assuming this timer function attempts to obtain the same lock, the system will deadlock. Assuming that the timer function has been registered again, the caller must first ensure that this another registration will not occur; This is often implemented with a "close" flag, which is checked by the timer function.
-
-
int timer_pending (const struct timer_list * timer);
-
Returns TRUE or false to indicate whether the timer is currently scheduled to execute by calling an opaque member of the structure.
Here are the API functions for the timer:
Adding timers
void Add_timer (struct timer_list * timer); |
Remove Timer
int Del_timer (struct timer_list * timer); |
Changing the expire of the timer
int Mod_timer (struct timer_list *timer, unsigned long expires); |
The general process for using timers is:
(1) Timer, write function;
(2) for the timer expires, data, function assignment value;
(3) Call Add_timer to add a timer to the list;
(4) When the timer expires, function is run;
(5) in the program involved in the timer control where appropriate to call Del_timer, Mod_timer Delete timer or change timer expires.
We are able to take part in the driver of the DRIVERS\CHAR\KEYBOARD.C keyboard about the timer:
... #include <linux/timer.h> ... static struct Timer_list Key_autorepeat_timer = { Function:key_callback };
static void
Kbd_processkeycode (unsigned char keycode, char up_flag, int autorepeat) { Char Raw_mode = (Kbd->kbdmode = = Vc_raw); if (Up_flag) { Rep = 0; if (!test_and_clear_bit (KeyCode, Key_down)) Up_flag = Kbd_unexpected_up (keycode); } else { Rep = Test_and_set_bit (KeyCode, Key_down); /* If the keyboard autorepeated for us, ignore it. * We do our own autorepeat processing. */ If (Rep &&!autorepeat) Return } if (Kbd_repeatkeycode = = KeyCode | |!up_flag | | raw_mode) { Kbd_repeatkeycode =-1; Del_timer (&key_autorepeat_timer); } ... /* * Calculate The next time we have to do some autorepeat * Processing. Note that we don't do autorepeat processing * While in raw mode autorepeat processing in * Medium Raw mode. */ if (!up_flag &&!raw_mode) { Kbd_repeatkeycode = KeyCode; if (Vc_kbd_mode (KBD, vc_repeat)) { if (rep) Key_autorepeat_timer.expires = jiffies + kbd_repeatinterval; Else Key_autorepeat_timer.expires = jiffies + kbd_repeattimeout; Add_timer (&key_autorepeat_timer); } } ... } |
Mod_timer functions and other timer functions