1. Times in UNIX:
This material is taken from USP, Chapter 9.
Look at programs simpletiming, timeprint, and badtiming.
The struct tm:
int tm_sec; /* seconds after the minute [0,60] */ int tm_min; /* minutes after the hour [0,59] */ int tm_hour; /* hours since midnight [0,23] */ int tm_mday; /* day of the month [1,31] */ int tm_mon; /* months since January [0,11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday [0,6] */ int tm_yday; /* days since January 1 [0,365] */ int tm_isdst; /* flag indicating Daylight Savings Time */
Thread safe versions:
char *asctime_r(const struct tm *restrict timeptr, char *restrict buf); char *ctime_r(const time_t *clock, char *buf); struct tm *gmtime_r(const time_t *restrict timer, struct tm *restrict result); struct tm *localtime_r(const time_t *restrict timer, struct tm *restrict result);Times in POSIX:XSI --- struct timeval
time_t tv_sec; /* seconds since the Epoch */ time_t tv_usec; /* and microseconds */ int gettimeofday(struct timeval *restrict tp, void *restrict tzp);The second parameter must be NULL.
Look at gettimeofdaytiming and gettimeofdaytest.
Look at typical results of gettimeofdaytest on various platforms.
Times in POSIX:TMR --- struct timespec
time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */POSIX:TMR uses "clocks" represented by variables of type clockid_t.
int clock_getres(clockid_t clock_id, struct timespec *res); int clock_gettime(clockid_t clock_id, struct timespec *tp); int clock_settime(clockid_t clock_id, const struct timespec *tp);clock_getres gives the resolution for setting the clock.
Look at clockrealtimetiming and clockrealtimetest.
Look at typical results of clockrealtimetest on various platforms.
The times function
clock_t times(struct tms *buffer);Returns the elapsed time in clock ticks since some arbitrary time.
clock_t tms_utime; /* user CPU time of process */ clock_t tms_stime; /* system CPU time on behalf of process */ clock_t tms_cutime /* user CPU time of process and terminated children */ clock_t tms_cstime; /* system CPU time of process and terminated children */
Look at cpufraction and timechild.
Typical number of clock ticks per seconds is only 100, so this is not too useful.
timechild cpufraction The number of ticks per second is 100.000000 Total CPU time for operation is 3.130000 seconds Fraction of CPU time used is 0.695556 cpufraction used 315 clock ticks or 3.150000 seconds
High resolution time in Solaris: gethrtime
#include <sys/time.h> hrtime_t gethrtime(void);The gethrtime() function returns the current high-resolution real time.
Sleep Functions
You should be familiar with
#include <unistd.h> unsigned sleep(unsigned seconds);
This sleeps for at least seconds seconds.
It may sleep longer.
The sleep function interacts with SIGALRM so do not use
them concurrently.
It may be possible to get better resolution with the following:
#include <time.h> int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);This suspends execution until either the time interval specified by rqtp has elapsed or a signal is caught.
Look at the program nanotest, Program 9.6, and the results on various systems.
Interval Timer Concepts
POSIX:XSI Interval Timers
Structure used for times: struct itimerval
This contains two fileds of type struct timeval, the same type used
by gettimeofday:
struct timeval it_value; struct timeval it_interval;There are 3 type of timers, corresponding to the type of clock used.
#include <sys/time.h> int getitimer(int which, struct itimerval *value); int setitimer(int which, const struct itimerval *restrict value, struct itimerval *restrict ovalue);
Look at Program 9.8, xsitimer for timing a program using ITIMER_VIRTUAL.
Realtime Signals (review)
In 1993 a new signal interface was added to the POSIX standard.
#include <signal.h> struct sigaction { void (*sa_handler)(); /* SIG_DFL, SIG_IGN, or pointer to function */ void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; /* additional signals to be blocked during execution of handler */ int sa_flags; /* special flags and options */ };This defines a new data type: siginfo_t which is a structure containing at least the following:
int si_signo; /* signal number */ int si_code; /* cause of the signal */ union sigval si_value; /* signal value */where the union sigval contains at least:
int sival_int; void *sival_ptr;When the sa_flags field has the SA_SIGINFO flag set, then sa_sigaction is used for the signal handler rather than sa_handler.
The system call to send one of these signals is called sigqueue
rather than kill:
#include <signal.h> int sigqueue(pid_t pid, int signo, const union sigval value);
On some systems, only certain signals can be queued, those between SIGRTMIN and SIGRTMAX.
Program 9.9 shows a program to send a queued signal to a process. Note that there is no command line function similar to kill.
Program 9.10, gives an example program that can receive SIGUSR1 signals.
POSIX:TMR Interval Timers
Structure used for times: struct itimerspec
This contains two fileds of type struct timespec, the same type used
by clock_gettime:
struct timespec it_interval; struct timespec it_value;You create a timer before you can do a set or get.
#include <signal.h> #include <time.h> int timer_create(clockid_t clock_id, struct sigevent *restrict evp, timer_t *restrict timerid); struct sigevent { int sigev_notify /* notification type */ int sigev_signo; /* signal number */ union sigval sigev_value; /* signal value */ }; union sigval { int sival_int; /* integer value */ void *sival_ptr; /* pointer value */ };
#include <time.h> int timer_getoverrun(timer_t timerid); int timer_gettime(timer_t timerid, struct itimerspec *value); int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue);The flags parameter indicates with relative or absolute times.
Look at Program 9.12, tmrtimer for timing a program using CLOCK_REALTIME.
Timer Drift, Overruns, and Absolute Time
Problem with relative times:
expiration number | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
time | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 |
drift | 0 | 8 | 16 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 |
desired expiration | 22 | 44 | 66 | 88 | 110 | 132 | 154 | 176 | 198 | 220 | 242 |
timer set for | 22 | 22 | 22 | 22 | 22 | 22 | 22 | 22 | 22 | 22 | 22 |
rounded to resolution | 30 | 30 | 30 | 30 | 30 | 30 | 30 | 30 | 30 | 30 | 30 |
With absolute time, you specify the absolute time the timer should expire and the system sets the timer with the appropriate relative time based on the current time.
expiration number | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
time | 0 | 30 | 50 | 70 | 90 | 110 | 140 | 160 | 180 | 200 | 220 |
drift | 0 | 8 | 6 | 4 | 2 | 0 | 8 | 6 | 4 | 2 | 0 |
desired expiration | 22 | 44 | 66 | 88 | 110 | 132 | 154 | 176 | 198 | 220 | 242 |
timer set for | 22 | 14 | 16 | 18 | 20 | 22 | 14 | 16 | 18 | 20 | 22 |
rounded to resolution | 30 | 20 | 20 | 20 | 20 | 20 | 30 | 20 | 20 | 20 | 30 |
The program abstime uses TMR timers to explore 3 ways of setting up periodic timers.
abstime -a | -r | -p [inctime [numtimes [spintime]]]
Look at results of running abstime on Linux and Solaris.
Counting Signals
The program timesignals wait for a signal to come in and then times how long it takes 1000 additional signals to come in.
The Program mulitkill sends signals as fast as possible.
Look at the output from these functions.
How would you modify these two functions so that you could tell how many signals are sent before 1000 signals are received?