TOC PREV NEXT INDEX

POSIX 1.b Migration Guide


Clocks and Timers

Introduction

The most important change in the clock and timer interface is that the following Draft 9 functions have no equivalent in POSIX.1b:

With non-trivial changes to the code, programs using the above functions can be migrated to POSIX.1b. Also, timer overrun counts are handled with a new function, timer_getoverrun(), instead of through the Draft 9
itimercb structure.

Refer to "Changes from Draft 9 to POSIX.1b" for equivalence between function names from Draft 9 and POSIX.1b.

Resolution of a Clock

The Draft 9 resclock() function obtains the maximum value of a clock. The equivalent clock_getres() function from POSIX.1b does not allow this. The following code is a comparison:

Draft 9 Code

#include <sys/timers.h>

main()
{
struct timespec res, maxval;
:
resclock(TIMEOFDAY, &res, &maxval);
printf("Resolution: %ld sec %ld nsec\n",
res.tv_sec, res.tv_nsec);
printf("Max. val.: %ld sec %ld nsec\n",
maxval.tv_sec, maxval.tv_nsec);
:
}

Equivalent POSIX.1b Code

#include <time.h>

main()
{
struct timespec res;
:
clock_getres(CLOCK_REALTIME, &res);
printf("Resolution: %ld sec %ld nsec\n",
res.tv_sec, res.tv_nsec);
:
}

Creation and Deletion of a Timer

The timer creation interface has changed from Draft 9 to POSIX.1b. In Draft 9, the function mktimer() returned timer_t. In POSIX.1b, the function timer_create() returns an int with a result argument of the type timer_t.

Also, there are differences in how notification type is specified. In POSIX.1b code, the sa_flags flag is set to SA_SIGINFO, and the sigev_notify field is set to SIGEV_SIGNAL to ensure the use of a real-time signal. In addition, the sa_sigaction member is used to set the signal handler.

Timers are deleted with the timer_delete() function, instead of with rmtimer().

Draft 9 Code

#include <sys/timers.h>
#include <sys/events.h>

void event_handler(void *evt_value,
evt_class_t evt_class, evtset_t evt_mask);

main()
{
timer_t timer1, timer2;
struct itimercb itimercbp;
:
timer1 = mktimer(TIMEOFDAY, DELIVERY_SIGNALS, NULL);
:
rmtimer(timer1);
:
itimercbp.itcb_event.evt_handler = event_handler;
itimercbp.itcb_event.evt_value = NULL;
itimercbp.itcb_event.evt_class = EVTCLASS_MIN;
evtemptyset(&itimercbp.itcb_event.evt_classmask);
itimercbp.itcb_count = 0;

timer2 = mktimer(TIMEOFDAY, DELIVERY_EVENTS,
&itimercbp);
:
rmtimer(timer2);
:
}

void event_handler(evt_value, evt_class, evt_mask)
void *evt_value;
evt_class_t evt_class;
evtset_t evt_mask;
{
:
:
}

Equivalent POSIX.1b Code

#include <time.h>
#include <signal.h>

void signal_handler(int signo, siginfo_t *info,
void *context);

main()
{
timer_t timer1, timer2;
struct sigevent se;
struct sigaction sa;
:
timer_create(CLOCK_REALTIME, NULL, &timer1);
:
timer_delete(timer1);
:
se.sigev_signo = SIGRTMIN;
se.sigev_value.sival_ptr = NULL;
se.sigev_notify = SIGEV_SIGNAL;

sa.sa_sigaction = signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;

sigaction(SIGRTMIN, &sa, NULL);

timer_create(CLOCK_REALTIME, &se, &timer2);
:
timer_delete(timer2);
:
}

void signal_handler(signo, info, context)
int signo;
siginfo_t *info;
void *context;
{
:
:
}

Setting a Timer

Draft 9 provides two functions, abstimer() and reltimer(), to set the value of a timer. These are used to set the absolute and the relative value, respectively. POSIX.1b provides only one function, timer_settime(), and requires an extra flag argument to choose between absolute and relative countdowns.

Draft 9 Code

#include <sys/timers.h>

main()
{
timer_t timer;
struct itimerspec value, ovalue;
struct timespec now;
:
timer = mktimer(TIMEOFDAY, DELIVERY_SIGNALS, NULL);
:
value.it_value.tv_sec = 2;
value.it_value.tv_nsec = 0;
value.it_interval.tv_sec = 0;
value.it_interval.tv_nsec = 0;

reltimer(timer, &value, &ovalue);
:
getclock(TIMEOFDAY, &now);

value.it_value.tv_sec = now.tv_sec + 5;
value.it_value.tv_nsec = 0;
value.it_interval.tv_sec = 0;
value.it_interval.tv_nsec = 0;

abstimer(timer, &value, &ovalue);
:
}

Equivalent POSIX.1b Code

#include <time.h>

main()
{
timer_t timer;
struct itimerspec value, ovalue;
struct timespec now;
:
timer_create(CLOCK_REALTIME, NULL, &timer);
:
value.it_value.tv_sec = 2;
value.it_value.tv_nsec = 0;
value.it_interval.tv_sec = 0;
value.it_interval.tv_nsec = 0;

timer_settime(timer, 0, &value, &ovalue);
:
clock_gettime(CLOCK_REALTIME, &now);

value.it_value.tv_sec = now.tv_sec + 5;
value.it_value.tv_nsec = 0;
value.it_interval.tv_sec = 0;
value.it_interval.tv_nsec = 0;

timer_settime(timer, TIMER_ABSTIME, &value,
&ovalue);
:
}

Determining Timer Overrun Count(s)

