SourceForge.net Logo

AEM - The Linux Asynchronous Event Mechanism





Back to main page





























AEM Timers

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);
        }
    }
}