Transcript ppt

Timers and Clocks II
Copyright ©: Nahrstedt, Angrave, Abdelzaher, Caccamo
1
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Sleep
#include <unistd.h>
unsigned sleep(unsigned seconds);
• Returns 0 if successful.
• Process can be awakened by a SIGNAL (sleep returns unslept time)
• sleep() may be implemented using SIGALRM; mixing calls to alarm(2) and
sleep() is a bad idea.
2
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Nanosleep



int nanosleep(const struct timespec *req, struct timespec *rem);
nanosleep() delays the execution of the program for at least the time
specified in *req. The function can return (with error) earlier if a signal has
been delivered to the process. In this case, it writes the remaining time into
the structure pointed to by rem unless rem is NULL.
The structure timespec is used to specify intervals of time with nanosecond
precision. It is specified in <time.h> and has the form
struct timespec {
time_t tv_sec;
long tv_nsec;
};
/* seconds */
/* nanoseconds */
3
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Nanosleep



Compared to sleep(3), nanosleep() has the advantage
of having higher resolution, not affecting any signals,
and it is standardized by POSIX.
nanosleep() is based on the kernel timer mechanism,
which has normally a resolution of 1-10 msec (see
man 7 time).
nanosleep() pauses always for at least the specified
time, however it can take up to 1 extra clock tick (110 msec) for the process to become runnable again. 4
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Elapsed time versus processor
time

The time function measures elapsed time or wall clock time.

The virtual time for a process is the amount of time that the process spends
in the running state
#include <sys/times.h>
clock_t times(struct tms *buffer);

The times() function shall fill the tms structure pointed to by buffer with
time-accounting information. The tms structure is defined in <sys/times.h>.
All times are measured in terms of the number of clock ticks used.

The tms_utime (of type clock_t) structure member is the CPU time charged
for the execution of user instructions of the calling process.

The tms_stime (of type clock_t) structure member is the CPU time charged
5
for execution by the system on behalf of the calling process.
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Interval Timers

Interval Timers



Set an alarm: on its expiration send a signal
Set a signal handler to do something with the signal
POSIX:TMR has at least 1 real-time clock, but a process can
create many independent timers

Most systems require the program be linked with the librt (-lrt) library
to use these functions.
6
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Real Time Clock & timers

Timers can be used to send a signal to a process after a specified period of
time has elapsed.

Timers may be used in one of two modes: one-shot or periodic:



when a one-shot timer is set up, a value time is specified. When that time has
elapsed, the operating system sends the process a signal and deletes the timer.
when a periodic timer is set up, both a value and an interval time are
specified. When the value time has elapsed, the operating system sends the
process a signal and reschedules the timer for interval time in the future. When
the interval time has elapsed, the OS sends another signal and again
reschedules the timer for interval time in the future. This will continue until the
process manually deletes the timer.
By default a timer will send the SIGALRM signal. If multiple timers are used
in one process, however, there is no way to determine which timer sent a
particular SIGALRM. Therefore, an alternate signal, like SIGUSR1, may be
specified when the timer is created.
7
Copyright ©: Nahrstedt, Angrave, Abdelzaher
POSIX.4 Real Time Clock &
timers
Resolution of timers:



Timers are maintained by the operating system, and they are only checked
periodically. A timer that expires between checks will be signaled (and
rescheduled if periodic) at the next check. As a result, a process may not
receive signals at the exact time(s) that it requested.
The period at which the timers are checked, called the clock resolution, is
operating system and hardware dependent (~1 msec in PC without add-on
high resolution timers). The actual value can be determined at runtime by
calling clock_getres() on the system-wide real-time clock
(CLOCK_REALTIME).
According to POSIX, there is at least 1 real-time clock (CLOCK_REALTIME)
8
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Real Time Clock & timers
Resolution of timers:


For example, suppose the OS checks the timers every 10 milliseconds
and a process schedules a periodic timer with value = 5 milliseconds
and interval = 21 milliseconds.
Quiz: Will the timer periodically expire every 21 milliseconds?
9
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Real Time Clock & timers
Resolution of timers:



For example, suppose the OS checks the timers every 10 milliseconds
and a process schedules a periodic timer with value = 5 milliseconds
and interval = 21 milliseconds.
Quiz: Will the timer periodically expire every 21 milliseconds?
Answer: If the period of timer is not an exact multiple of the
granularity of underlying clock (see man 7 time), then the interval
will be rounded up to the next multiple.
10
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Real Time Clock & timers
High Resolution Timers (require hardware support):


How to use high resolution timers?
There are no special requirements, except a recent glibc, to make use
of high resolution timers. When the high resolution timers are enabled
in the (Linux) kernel, then nanosleep, itimers and posix timers provide
the high resolution mode without changes to the source code.
11
Copyright ©: Nahrstedt, Angrave, Abdelzaher
High Resolution Timers
in Linux
See man 7 time:


