1TIMER_CREATE(2)            Linux Programmer's Manual           TIMER_CREATE(2)
2
3
4

NAME

6       timer_create - create a POSIX per-process timer
7

SYNOPSIS

9       #include <signal.h>
10       #include <time.h>
11
12       int timer_create(clockid_t clockid, struct sigevent *sevp,
13                        timer_t *timerid);
14
15       Link with -lrt.
16
17   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
18
19       timer_create(): _POSIX_C_SOURCE >= 199309L
20

DESCRIPTION

22       timer_create() creates a new per-process interval timer.  The ID of the
23       new timer is returned in the buffer pointed to by timerid,  which  must
24       be a non-NULL pointer.  This ID is unique within the process, until the
25       timer is deleted.  The new timer is initially disarmed.
26
27       The clockid argument specifies the clock that the  new  timer  uses  to
28       measure time.  It can be specified as one of the following values:
29
30       CLOCK_REALTIME
31              A settable system-wide real-time clock.
32
33       CLOCK_MONOTONIC
34              A  nonsettable monotonically increasing clock that measures time
35              from some unspecified point in the past  that  does  not  change
36              after system startup.
37
38       CLOCK_PROCESS_CPUTIME_ID (since Linux 2.6.12)
39              A  clock  that  measures  (user and system) CPU time consumed by
40              (all of the threads in) the calling process.
41
42       CLOCK_THREAD_CPUTIME_ID (since Linux 2.6.12)
43              A clock that measures (user and system) CPU time consumed by the
44              calling thread.
45
46       As  well  as  the above values, clockid can be specified as the clockid
47       returned  by  a  call  to  clock_getcpuclockid(3)  or   pthread_getcpu‐
48       clockid(3).
49
50       The sevp argument points to a sigevent structure that specifies how the
51       caller should be notified when the timer expires.  For  the  definition
52       and general details of this structure, see sigevent(7).
53
54       The sevp.sigev_notify field can have the following values:
55
56       SIGEV_NONE
57              Don't asynchronously notify when the timer expires.  Progress of
58              the timer can be monitored using timer_gettime(2).
59
60       SIGEV_SIGNAL
61              Upon timer expiration, generate the signal sigev_signo  for  the
62              process.   See  sigevent(7)  for  general  details.  The si_code
63              field of the siginfo_t structure will be set  to  SI_TIMER.   At
64              any  point  in time, at most one signal is queued to the process
65              for a given timer; see timer_getoverrun(2) for more details.
66
67       SIGEV_THREAD
68              Upon timer expiration, invoke  sigev_notify_function  as  if  it
69              were  the  start  function of a new thread.  See sigevent(7) for
70              details.
71
72       SIGEV_THREAD_ID (Linux-specific)
73              As for SIGEV_SIGNAL, but the signal is targeted  at  the  thread
74              whose  ID  is  given  in sigev_notify_thread_id, which must be a
75              thread   in   the   same   process   as   the    caller.     The
76              sigev_notify_thread_id  field specifies a kernel thread ID, that
77              is, the value returned by clone(2) or gettid(2).  This  flag  is
78              intended only for use by threading libraries.
79
80       Specifying  sevp  as  NULL  is  equivalent to specifying a pointer to a
81       sigevent structure in which sigev_notify is  SIGEV_SIGNAL,  sigev_signo
82       is SIGALRM, and sigev_value.sival_int is the timer ID.
83

RETURN VALUE

85       On  success,  timer_create()  returns 0, and the ID of the new timer is
86       placed in *timerid.  On failure, -1 is returned, and errno  is  set  to
87       indicate the error.
88

ERRORS

90       EAGAIN Temporary error during kernel allocation of timer structures.
91
92       EINVAL Clock  ID,  sigev_notify, sigev_signo, or sigev_notify_thread_id
93              is invalid.
94
95       ENOMEM Could not allocate memory.
96

VERSIONS

98       This system call is available since Linux 2.6.
99

CONFORMING TO

101       POSIX.1-2001.
102

NOTES

104       A program may create multiple interval timers using timer_create().
105
106       Timers are not inherited by the child of a fork(2),  and  are  disarmed
107       and deleted during an execve(2).
108
109       The kernel preallocates a "queued real-time signal" for each timer cre‐
110       ated using timer_create().  Consequently, the number of timers is  lim‐
111       ited by the RLIMIT_SIGPENDING resource limit (see setrlimit(2)).
112
113       The  timers  created  by  timer_create()  are  commonly known as "POSIX
114       (interval) timers".  The POSIX timers API  consists  of  the  following
115       interfaces:
116
117       *  timer_create(): Create a timer.
118
119       *  timer_settime(2): Arm (start) or disarm (stop) a timer.
120
121       *  timer_gettime(2): Fetch the time remaining until the next expiration
122          of a timer, along with the interval setting of the timer.
123
124       *  timer_getoverrun(2): Return the overrun count  for  the  last  timer
125          expiration.
126
127       *  timer_delete(2): Disarm and delete a timer.
128
129       Part  of  the  implementation  of  the  POSIX timers API is provided by
130       glibc.  In particular:
131
132       *  The functionality for  SIGEV_THREAD  is  implemented  within  glibc,
133          rather than the kernel.
134
135       *  The timer IDs presented at user level are maintained by glibc, which
136          maps these IDs to the timer IDs employed by the kernel.
137
138       The POSIX timers system calls first appeared in Linux  2.6.   Prior  to
139       this,   glibc   provided   an   incomplete   user-space  implementation
140       (CLOCK_REALTIME timers only) using POSIX  threads,  and  current  glibc
141       falls back to this implementation on systems running pre-2.6 Linux ker‐
142       nels.
143

