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       CLOCK_BOOTTIME (Since Linux 2.6.39)
47              Like  CLOCK_MONOTONIC, this is a monotonically increasing clock.
48              However, whereas the CLOCK_MONOTONIC clock does not measure  the
49              time  while a system is suspended, the CLOCK_BOOTTIME clock does
50              include the time during which the system is suspended.  This  is
51              useful   for   applications   that  need  to  be  suspend-aware.
52              CLOCK_REALTIME is not suitable for such applications, since that
53              clock is affected by discontinuous changes to the system clock.
54
55       CLOCK_REALTIME_ALARM (since Linux 3.0)
56              This  clock  is like CLOCK_REALTIME, but will wake the system if
57              it is suspended.  The caller must have the CAP_WAKE_ALARM  capa‐
58              bility in order to set a timer against this clock.
59
60       CLOCK_BOOTTIME_ALARM (since Linux 3.0)
61              This  clock  is like CLOCK_BOOTTIME, but will wake the system if
62              it is suspended.  The caller must have the CAP_WAKE_ALARM  capa‐
63              bility in order to set a timer against this clock.
64
65       As  well  as  the above values, clockid can be specified as the clockid
66       returned  by  a  call  to  clock_getcpuclockid(3)  or   pthread_getcpu‐
67       clockid(3).
68
69       The sevp argument points to a sigevent structure that specifies how the
70       caller should be notified when the timer expires.  For  the  definition
71       and general details of this structure, see sigevent(7).
72
73       The sevp.sigev_notify field can have the following values:
74
75       SIGEV_NONE
76              Don't asynchronously notify when the timer expires.  Progress of
77              the timer can be monitored using timer_gettime(2).
78
79       SIGEV_SIGNAL
80              Upon timer expiration, generate the signal sigev_signo  for  the
81              process.   See  sigevent(7)  for  general  details.  The si_code
82              field of the siginfo_t structure will be set  to  SI_TIMER.   At
83              any  point  in time, at most one signal is queued to the process
84              for a given timer; see timer_getoverrun(2) for more details.
85
86       SIGEV_THREAD
87              Upon timer expiration, invoke  sigev_notify_function  as  if  it
88              were  the  start  function of a new thread.  See sigevent(7) for
89              details.
90
91       SIGEV_THREAD_ID (Linux-specific)
92              As for SIGEV_SIGNAL, but the signal is targeted  at  the  thread
93              whose  ID  is  given  in sigev_notify_thread_id, which must be a
94              thread   in   the   same   process   as   the    caller.     The
95              sigev_notify_thread_id  field specifies a kernel thread ID, that
96              is, the value returned by clone(2) or gettid(2).  This  flag  is
97              intended only for use by threading libraries.
98
99       Specifying  sevp  as  NULL  is  equivalent to specifying a pointer to a
100       sigevent structure in which sigev_notify is  SIGEV_SIGNAL,  sigev_signo
101       is SIGALRM, and sigev_value.sival_int is the timer ID.
102

RETURN VALUE

104       On  success,  timer_create()  returns 0, and the ID of the new timer is
105       placed in *timerid.  On failure, -1 is returned, and errno  is  set  to
106       indicate the error.
107

ERRORS

109       EAGAIN Temporary error during kernel allocation of timer structures.
110
111       EINVAL Clock  ID,  sigev_notify, sigev_signo, or sigev_notify_thread_id
112              is invalid.
113
114       ENOMEM Could not allocate memory.
115

VERSIONS

117       This system call is available since Linux 2.6.
118

CONFORMING TO

120       POSIX.1-2001, POSIX.1-2008.
121

NOTES