Before Linux 2.6.21, the accuracy of timer and sleep system calls (see
below) was limited by the resolution of software clock (~1-10 msec)
Since kernel 2.6.21, Linux supports high-resolution timers (HRTs),
optionally configurable via CONFIG_HIGH_RES_TIMERS. On a system
that supports HRTs, the accuracy of sleep and timer system calls is
no longer constrained by the software clock, but instead can be as
accurate as the hardware allows (microsecond accuracy is typical of
modern hardware). You can determine whether high-resolution
timers are supported by checking the resolution returned by a call to
clock_getres(2) or looking at the "resolution" entries in /proc/timer_list.
12
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Real Time Clock & timers
Operations:

Create_timer() is used to create a new timer. As with clock_getres(), the systemwide real-time clock (CLOCK_REALTIME) should be used. The following code
shows how to create a timer that sends the default SIGALRM signal.
timer_t timer1;
// create a new timer that sends the default SIGALARM signal
if (timer_create (CLOCK_REALTIME, NULL, &timer1) != 0) {
perror(“timer create”);
exit(1);
NULL specifies that default SIGALARM
}
will be delivered!
13
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Timers: struct sigevent

If a different signal needs to be sent on timer expiration, then the
second argument of timer_create takes a pointer to struct sigevent
to specify a different signal to be sent.
struct sigevent {
int
int
union sigval
}

sigev_notify


SIGEV_NONE
SIGEV_SIGNAL
sigev_notify;
sigev_signo;
sigev_value;
/* notification type */
/* signal number */
/* Extra data to be delivered
with a real-time signal!
*/
- No notification from timer
- Send a signal
14
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Real Time Clock & timers
Operations:

The following code shows how to create a timer that sends the SIGUSR1 signal:
timer_t timerid;
struct sigevent se;
// Zero out the data structure and configure it for using SIGUSR1 signal
memset(&se, 0, sizeof(se));
se.sigev_signo = SIGUSR1;
se.sigev_notify = SIGEV_SIGNAL;
// Create a new timer that will send the SIGUSR1 signal
if (timer_create(CLOCK_REALTIME, &se, &timerid) != 0)
{
perror("Failed to create timer”);
exit(1);
}
15
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Real Time Clock & timers


The timer_settime() function is used to schedule a timer. The struct
itimerspec definition taken from /usr/include/linux/time.h is seen here.
The it_value member sets the time until the timer first expires. If it is set
to 0, the timer will never go off. The it_interval member sets the period of
the timer after it first expires. If it is set to 0, the timer will be one-shot.
struct itimerspec {
struct timespec it_interval; /* Timer period
*/
struct timespec it_value;
/* Timer initial expiration */
};
struct timespec {
time_t tv_sec;
long
tv_nsec;
};
/* seconds */
/* nanoseconds */
16
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Real Time Clock & timers

Example of scheduling timer1 (created in a preceding example) to go off in
2.5 seconds, and then every 100 milliseconds thereafter.
struct itimerspec timervals;
// The it_value member sets the time until the timer first goes off (2.5 seconds).
// The it_interval member sets the period of the timer after it first goes off (100 ms).
timervals.it_value.tv_sec = 2;
// 2 seconds
timervals.it_value.tv_nsec = 500000000;// 0.5 seconds (5e8 nanoseconds)
timervals.it_interval.tv_sec = 0;
// 0 seconds
timervals.it_interval.tv_nsec = 100000000;
// 100 milliseconds (1e8 nanoseconds)
// Schedule the timer
if (timer_settime(timerid, 0, &timervals, NULL) != 0)
{
perror("Failed to start timer");
exit(1);
}
Pointer to old itimerspec!
It specifies a “relative timer”: it does not use absolute time!
17
Copyright ©: Nahrstedt, Angrave, Abdelzaher
POSIX Real Time Clocks

POSIX defines the structure of time representation. There is at least 1 real time
clock. We can check the current time with clock_gettime and check the clock
resolution with clock_getres. See the following example (compile with -lrt):
#include <time.h>
struct timespec current_time, clock_resolution;
return_code = clock_gettime(CLOCK_REALTIME, &current_time);
//check return_code...
Printf(“current time in CLOCK_REALTIME is %ld sec, %ld nsec \n”,
current_time.tv_sec,
// the second portion
current_time.tv_nsec);
// the fractional portion in nsec representation
return_code = clock_getres(CLOCK_REALTIME, &clock_resolution)
//check return_code...
printf(“CLOCK_REALTIME’s resolution is %ld sec, %ld nsec \n”,
clock_resolution.tv_sec, clock_resolution.tv_nsec);
18