Precision timer in Linux

Source: Internet
Author: User

From: http://blog.163.com/hong_nt/blog/static/10468917120081130103632925/


The main function of the software timer is to implement the timeout mechanism of the state machine and implement the timeout-based counting function.
Because the Protocol state machine runs on the Linux kernel, that is, it runs on the user State. In
In Linux, user-Mode Applications can only call three Timers: itimer_real, itimer_virtual, and itimer_prof. In the Protocol state machine
32 timers are required, so a new mechanism is required to complete the timer function.
Software timers are mainly used to solve the physical limitations of hardware timers and provide more flexible timer programming interfaces for applications.
Port. The most basic function of a timer is to allow a task to run at a specific time point in the future. The timer times out and the registered task starts to run. In our system, tasks related to the timer are to generate
Timer timeout event. We define the most basic timer structure timer as our software timer object:
# Define max_timers N // n number of timers you need
Struct timer {
Long timeout; // timer timeout time, in milliseconds
Long expire; // The remaining timeout time of the timer during the next interruption, in milliseconds
Int inuse; // whether the timer is used
Int set; // whether the timer times out
Int signal; // The type of event sent when the timer times out.
Int Param; // the parameter of the event type sent when the timer times out.
} T [max_timers]; // timer set
The software timer provides four interfaces for the application:
Int init_timers (); // initializes the timer set.
Int start_timer (struct timer * t); // start the timer t
Int stop_timer (struct timer * t); // stop the timer t
Int get_event (); // query timeout timer events
When the program initializes, it calls init_timers () to initialize the timer set. After initialization, it can call start_timer () and stop_timer () in the system to use the timer function. The Protocol state machine calls get_event () cyclically to query timeout timer events and input them to the Protocol state machine.
Soft
The timer is based on an internal itimer_real timer provided by the Linux operating system. The timer is used to complete the actual timer work. Timer itimer_real
From time to time, call update_timers () to update the timer set, set the set position of the timer that times out, query all the started timers in the timer set, and select the expire value
The smallest timer, which uses the expire value to reset the timer itimer_real, and updates the expire values of all started timers in the timer set. In other words
After expire milliseconds, the timer itimer_real will re-initiate the timeout interruption and repeat the above process. If no software timer is started, the timer itimer_real will be cleared.
Zero until the next call to start_timer ().
If start_timer (struct timer) is called between two interruptions
* T), the value of T-> expire will be compared with the time interval time_remain from the next clock interruption. If T-> expire is smaller
Time_remain, t will be used as the minimum timer, use t-> expire to reset the Internal timer itimer_real, and update all started Timer In the timer set
If T-> expire is not smaller than time_remain, you only need to update the expire value of T.
Stop_timer (struct timer * t) is automatically ignored when the timer set is updated by setting the insue value of T.

Some code is as follows:
Program soft_timer.c:

# Include "soft_timer.h"
Int Delta = 10;
Long start = 0;
Struct itimerval phy_timer;
Struct itimerval old_timer;
Struct timer * cur_timer;

Void update_timers (INT sig)
{
Int I = 0;
Int min_timer =-1;
Long min _expire = 1000000000;

If (cur_timer-> inuse) cur_timer-> set = 1;

For (I = 0; I <max_timers; I ++ ){
If (T. inuse &&! T. Set ){
If (T. expire <delta ){
T. Set = 1;
} Else if (T. expire> 0 & min_expire> T. expire ){
Min_expire = T. expire;
Min_timer = I;
}
}
}

If (min_timer <0 ){
Timerclear (& (phy_timer.it_value ));
Timerclear (& (phy_timer.it_interval ));
} Else {
Phy_timer.it_value. TV _sec = min_expire/1000;
Phy_timer.it_value. TV _usec = (min_expire % 1000) * 1000;
Timerclear (& (phy_timer.it_interval ));
Cur_timer = & T [min_timer];
For (I = 0; I <max_timers; I ++ ){
If (T. inuse &&! T. Set ){
T. expire-= min_expire;
}
}
}

Setitimer (itimer_real, & phy_timer, null );
}

