timer_create()

Create a timer

Synopsis:

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

int timer_create( clockid_t clock_id,
                  struct sigevent * evp,
                  timer_t * timerid );

Arguments:

clock_id
The clock source that you want to use; one of:
  • CLOCK_REALTIME — the standard POSIX-defined clock. Timers based on this clock wake up the processor if it's in a power-saving mode.
  • CLOCK_SOFTTIME — (a QNX Neutrino extension) this clock is active only when the processor isn't in a power-saving mode. For example, an application using a CLOCK_SOFTTIME timer to sleep wouldn't wake up the processor when the application was due to wake up. This will allow the processor to enter a power-saving mode.

    While the processor isn't in a power-saving mode, CLOCK_SOFTTIME behaves the same as CLOCK_REALTIME.

  • CLOCK_MONOTONIC — this clock always increases at a constant rate and can't be adjusted.
  • (QNX Neutrino 7.0.1 or later) CLOCK_THREAD_CPUTIME_ID or a thread CPU-time clock ID returned by pthread_getcpuclockid() or ClockId(). The timeout that you set for this type of timer represents the thread's execution time. CLOCK_THREAD_CPUTIME_ID is a special clock ID that refers to the calling thread. See Monitoring execution times in the “Understanding the Microkernel's Concept of Time” chapter of the QNX Neutrino Programmer's Guide.
    Note: You can have only one timer at a time associated with a thread. You can't currently create a timer for a process CPU-time clock.

For more information about the different clocks, see Other clock sources in the Clocks, Timers, and Getting a Kick Every So Often of Getting Started with QNX Neutrino.

evp
NULL, or a pointer to a sigevent structure containing the event that you want to deliver when the timer fires.
timerid
A pointer to a timer_t object where the function stores the ID of the new timer.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The timer_create() function creates a per-process timer using the specified clock source, clock_id, as the timing base.

Note:
  • This function fails if the clock ID corresponds to the CPU-time clock of a process or thread different from the process or thread invoking the function.
  • In order to create a timer that sends a pulse to a process belonging to a different user, your process must have the PROCMGR_AID_CONNECTION ability enabled. For more information, see procmgr_ability().

You can use the time ID that the function stores in timerid in subsequent calls to timer_gettime(), timer_settime(), and timer_delete().

The timer is created in the disabled state, and isn't enabled until you call timer_settime().

We recommend the following event types:

If the evp argument is NULL, a SIGALRM signal is sent to your process when the timer expires. To specify a handler for this signal, call sigaction().

Returns:

0
Success. The timerid argument is set to the timer's ID.
-1
An error occurred (errno is set).

Errors:

EAGAIN
One of the following occurred:
  • All timers are in use. You'll have to wait for a process to release one.
  • (QNX Neutrino 7.0.1 or later) There's already a timer associated with the given thread CPU-time clock.
EINVAL
One of the following occurred:
  • The clock_id isn't one of the valid CLOCK_* constants.
  • (QNX Neutrino 7.0.1 or later) You tried to create a timer for a process CPU-time clock.
EPERM
The calling process doesn't have the required permission; see procmgr_ability().

Examples:

/*
 * Demonstrate how to set up a timer that, on expiry, 
 * sends us a pulse.  This example sets the first 
 * expiry to 1.5 seconds and the repetition interval 
 * to 1.5 seconds.
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <sys/netmgr.h>
#include <sys/neutrino.h>

#define MY_PULSE_CODE   _PULSE_CODE_MINAVAIL

typedef union {
        struct _pulse   pulse;
        /* your other message structures would go 
           here too */
} my_message_t;

int main()
{
   struct sigevent         event;
   struct itimerspec       itime;
   timer_t                 timer_id;
   int                     chid;
   int                     rcvid;
   my_message_t            msg;
   struct sched_param      scheduling_params;
   int prio;

   chid = ChannelCreate(0);
 
  /* Get our priority. */
    if (SchedGet( 0, 0, &scheduling_params) != -1)
    {
       prio = scheduling_params.sched_priority;
    }
    else
    {
       prio = 10;
    }
 
   event.sigev_notify = SIGEV_PULSE;
   event.sigev_coid = ConnectAttach(ND_LOCAL_NODE, 0, 
                                    chid, 
                                    _NTO_SIDE_CHANNEL, 0);
   event.sigev_priority = prio;
   event.sigev_code = MY_PULSE_CODE;
   timer_create(CLOCK_MONOTONIC, &event, &timer_id);

   itime.it_value.tv_sec = 1;
   /* 500 million nsecs = .5 secs */
   itime.it_value.tv_nsec = 500000000; 
   itime.it_interval.tv_sec = 1;
   /* 500 million nsecs = .5 secs */
   itime.it_interval.tv_nsec = 500000000; 
   timer_settime(timer_id, 0, &itime, NULL);

   /*
    * As of the timer_settime(), we will receive our pulse 
    * in 1.5 seconds (the itime.it_value) and every 1.5 
    * seconds thereafter (the itime.it_interval)
    */

   for (;;) {
       rcvid = MsgReceive(chid, &msg, sizeof(msg), NULL);
       if (rcvid == 0) { /* we got a pulse */
            if (msg.pulse.code == MY_PULSE_CODE) {
                printf("we got a pulse from our timer\n");
            } /* else other pulses ... */
       } /* else other messages ... */
   }
   return(EXIT_SUCCESS);
}

Classification:

POSIX 1003.1

Safety:  
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes

Caveats:

This version of timer_create() is different from the QNX 4 version, which was based on a draft standard.