I saw the add_timer function today. The comment says this is a problem. I took a closer look and found it a problem.
I fixed it myself. Please take a look. I changed the red part. However, it seems that free_timer is still a problem.
The source code is as follows:
/*
* Linux/kernel/sched. c
*
* This piece of code is copied from Linux Kernel 0.12.
* Since the timer for kernel has a minor bug, I want to fix it.
* (C) 1991 Linus Torvalds
*/
# Include <stdio. h>
# Define TIME_REQUESTS 64
Static struct timer_list {
Long jiffies;
Void (* fn )();
Struct timer_list * next;
} Timer_list [TIME_REQUESTS], * next_timer = NULL;
Static struct timer_list timer_list_test [TIME_REQUESTS], * next_timer_test = NULL;
/* Kernel function with out change */
Void add_timer (long jiffies, void (* fn) (void ))
{
Struct timer_list * p;
If (! Fn)
Return;
// Cli ();
If (jiffies <= 0)
(Fn )();
Else {
For (p = timer_list; p <timer_list + TIME_REQUESTS; p ++)
If (! P-> fn)
Break;
If (p> = timer_list + TIME_REQUESTS)
Return;
// Panic ("No more time requests free ");
P-> fn = fn;
P-> jiffies = jiffies;
P-> next = next_timer;
Next_timer = p;
While (p-> next & p-> next-> jiffies <p-> jiffies ){
P-> jiffies-= p-> next-> jiffies;
Fn = p-> fn;
P-> fn = p-> next-> fn;
P-> next-> fn = fn;
Jiffies = p-> jiffies;
P-> jiffies = p-> next-> jiffies;
P-> next-> jiffies = jiffies;
P = p-> next;
}
}
// Sti ();
}
/* My version */
Void add_timer_test (long jiffies, void (* fn) (void ))
{
Struct timer_list * p;
If (! Fn)
Return;
// Cli ();
If (jiffies <= 0)
(Fn )();
Else {
For (p = timer_list_test; p <timer_list_test + TIME_REQUESTS; p ++)
If (! P-> fn)
Break;
If (p> = timer_list_test + TIME_REQUESTS)
Return;
// Panic ("No more time requests free ");
P-> fn = fn;
P-> jiffies = jiffies;
P-> next = next_timer_test;
Next_timer_test = p;
While (p-> next ){
If (p-> jiffies <= p-> next-> jiffies)
{
P-> next-> jiffies-= p-> jiffies;
Break;
}
P-> jiffies-= p-> next-> jiffies;
Fn = p-> fn;
P-> fn = p-> next-> fn;
P-> next-> fn = fn;
Jiffies = p-> jiffies;
P-> jiffies = p-> next-> jiffies;
P-> next-> jiffies = jiffies;
P = p-> next;
}
}
// Sti ();
}
Void dump_timer (struct timer_list * p)
{
Int sum = 0, I = 1;
Printf ("/tTimer node/trelative time/tabsolute time/n ");
While (p)
{
Sum + = p-> jiffies;
Printf ("/t % 6d/t % 8d/t % 8d/n", I, p-> jiffies, sum );
P = p-> next;
I ++;
}
Return;
}
Void free_timer (struct timer_list ** p)
{
Struct timer_list ** start = p;
Struct timer_list * liter = * p, * m;
For (m; m <liter + TIME_REQUESTS; m ++)
{
M-> fn = NULL;
M-> jiffies = 0;
M-> next = NULL;
}
* Start = NULL;
Return;
}
Void handler ()
{
Printf ("handler here/n ");
Return;
}
Void main ()
{
Printf ("This is a bug fixing for linux kernel./n ");
/* Linux kernel test */
Add_timer (5, handler );
Add_timer (10, handler );
Add_timer (20, handler );
Dump_timer (next_timer );
Free_timer (& next_timer );
Dump_timer (next_timer );
Printf ("-----------------------------/n ");
Add_timer (20, handler );
Add_timer (10, handler );
Add_timer (30, handler );
Dump_timer (next_timer );
Free_timer (& next_timer );
Dump_timer (next_timer );
Printf ("-----------------------------/n ");
/* My function test */
Add_timer_test (5, handler );
Add_timer_test (10, handler );
Add_timer_test (20, handler );
Dump_timer (next_timer_test );
Free_timer (& next_timer_test );
Dump_timer (next_timer_test );
Printf ("-----------------------------/n ");
Add_timer_test (20, handler );
Add_timer_test (10, handler );
Add_timer_test (30, handler );
Dump_timer (next_timer_test );
Free_timer (& next_timer_test );
Dump_timer (next_timer_test );
Printf ("-----------------------------/n ");
Return;
}
The following is the running result.
This is a bug fixing for linux kernel.
Timer node relative time absolute time
1 5 5
2 5 10
3 10 20
Timer node relative time absolute time
-----------------------------
Timer node relative time absolute time
1 10 10
2 20 30
3 20 50
Timer node relative time absolute time
-----------------------------
Timer node relative time absolute time
1 5 5
2 5 10
3 10 20
Timer node relative time absolute time
-----------------------------
Timer node relative time absolute time
1 10 10
2 10 20
3 10 30
Timer node relative time absolute time
-----------------------------
Press any key to continue