Int create_phy_timer (struct itimerval * timer, void (* Handler) (INT ))
{
Int rc = 0;
Struct sigaction SA;
Memset (& SA, 0, sizeof (SA ));
SA. sa_handler = handler;
Sigaction (sigalrm, & SA, null );

Timerclear (& (timer-> it_value ));
Timerclear (& (timer-> it_interval ));

Setitimer (itimer_real, timer, null );

Return RC;

}

Int init_timers ()
{
Int ret = 0;
Int I = 0;
For (I = 0; I <max_timers; I ++ ){
T. inuse = 0;
T. Param = 0;
T. Set = 0;
T. Timeout = 0;
T. expire = 0;
}
Cur_timer = & T [0];
Create_phy_timer (& phy_timer, update_timers );
}

Int start_timer (struct timer * t)
{
Int ret = 0;
Int I = 0;
Long diff = 0;
Long time_remain;

T-> expire = T-> timeout;
T-> inuse = 1;
T-> set = 0;
Getitimer (itimer_real, & old_timer );

Time_remain = old_timer.it_value. TV _sec * 1000 + old_timer.it_value. TV _usec/1000;
// Printf ("time_remain = % LD/N", time_remain );
If (time_remain = 0 ){

Phy_timer.it_value. TV _sec = T-> time out/1000;
Phy_timer.it_value. TV _usec = (t-> timeout % 1000) * 1000;
Timerclear (& (phy_timer.it_interval ));
Setitimer (itimer_real, & phy_timer, null );
Cur_timer = T;
Return ret;
}

If (t-> timeout + Delta <= time_remain ){
Diff = time_remain-T-> timeout;

For (I = 0; I <max_timers; I ++ ){

If (cur_timer ==& t ){
Cur_timer-> expire = diff;
} Else if (t = & T ){
} Else if (T. inuse &&! T. Set ){
T. expire + = diff;
}
}

Phy_timer.it_value. TV _sec = T-> time out/1000;
Phy_timer.it_value. TV _usec = (t-> timeout % 1000) * 1000;
Timerclear (& (phy_timer.it_interval ));
Setitimer (itimer_real, & phy_timer, null );
Cur_timer = T;

} Else {
T-> expire = T-> timeout-time_remain;
// Printf ("T-> expire = % LD/N", T-> expire );
}
Return ret;

}
Int stop_timer (struct timer * t)
{
Int ret = 0;
T-> inuse = 0;
T-> expire = T-> timeout;
T-> set = 0;
Return ret;

}
Long current_millis ()
{
Struct timeval TV;
Long now;
Gettimeofday (& TV, null );
Now = (TV. TV _sec % 100000) * 1000 + TV. TV _usec/1000;
Return now;
}

Void sleep_millis (long MS)
{
Struct timespec TV;
TV. TV _sec = MS/1000;
TV. TV _nsec = (long) (MS % 1000) * 1000000;

Nanosleep (& TV, null );
}

The soft_timer.h header file is as follows:

# Define max_timers n

Struct timer {
Long timeout;
Long expire;
Int inuse;
Int set;
Int signal;
Int Param;
} T [max_timers];

Extern int init_timers ();
Extern int start_timer (struct timer * t );
Extern int stop_timer (struct timer * t );
Extern int start_phy_timer (struct timer * t, void (* Handler) (INT ));
Extern int stop_phy_timer (struct timer * t );

Extern long current_millis ();
Extern void sleep_millis (long MS );

# Ifdef _ cplusplus
}
# Endif

# Endif/* _ soft_timer_h */

You can initialize it before calling it.
Init_timers ();
For (I = 1; I <max_timers; I ++ ){
If (I <n_timers ){
T. Timeout = timeouts;
T. Signal = time_events;
} Else {
T. Timeout = T [13]. Timeout;
T. Signal = T [13]. signal;
}
}

Start_timer (& T [N]); or stop_timer (& T [N ]);

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.