Kernel timing mechanism Application

Source: Internet
Author: User
Tags sigint signal

Kernel timing mechanism Application

Exercise how to compile the time measurement function that calls the kernel for application measurement and precise timing. Through this exercise, we can further understand the timing mechanism of the Linux kernel and its data structure and how to access the time data of the kernel space from the user space.

The following code is required to obtain system time data from a user space:

# Include
  
   
Struct timeval {long TV _sec; // the number of seconds that have elapsed since: long TV _usec; // The number of microseconds that have elapsed since the last one} theTime; gettimeofday (& theTime, NULL); // obtain the system call time of the system.
  

Various timers used by each process require Linux internal timers. The Internal timer can be used to track and record three different types of timing mechanisms, which reflect the division of time. These timing mechanisms have different functions and applications.

They are:
? ITIMER_REAL: indicates the actual time when the process passes through. When such a timer arrives, the SIGALRM signal is sent. It is related to the it_real_value and it_real_incr fields in the struct task_struct structure.

? ITIMER_VIRTUAL: indicates the virtual time of a process. This time increases only when the process is being executed. The SIGVTALRM signal is sent after the timer. It is related to the it_1__value and it_1__incr fields in the struct task_struct structure.

? ITIMER_PROF: indicates the sum of the virtual time taken by the process and the time when the kernel is used to execute the relevant process. When the timer arrives, a sigprof letter is sent. It is related to the it_prof_value and it_prof_incr fields in the struct task_struct structure.

Each timer needs to set an initial time value cyclically, and then the scheduled interruption is triggered after the count is reduced to 0. A timeout signal is generated to notify the corresponding process of the timer time, the timer then resends the count from the initial value.

All three timers use setitimer () system call for initialization:

# Include  ? Setitimer (int timerType, // timer type const struct itimerval * value, // The initial and current number of seconds and milliseconds of the timer struct itimerval * oldValue) struct itimerval {struct timeval it_it_interval; // initial values of the next scheduled time. If it is 0, the timer stops struct timeval it_value // the current value of the timer }; 

All three timers use the getitimer () System Call to obtain the current value of the Timer:

# Include  Setitimer (int timerType, // timer type const struct itimerval * value, // The initial and current number of seconds and milliseconds of the timer struct itimerval * oldValue) struct itimerval {struct timeval it_it_interval; // initial values of the next scheduled time. If it is 0, the timer stops struct timeval it_value // the current value of the timer }; 

First, we will first implement an example of testing program running time based on the kernel's timing mechanism:
The program listens to the user's ctrl + c button. After the press, it prints the time it takes for the program to run from the beginning. below is the implementation of my code:

/*** Function: the time when the program starts to run * each time the user presses the ctrl + c key, the program outputs the * running time */# include  # Include  # Include  # Include  # Include  // The original function static void sigreal (void) for timer interrupt processing; // listens to the SIGINT signal processing function static void sigctrl (void ); // record the value of running seconds static long run_sec = 0; // record the structure variable static struct itimerval realt; int main () {signal (SIGINT, sigctrl ); signal (SIGALRM, sigreal); realt. it_interval. TV _sec = 0; realt. it_interval. TV _usec = 999999; realt. it_value. TV _sec = 0; realt. it_value. TV _usec = 999999; setitimer (ITIMER_REAL, & realt, NULL); // test data int temp = 0; while (1) {temp ++;} return 0 ;} static void sigreal (void) {run_sec ++;} // The SIGINT signal processing function static void sigctrl (void) {// the calculation process is not very clear about getitimer (ITIMER_REAL, & realt); printf ("The run time is: % ld s % ld ms \ n", run_sec, (99999999-realt.it_value. TV _usec)/1000 );}     

Below is the running of my program:

Next, let's implement the alarm function. One feature of this alarm is that it can be accurate to microseconds, that is, our timing mechanism. the user is reminded of the number of hours, minutes, seconds, and milliseconds that the user has entered. the following is the implementation of my program:

/*** Function: Implement an alarm in microseconds * use the system timer Function to make the alarm accurate to microseconds **/# include  # Include  # Include  # Include  # Include  // Signal SIGALRM processing function prototype static void sigreal (void); // timer struct itimerval realt; // sets whether the program continues to run static int is_run = 1; int main () {int h, m, s, ms, us; printf ("Please enter the hours: minutes: seconds: ms: us after! \ N "); scanf (" % d: % d ", & h, & m, & s, & ms, & us ); int seconds = h * 3600 + m * 60 + s; int uSeconds = MS * 1000 + us; // timer setting realt. it_interval. TV _sec = seconds; realt. it_interval. TV _usec = uSeconds; realt. it_value. TV _sec = seconds; realt. it_value. TV _usec = uSeconds; signal (SIGALRM, sigreal); setitimer (ITIMER_REAL, & realt, NULL); while (is_run) {} printf ("Time over !! \ N "); return 0 ;}// after receiving the signal, the program stops running static void sigreal (void) {is_run = 0 ;}     

Below is the program running:

<喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4NCjxwPjxjb2RlIGNsYXNzPQ = "hljs vala"> In the last example, we created two sub-processes using the parent process. These three processes calculate the non-wavelet and series of different levels respectively, and finally print the time used by each process.

The following is code implementation:

/*** Function: test various time periods in the execution of concurrent processes * 3 Non-wavelet and number of serial numbers are specified, which can be between 36 and 45 * Author: Chen Hongbo */# include  # Include  # Include  # Include  # Include  // The Three timers of the parent process interrupt processing function prototype static void psig_real (void); static void psig_virtual (void); static void psig_prof (void ); // three scheduled interrupt processing function prototypes of sub-process 1: static void c1sig_real (void); static void c1sig_virtual (void); static void c1sig_prof (void ); // three timer interrupt processing function prototype of sub-process 2 static void c2sig_real (void); static void c2sig_virtual (void); static void c2sig_prof (void ); // long unsigned int fibonnacci (unsigned int n), a non-wavelet and Series function prototype; // record the Stas variable of three scheduled seconds Tic long p_real_secs = 0, c1_real_secs = 0, bytes = 0; static long p_virtual_secs = 0, c1_virtual_secs = 0, c2_virtual_secs = 0; static long p_prof_secs = 0, c1_prof_secs = 0, cost = 0; // record the Structure Variables static struct itimerval p_realt, c1_realt, c2_realt; static struct itimerval p_0000t, c1_0000t, c2_0000t; static struct itimerval p_proft, c1_proft, c2_proft; int main (int argc, char ** argv) {long uns Igned fib = 0; pid_t pid1, pid2; unsigned int fibarg; int status; int I; if (argc <3) {printf ("Usage: testing arg1 arg2 and arg3! \ N "); return 1 ;}// entry to the timing processing function in parent process settings 3: SIGALRM (SIGALRM, psig_real); signal (SIGVTALRM, psig_virtual); signal (SIGPROF, psig_prof); // initialize the three time timers of the parent process // the actual time when the process passes p_realt.it_interval. TV _sec = 9; timeout = 999999; p_realt.it_value. TV _sec = 9; timeout = 999999; setitimer (ITIMER_REAL, & p_realt, NULL); // The virtual time when a process passes through. Only the time when the relevant process is being executed is required. (unsigned int n); p_{t.it_interval. TV _sec = 9; p_{t.it_interval. TV _usec = 999999; p_0000t.it_value. TV _sec = 9; p_0000t.it_value. TV _usec = 999999; setitimer (ITIMER_VIRTUAL, & p_0000t, NULL); // reflect the sum of the virtual time of the process and the time when the kernel is used to execute the related process; latency = 999999; p_proft.it_value. TV _sec = 9; p_proft.it_value. TV _usec = 999999; setimer (ITIMER_PROF, & p_proft, NULL); pid1 = fork (); if) {// entry for timing processing in sub-process 1 3 (SIGALRM, c1sig_real); signal (SIGVTALRM, c1sig_virtual); signal (SIGPROF, c1sig_prof ); // three time timers of sub-processes: c1_realt.it_interval. TV _sec = 9; latency = 999999; c1_realt.it_value. TV _sec = 9; latency = 999999; setitimer (ITIMER_REAL, & c1_realt, NULL); Cost = 9; cost = 999999; c1_0000t.it_value. TV _sec = 9; c1_0000t.it_value. TV _usec = 999999; setitimer (ITIMER_VIRTUAL, & c1_0000t, NULL); Cost = 9; cost = 999999; cost = 9; cost = 999999; setitimer (ITIMER_PROF, & c1_proft, NULL); // The child process 1 starts to calculate fib = maid (atoi (argv [1]); // print the three time values getitimer (ITIMER_REAL, & c1_realt) of sub-process 1 ); printf ("Child1 fib = % ld \ n Child1 Real Time = % ld Sec % ld Msec \ n", fib, c1_real_secs + 9-c1_realt.it_value. TV _sec, (latency)/1000 ); getitimer (ITIMER_VIRTUAL, & c1_0000t); printf ("Child1 Virtual Time = % ld sec % ld Msec \ n", c1_virtual_secs + hour, (hour)/1000); getimer (ITIMER_PROF, & c1_proft); printf ("Child1 Prof Time = % ld sec % ld Msec \ n", c1_prof_secs + 9-c1_proft.it_value. TV _sec, (cost)/1000 );} else if (pid2 = fork () = 0) {// subprocess 2 setting 3 the timing processing entry signal (SIGALRM, c2sig_real); signal (SIGVTALRM, c2sig_virtual ); signal (SIGPROF, c2sig_prof); // three timer types of sub-process 2: timer = 9; timer = 999999; c2_realt.it_value. TV _sec = 9; timer = 999999; setitimer (ITIMER_REAL, & c2_realt, NULL); c2_0000t.it_interval. TV _sec = 9; Percentage = 999999; c2_0000t.it_value. TV _sec = 9; Percentage = 999999; setimer (ITIMER_VIRTUAL, & c2_0000t, NULL); Percentage = 9; Percentage = 999999; c2_proft.it_value. TV _sec = 9; Percentage = 999999; setitimer (ITIMER_PROF, & c2_proft, NULL); // child process 2 starts to calculate fib = maid (atoi (argv [2]); // print the three time values getitimer (ITIMER_REAL, & c2_realt) of sub-process 2 ); printf ("Child2 fib = % ld \ n Child2 Real Time = % ld Sec % ld Msec \ n", fib, c2_real_secs + 9-c2_realt.it_value. TV _sec, (bytes)/1000 ); getitimer (ITIMER_VIRTUAL, & c2_0000t); printf ("Child2 Virtual Time = % ld sec % ld Msec \ n", c2_virtual_secs + hour, (hour)/1000); getimer (ITIMER_PROF, & c2_proft); printf ("Child2 Prof Time = % ld sec % ld Msec \ n", c2_prof_secs + 9-c2_proft.it_value. TV _sec, (bytes)/1000 );} else {// The parent process starts to calculate fib = maid (atoi (argv [3]); // print the three time values of the parent process getitimer (ITIMER_REAL, & p_realt); printf ("Parent fib = % ld \ n Parent Real Time = % ld Sec % ld Msec \ n", fib, p_real_secs + 9-p_realt.it_value. TV _sec, (bytes) /1000); getimer (ITIMER_VIRTUAL, & p_0000t); printf ("Parent Virtual Time = % ld sec % ld Msec \ n", p_virtual_secs + 9-p_0000t.it_value. TV _sec, (Limit)/1000 ); getimer (ITIMER_PROF, & p_proft); printf ("Parent Prof Time = % ld sec % ld Msec \ n", p_prof_secs + 9-p_proft.it_value. TV _sec, (Limit)/1000 ); // wait until the child process ends waitpid (pid1, & status, 0); waitpid (pid2, & status, 0 );}} // three scheduled interrupt processing functions of the parent process: static void psig_real (void) {p_real_secs + = 10;} static void psig_virtual (void) {p_virtual_secs + = 10 ;} static void psig_prof (void) {p_prof_secs + = 10;} // three interrupt processing functions of sub-process 1 static void c1sig_real (void) {c1_real_secs + = 10 ;} static void c1sig_virtual (void) {c1_virtual_secs + = 10;} static void c1sig_prof (void) {c1_prof_secs + = 10 ;} // three interrupt handler functions of sub-process 2: static void c2sig_real (void) {c2_real_secs + = 10;} static void c2sig_virtual (void) {c2_virtual_secs + = 10 ;} static void c2sig_prof (void) {c2_prof_secs + = 10;} // Recursive Implementation of long unsigned int maid (unsigned int n) {if (n = 1 | n = 2) return 1; return fig (n-1) + fig (n-2 );}     

Below is the program running:

Related Article

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.