123       A program may create multiple interval timers using timer_create().
124
125       Timers are not inherited by the child of a fork(2),  and  are  disarmed
126       and deleted during an execve(2).
127
128       The kernel preallocates a "queued real-time signal" for each timer cre‐
129       ated using timer_create().  Consequently, the number of timers is  lim‐
130       ited by the RLIMIT_SIGPENDING resource limit (see setrlimit(2)).
131
132       The  timers  created  by  timer_create()  are  commonly known as "POSIX
133       (interval) timers".  The POSIX timers API  consists  of  the  following
134       interfaces:
135
136       *  timer_create(): Create a timer.
137
138       *  timer_settime(2): Arm (start) or disarm (stop) a timer.
139
140       *  timer_gettime(2): Fetch the time remaining until the next expiration
141          of a timer, along with the interval setting of the timer.
142
143       *  timer_getoverrun(2): Return the overrun count  for  the  last  timer
144          expiration.
145
146       *  timer_delete(2): Disarm and delete a timer.
147
148       Since  Linux  3.10, the /proc/[pid]/timers file can be used to list the
149       POSIX timers for the process with PID pid.   See  proc(5)  for  further
150       information.
151
152       Since  Linux  4.10,  support  for POSIX timers is a configurable option
153       that is enabled by default.  Kernel support can  be  disabled  via  the
154       CONFIG_POSIX_TIMERS option.
155
156   C library/kernel differences
157       Part  of  the  implementation  of  the  POSIX timers API is provided by
158       glibc.  In particular:
159
160       *  Much of the functionality for  SIGEV_THREAD  is  implemented  within
161          glibc,  rather  than the kernel.  (This is necessarily so, since the
162          thread involved in handling the notification is  one  that  must  be
163          managed  by  the  C library POSIX threads implementation.)  Although
164          the notification delivered to the process is via  a  thread,  inter‐
165          nally   the   NPTL  implementation  uses  a  sigev_notify  value  of
166          SIGEV_THREAD_ID along with a real-time signal that  is  reserved  by
167          the implementation (see nptl(7)).
168
169       *  The  implementation of the default case where evp is NULL is handled
170          inside glibc, which invokes the underlying system call with a  suit‐
171          ably populated sigevent structure.
172
173       *  The timer IDs presented at user level are maintained by glibc, which
174          maps these IDs to the timer IDs employed by the kernel.
175
176       The POSIX timers system calls first appeared in Linux  2.6.   Prior  to
177       this,   glibc   provided   an   incomplete   user-space  implementation
178       (CLOCK_REALTIME timers only) using POSIX threads, and in glibc versions
179       before 2.17, the implementation falls back to this technique on systems
180       running pre-2.6 Linux kernels.
181

EXAMPLE