EXAMPLE

145       The program below takes two arguments: a sleep period in seconds, and a
146       timer  frequency in nanoseconds.  The program establishes a handler for
147       the signal it uses for the timer, blocks that signal, creates and  arms
148       a timer that expires with the given frequency, sleeps for the specified
149       number of seconds, and then unblocks the timer signal.   Assuming  that
150       the  timer  expired  at  least once while the program slept, the signal
151       handler will be invoked, and  the  handler  displays  some  information
152       about the timer notification.  The program terminates after one invoca‐
153       tion of the signal handler.
154
155       In the following example run, the program sleeps for  1  second,  after
156       creating  a timer that has a frequency of 100 nanoseconds.  By the time
157       the signal is unblocked and delivered, there have been around ten  mil‐
158       lion overruns.
159
160           $ ./a.out 1 100
161           Establishing handler for signal 34
162           Blocking signal 34
163           timer ID is 0x804c008
164           Sleeping for 1 seconds
165           Unblocking signal 34
166           Caught signal 34
167               sival_ptr = 0xbfb174f4;     *sival_ptr = 0x804c008
168               overrun count = 10004886
169
170   Program source
171
172       #include <stdlib.h>
173       #include <unistd.h>
174       #include <stdio.h>
175       #include <signal.h>
176       #include <time.h>
177
178       #define CLOCKID CLOCK_REALTIME
179       #define SIG SIGRTMIN
180
181       #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
182                               } while (0)
183
184       static void
185       print_siginfo(siginfo_t *si)
186       {
187           timer_t *tidp;
188           int or;
189
190           tidp = si->si_value.sival_ptr;
191
192           printf("    sival_ptr = %p; ", si->si_value.sival_ptr);
193           printf("    *sival_ptr = 0x%lx\n", (long) *tidp);
194
195           or = timer_getoverrun(*tidp);
196           if (or == -1)
197               errExit("timer_getoverrun");
198           else
199               printf("    overrun count = %d\n", or);
200       }
201
202       static void
203       handler(int sig, siginfo_t *si, void *uc)
204       {
205           /* Note: calling printf() from a signal handler is not
206              strictly correct, since printf() is not async-signal-safe;
207              see signal(7) */
208
209           printf("Caught signal %d\n", sig);
210           print_siginfo(si);
211           signal(sig, SIG_IGN);
212       }
213
214       int
215       main(int argc, char *argv[])
216       {
217           timer_t timerid;
218           struct sigevent sev;
219           struct itimerspec its;
220           long long freq_nanosecs;
221           sigset_t mask;
222           struct sigaction sa;
223
224           if (argc != 3) {
225               fprintf(stderr, "Usage: %s <sleep-secs> <freq-nanosecs>\n",
226                       argv[0]);
227               exit(EXIT_FAILURE);
228           }
229
230           /* Establish handler for timer signal */
231
232           printf("Establishing handler for signal %d\n", SIG);
233           sa.sa_flags = SA_SIGINFO;
234           sa.sa_sigaction = handler;
235           sigemptyset(&sa.sa_mask);
236           if (sigaction(SIG, &sa, NULL) == -1)
237               errExit("sigaction");
238
239           /* Block timer signal temporarily */
240
241           printf("Blocking signal %d\n", SIG);
242           sigemptyset(&mask);
243           sigaddset(&mask, SIG);
244           if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1)
245               errExit("sigprocmask");
246
247           /* Create the timer */
248
249           sev.sigev_notify = SIGEV_SIGNAL;
250           sev.sigev_signo = SIG;
251           sev.sigev_value.sival_ptr = &timerid;
252           if (timer_create(CLOCKID, &sev, &timerid) == -1)
253               errExit("timer_create");
254
255           printf("timer ID is 0x%lx\n", (long) timerid);
256
257           /* Start the timer */
258
259           freq_nanosecs = atoll(argv[2]);
260           its.it_value.tv_sec = freq_nanosecs / 1000000000;
261           its.it_value.tv_nsec = freq_nanosecs % 1000000000;
262           its.it_interval.tv_sec = its.it_value.tv_sec;
263           its.it_interval.tv_nsec = its.it_value.tv_nsec;
264
265           if (timer_settime(timerid, 0, &its, NULL) == -1)
266                errExit("timer_settime");
267
268           /* Sleep for a while; meanwhile, the timer may expire
269              multiple times */
270
271           printf("Sleeping for %d seconds\n", atoi(argv[1]));
272           sleep(atoi(argv[1]));
273
274           /* Unlock the timer signal, so that timer notification
275              can be delivered */
276
277           printf("Unblocking signal %d\n", SIG);
278           if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
279               errExit("sigprocmask");
280
281           exit(EXIT_SUCCESS);
282       }
283

SEE ALSO

285       clock_gettime(2), setitimer(2), timer_delete(2), timer_getoverrun(2),
286       timer_settime(2), timerfd_create(2), clock_getcpuclockid(3),
287       pthread_getcpuclockid(3), pthreads(7), sigevent(7), signal(7), time(7)
288

COLOPHON

290       This page is part of release 3.53 of the Linux man-pages project.  A
291       description of the project, and information about reporting bugs, can
292       be found at http://www.kernel.org/doc/man-pages/.
293
294
295
296Linux                             2010-09-27                   TIMER_CREATE(2)
Impressum