The following example shows how Draft 9 code, which determines the timer overrun count(s), can be migrated to the POSIX.1b:

Draft 9 Code

#include <sys/timers.h>
#include <sys/events.h>

void event_handler(void *evt_value,
evt_class_t evt_class, evtset_t evt_mask);

main()
{
timer_t timer;
struct itimercb itimercbp;
:
itimercbp.itcb_event.evt_handler = event_handler;
itimercbp.itcb_event.evt_value = NULL;
itimercbp.itcb_event.evt_class = EVTCLASS_MIN;
evtemptyset(&itimercbp.itcb_event.evt_classmask);
itimercbp.itcb_count = 0;

timer = mktimer(TIMEOFDAY, DELIVERY_EVENTS,
&itimercbp);
:
printf("Overrun count = %d\n",
itimercbp.itcb_count);
:
}

void event_handler(evt_value, evt_class, evt_mask)
void *evt_value;
evt_class_t evt_class;
evtset_t evt_mask;
{
:
:
}

Equivalent POSIX.1b Code

#include <time.h>

void signal_handler(int signo, siginfo_t *info,
void *context);

int overrun;
timer_t timer;

main()
{
struct sigevent se;
struct sigaction sa;
:
se.sigev_signo = SIGRTMIN;
se.sigev_value.sival_ptr = NULL;
se.sigev_notify = SIGEV_SIGNAL;

sa.sa_sigaction = signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;

sigaction(SIGRTMIN, &sa, NULL);

timer_create(CLOCK_REALTIME, &se, &timer);
:
printf("Overrun count = %d\n", overrun);
:
}

void signal_handler(signo, info, context)
int signo;
siginfo_t *info;
void *context;
{
:
overrun = timer_getoverrun(timer);
:
}

Changes from Draft 9 to POSIX.1b

Almost all Draft 9 timer functionality has an equivalent in POSIX.1b. Where there is no equivalent function, it can be emulated with a series of other functions. There are some notable differences between the two interfaces.

Clock And Timer Interface
Draft 9
POSIX.1b
<sys/timers.h>
<time.h>
TIMEOFDAY
CLOCK_REALTIME
getclock()
clock_gettime()
setclock()
clock_settime()
resclock()
clock_getres()
mktimer()
timer_create()
rmtimer()
timer_delete()
gettimer()
timer_gettime()
reltimer()
timer_settime(timerid,0,...)
abstimer()
timer_settime(timerid, TIMER_ABSTIME,..)
itimercb.itcb_count
timer_getoverrun()
resabs()
Documentation
resrel()
Documentation
ressleep()
Documentation

Overrun Count

The overrun count is handled differently in the Draft 9 and POSIX.1b interfaces. In Draft 9, the structure itimercb encloses the overrun count for the timer. In POSIX.1b, no separate structure item is used. The overrun count is accessed through the new timer_getoverrun() function.

Signal/Event Associated with a Timer

In Draft 9, the structure itimercb encloses an event associated with a timer. In POSIX.1b, this structure no longer exists. Instead, a sigevent structure for a real-time signal is used as an argument to timer_create().

Signal Number

In Draft 9, the flag DELIVERY_SIGNALS for notify_type in mktimer() delivers the SIGALRM signal. If the flag is DELIVERY_EVENTS, an event is associated with the timer. In POSIX.1b if the sigevent structure passed to timer_create() is NULL, the default signal is used (which is SIGALRM for CLOCK_REALTIME). If the sigevent structure for timer_create() specifies SIGEV_SIGNAL and if the SA_SIGINFO bit is set for any real-time signal between SIGRTMIN and SIGRTMAX, then that signal is queued.

Relative and Absolute Times

Draft 9 provides two functions, reltimer() and abstimer(), to set a timer either with a relative offset or the absolute value, respectively. In POSIX.1b, the timer_settime() function does both jobs. The new TIMER_ABSTIME flag specifies the choice of an absolute timer instead of a relative timer.

Resolutions

With non-trivial changes to the code, programs using resrel(), resabs(), and ressleep() can be migrated to POSIX.1b.

Get Timer Value

The gettimer() function from Draft 9 always returns the it_interval last set by reltimer() or abstimer(). On the other hand, the timer_gettime() function from POSIX.1b always returns how much time remains on the timer.

Create Timer

The mktimer() function from Draft 9 returns a timer_t, and has a notify_type argument. The timer_create() function from POSIX.1b has a timer_t as a result argument, and returns an int. The notification type is handled through the sigev_notify entry in the sigevent structure, which is an argument.

Clock Resolution

The resclock() function from Draft 9 provides an extra argument to obtain maximum possible time value for a clock. The timer_getres() function from POSIX.1b does not provide such an argument.

nanosleep()

In Draft 9, the second argument to the nanosleep() function is updated to contain the unslept time. In POSIX.1b, this is done only if that argument is
non-NULL.

Pending Signals/Events

Draft 9 specifies that deleting a timer would cancel any pending events for that timer. However for POSIX.1b, even after deleting a timer, signals queued from it continue to be queued. Also with POSIX.1b, signals queued from a timer continue to be queued, even after disarming or resetting a timer.

Interoperability

There is no inter-operability between the Draft 9 and final standard versions of clocks and timers. These are distinct and separate features. However, the system-wide time-of-day clock is the same for all processes. Two processes, one a Draft 9 process using TIMEOFDAY, and another POSIX.1b process using CLOCK_REALTIME can access the same clock.



LynuxWorks, Inc.
855 Branham Lane East
San Jose, CA 95138
http://www.lynuxworks.com
1.800.255.5969
TOC PREV NEXT INDEX