183       The program below takes two arguments: a sleep period in seconds, and a
184       timer  frequency in nanoseconds.  The program establishes a handler for
185       the signal it uses for the timer, blocks that signal, creates and  arms
186       a timer that expires with the given frequency, sleeps for the specified
187       number of seconds, and then unblocks the timer signal.   Assuming  that
188       the  timer  expired  at  least once while the program slept, the signal
189       handler will be invoked, and  the  handler  displays  some  information
190       about the timer notification.  The program terminates after one invoca‐
191       tion of the signal handler.
192
193       In the following example run, the program sleeps for  1  second,  after
194       creating  a timer that has a frequency of 100 nanoseconds.  By the time
195       the signal is unblocked and delivered, there have been around ten  mil‐
196       lion overruns.
197
198           $ ./a.out 1 100
199           Establishing handler for signal 34
200           Blocking signal 34
201           timer ID is 0x804c008
202           Sleeping for 1 seconds
203           Unblocking signal 34
204           Caught signal 34
205               sival_ptr = 0xbfb174f4;     *sival_ptr = 0x804c008
206               overrun count = 10004886
207
208   Program source
209
210       #include <stdlib.h>
211       #include <unistd.h>
212       #include <stdio.h>
213       #include <signal.h>
214       #include <time.h>
215
216       #define CLOCKID CLOCK_REALTIME
217       #define SIG SIGRTMIN
218
219       #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
220                               } while (0)
221
222       static void
223       print_siginfo(siginfo_t *si)
224       {
225           timer_t *tidp;
226           int or;
227
228           tidp = si->si_value.sival_ptr;
229
230           printf("    sival_ptr = %p; ", si->si_value.sival_ptr);
231           printf("    *sival_ptr = 0x%lx\n", (long) *tidp);
232
233           or = timer_getoverrun(*tidp);
234           if (or == -1)
235               errExit("timer_getoverrun");
236           else
237               printf("    overrun count = %d\n", or);
238       }
239
240       static void
241       handler(int sig, siginfo_t *si, void *uc)
242       {
243           /* Note: calling printf() from a signal handler is not safe
244              (and should not be done in production programs), since
245              printf() is not async-signal-safe; see signal-safety(7).
246              Nevertheless, we use printf() here as a simple way of
247              showing that the handler was called. */
248
249           printf("Caught signal %d\n", sig);
250           print_siginfo(si);
251           signal(sig, SIG_IGN);
252       }
253
254       int
255       main(int argc, char *argv[])
256       {
257           timer_t timerid;
258           struct sigevent sev;
259           struct itimerspec its;
260           long long freq_nanosecs;
261           sigset_t mask;
262           struct sigaction sa;
263
264           if (argc != 3) {
265               fprintf(stderr, "Usage: %s <sleep-secs> <freq-nanosecs>\n",
266                       argv[0]);
267               exit(EXIT_FAILURE);
268           }
269
270           /* Establish handler for timer signal */
271
272           printf("Establishing handler for signal %d\n", SIG);
273           sa.sa_flags = SA_SIGINFO;
274           sa.sa_sigaction = handler;
275           sigemptyset(&sa.sa_mask);
276           if (sigaction(SIG, &sa, NULL) == -1)
277               errExit("sigaction");
278
279           /* Block timer signal temporarily */
280
281           printf("Blocking signal %d\n", SIG);
282           sigemptyset(&mask);
283           sigaddset(&mask, SIG);
284           if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1)
285               errExit("sigprocmask");
286
287           /* Create the timer */
288
289           sev.sigev_notify = SIGEV_SIGNAL;
290           sev.sigev_signo = SIG;
291           sev.sigev_value.sival_ptr = &timerid;
292           if (timer_create(CLOCKID, &sev, &timerid) == -1)
293               errExit("timer_create");
294
295           printf("timer ID is 0x%lx\n", (long) timerid);
296
297           /* Start the timer */
298
299           freq_nanosecs = atoll(argv[2]);
300           its.it_value.tv_sec = freq_nanosecs / 1000000000;
301           its.it_value.tv_nsec = freq_nanosecs % 1000000000;
302           its.it_interval.tv_sec = its.it_value.tv_sec;
303           its.it_interval.tv_nsec = its.it_value.tv_nsec;
304
305           if (timer_settime(timerid, 0, &its, NULL) == -1)
306                errExit("timer_settime");
307
308           /* Sleep for a while; meanwhile, the timer may expire
309              multiple times */
310
311           printf("Sleeping for %d seconds\n", atoi(argv[1]));
312           sleep(atoi(argv[1]));
313
314           /* Unlock the timer signal, so that timer notification
315              can be delivered */
316
317           printf("Unblocking signal %d\n", SIG);
318           if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
319               errExit("sigprocmask");
320
321           exit(EXIT_SUCCESS);
322       }
323

SEE ALSO

325       clock_gettime(2), setitimer(2), timer_delete(2), timer_getoverrun(2),
326       timer_settime(2), timerfd_create(2), clock_getcpuclockid(3),
327       pthread_getcpuclockid(3), pthreads(7), sigevent(7), signal(7), time(7)
328

COLOPHON

330       This page is part of release 5.04 of the Linux man-pages project.  A
331       description of the project, information about reporting bugs, and the
332       latest version of this page, can be found at
333       https://www.kernel.org/doc/man-pages/.
334
335
336
337Linux                             2019-03-06                   TIMER_CREATE(2)
Impressum