DESCRIPTION
The module
aem-timer provides a POSIX
Timer implementation based on the AEM notification mechanism. The
minimum system resolution of these timers is 1 ms.
DEFINITIONS
#include <aem.h>
This file is located in the directory {AEMSRC}/include/user in the AEM
source package. It must be installed and included with your source code.
SIGEV_AEM
When creating a timer, this specifies that the
notification mechanism to use is AEM.
CLOCK_AEMEVENT
When creating a timer, this specifies that the clock
will be AEM.
libaem
This is the AEM library. It is located in
the directory {AEMSRC}/lib
in the AEM source package. It must be installed and linked with your
source code.
INTERFACES
The following set of API
is provided by libaem.
int aemTimer_init (void);
Initialize the aem-timer functionality.
void
timer_handler (int, void *);
The timer handler prototype. There can be as many
handlers as there are timers. The first argument is the timer reference.
The second argument is a user address given when the timer was created.
It is the user responsability to give a valid address since no checking
is done by the kernel.
int
aemPOSIX_timer_create (int, struct sigevent *, int *);
Create a timer and
return a reference or an error. At the moment there is no limit
regarding the number of timer
that can be created by an application. The timer handler can be unique
for each created timer.
Example:
struct sigevent sigspec;
sigspec.sigev_notify
=
SIGEV_AEM;
/* Use tht AEM notification mechanism */
sigspec.sigev_notify_function
= (void *)timer_handler; /* Timer
handler */
sigspec.sigev_value.sival_ptr
= (void
*)NULL;
/* User argument to pass as the second parameter of the timer handler */
err = aemPOSIX_timer_create
(CLOCK_AEMEVENT, &sigspec, &id);
if (err < 0) {
printf ("Error
while creating timer (id=%d)\n", id);
perror
("");
exit (1);
}
int
aemPOSIX_timer_delete (int);
Delete the timer which
is specified in parameter.
int aemPOSIX_timer_settime (int, int, struct itimerspec *, struct
itimerspec *);
This function (re-)sets
and starts a timer. The first parameter is the timer reference. The
third parameter provides the new timer initialization value and
the fourth parameter is used to return the remaining time before
expiration (of the previous settings). The second parameter is not used
at the moment. The TIMER_ABSTIME
setting is not yet supported.
Example:
struct itimerspec value, ovalue;
printf ("Timer executed in 7sec
then iterate every 1sec\n");
value.it_interval.tv_sec = 7;
value.it_interval.tv_nsec = 0;
value.it_value.tv_sec = 1;
value.it_value.tv_nsec = 0;
aemPOSIX_timer_settime (id, 0,
&value, &ovalue);
int aemPOSIX_timer_gettime (int, struct itimerspec *);
Gets the timer actual
value. The first parameter is the timer
reference. The second parameter is used to return the remaining time before the timer expiration.
int aemPOSIX_timer_getoverrun (int);
Returns the number of missed expirations for the timer specified in
parameter.
EXAMPLE
The following example illustrates how to
use Posix Timers with AEM. This example is also available in the
examples that come with the source package.
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <stdlib.h>
#include <aem.h>
unsigned int counter;
void timer (int id, void *context)
{
struct itimerspec value, ovalue;
counter++;
printf ("%d: Timer event Id:%d [context=%p]\n",
counter, id, context);
if (counter == 10) {
printf ("stop timer now!!\n");
value.it_value.tv_sec = 0;
value.it_value.tv_nsec = 0;
value.it_interval.tv_sec =
0;
value.it_interval.tv_nsec = 0;
aemPOSIX_timer_settime (id, 0,
&value, &ovalue);
printf ("set timer: interval
tv_sec=%u, tv_nsec=%u, value tv_sec=%u, tv_nsec=%u\n",
ovalue.it_interval.tv_sec, ovalue.it_interval.tv_nsec,
ovalue.it_value.tv_sec, ovalue.it_value.tv_nsec);
printf ("Timer handler: sleep(5)
sec\n");
sleep (5);
printf ("Timer overrrun: %d
(should be 0)\n", aemPOSIX_timer_getoverrun (id));
printf ("Timer new period in 7sec
then iterate every 1sec\n");
value.it_interval.tv_sec =
7;
value.it_interval.tv_nsec = 0;
value.it_value.tv_sec = 1;
value.it_value.tv_nsec = 0;
aemPOSIX_timer_settime (id, 0,
&value, &ovalue);
printf ("set timer: interval
tv_sec=%u, tv_nsec=%u, value tv_sec=%u, tv_nsec=%u\n",
ovalue.it_interval.tv_sec, ovalue.it_interval.tv_nsec,
ovalue.it_value.tv_sec, ovalue.it_value.tv_nsec);
}
if (counter == 15) {
printf ("Timer handler: sleep(6)
sec\n");
sleep (6);
printf ("Timer overrrun: %d
(should NOT be 0)\n", aemPOSIX_timer_getoverrun (id));
aemPOSIX_timer_delete (id);
}
}
main (int argc, char **argv)
{
struct itimerspec value, ovalue;
struct sigevent sigspec;
unsigned long f;
int id;
int err;
aemTimer_init ();
sigspec.sigev_notify = SIGEV_AEM;
sigspec.sigev_notify_function = (void *)timer;
sigspec.sigev_value.sival_ptr = (void *)NULL;
err = aemPOSIX_timer_create (CLOCK_AEMEVENT,
&sigspec, &id);
if (err < 0) {
perror ("");
exit (1);
}
value.it_interval.tv_sec = 5;
value.it_interval.tv_nsec = 0;
value.it_value.tv_sec = 1;
value.it_value.tv_nsec = 0;
/* Set the timer and start it in 5 seconds */
aemPOSIX_timer_settime (id, 0, &value,
&ovalue);
printf ("Init timer: interval tv_sec=%u, tv_nsec=%u,
value tv_sec=%u, tv_nsec=%u\n",
value.it_interval.tv_sec,
value.it_interval.tv_nsec,
value.it_value.tv_sec,
value.it_value.tv_nsec);
while (1) {
int err;
pause ();
/* This prints out the timer
values every 1 sec */
err = aemPOSIX_timer_gettime (id,
&value);
if (err == 0) {
printf
("\t-> get timer: interval tv_sec=%u, tv_nsec=%u, value tv_sec=%u,
tv_nsec=%u\n",
value.it_interval.tv_sec, value.it_interval.tv_nsec,
value.it_value.tv_sec, value.it_value.tv_nsec);
}
else {
printf ("timer
%d has been deleted.\n", id);
exit (0);
}
}
}
|