1TIMER_CREATE(2) Linux Programmer's Manual TIMER_CREATE(2)
2
3
4
6 timer_create - create a POSIX per-process timer
7
9 #include <signal.h> /* Definition of SIGEV_* constants */
10 #include <time.h>
11
12 int timer_create(clockid_t clockid, struct sigevent *restrict sevp,
13 timer_t *restrict timerid);
14
15 Link with -lrt.
16
17 Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
18
19 timer_create():
20 _POSIX_C_SOURCE >= 199309L
21
23 timer_create() creates a new per-process interval timer. The ID of the
24 new timer is returned in the buffer pointed to by timerid, which must
25 be a non-null pointer. This ID is unique within the process, until the
26 timer is deleted. The new timer is initially disarmed.
27
28 The clockid argument specifies the clock that the new timer uses to
29 measure time. It can be specified as one of the following values:
30
31 CLOCK_REALTIME
32 A settable system-wide real-time clock.
33
34 CLOCK_MONOTONIC
35 A nonsettable monotonically increasing clock that measures time
36 from some unspecified point in the past that does not change af‐
37 ter system startup.
38
39 CLOCK_PROCESS_CPUTIME_ID (since Linux 2.6.12)
40 A clock that measures (user and system) CPU time consumed by
41 (all of the threads in) the calling process.
42
43 CLOCK_THREAD_CPUTIME_ID (since Linux 2.6.12)
44 A clock that measures (user and system) CPU time consumed by the
45 calling thread.
46
47 CLOCK_BOOTTIME (Since Linux 2.6.39)
48 Like CLOCK_MONOTONIC, this is a monotonically increasing clock.
49 However, whereas the CLOCK_MONOTONIC clock does not measure the
50 time while a system is suspended, the CLOCK_BOOTTIME clock does
51 include the time during which the system is suspended. This is
52 useful for applications that need to be suspend-aware.
53 CLOCK_REALTIME is not suitable for such applications, since that
54 clock is affected by discontinuous changes to the system clock.
55
56 CLOCK_REALTIME_ALARM (since Linux 3.0)
57 This clock is like CLOCK_REALTIME, but will wake the system if
58 it is suspended. The caller must have the CAP_WAKE_ALARM capa‐
59 bility in order to set a timer against this clock.
60
61 CLOCK_BOOTTIME_ALARM (since Linux 3.0)
62 This clock is like CLOCK_BOOTTIME, but will wake the system if
63 it is suspended. The caller must have the CAP_WAKE_ALARM capa‐
64 bility in order to set a timer against this clock.
65
66 CLOCK_TAI (since Linux 3.10)
67 A system-wide clock derived from wall-clock time but ignoring
68 leap seconds.
69
70 See clock_getres(2) for some further details on the above clocks.
71
72 As well as the above values, clockid can be specified as the clockid
73 returned by a call to clock_getcpuclockid(3) or pthread_getcpu‐
74 clockid(3).
75
76 The sevp argument points to a sigevent structure that specifies how the
77 caller should be notified when the timer expires. For the definition
78 and general details of this structure, see sigevent(7).
79
80 The sevp.sigev_notify field can have the following values:
81
82 SIGEV_NONE
83 Don't asynchronously notify when the timer expires. Progress of
84 the timer can be monitored using timer_gettime(2).
85
86 SIGEV_SIGNAL
87 Upon timer expiration, generate the signal sigev_signo for the
88 process. See sigevent(7) for general details. The si_code
89 field of the siginfo_t structure will be set to SI_TIMER. At
90 any point in time, at most one signal is queued to the process
91 for a given timer; see timer_getoverrun(2) for more details.
92
93 SIGEV_THREAD
94 Upon timer expiration, invoke sigev_notify_function as if it
95 were the start function of a new thread. See sigevent(7) for
96 details.
97
98 SIGEV_THREAD_ID (Linux-specific)
99 As for SIGEV_SIGNAL, but the signal is targeted at the thread
100 whose ID is given in sigev_notify_thread_id, which must be a
101 thread in the same process as the caller. The sigev_no‐
102 tify_thread_id field specifies a kernel thread ID, that is, the
103 value returned by clone(2) or gettid(2). This flag is intended
104 only for use by threading libraries.
105
106 Specifying sevp as NULL is equivalent to specifying a pointer to a
107 sigevent structure in which sigev_notify is SIGEV_SIGNAL, sigev_signo
108 is SIGALRM, and sigev_value.sival_int is the timer ID.
109
111 On success, timer_create() returns 0, and the ID of the new timer is
112 placed in *timerid. On failure, -1 is returned, and errno is set to
113 indicate the error.
114
116 EAGAIN Temporary error during kernel allocation of timer structures.
117
118 EINVAL Clock ID, sigev_notify, sigev_signo, or sigev_notify_thread_id
119 is invalid.
120
121 ENOMEM Could not allocate memory.
122
123 ENOTSUP
124 The kernel does not support creating a timer against this
125 clockid.
126
127 EPERM clockid was CLOCK_REALTIME_ALARM or CLOCK_BOOTTIME_ALARM but the
128 caller did not have the CAP_WAKE_ALARM capability.
129
131 This system call is available since Linux 2.6.
132
134 POSIX.1-2001, POSIX.1-2008.
135
137 A program may create multiple interval timers using timer_create().
138
139 Timers are not inherited by the child of a fork(2), and are disarmed
140 and deleted during an execve(2).
141
142 The kernel preallocates a "queued real-time signal" for each timer cre‐
143 ated using timer_create(). Consequently, the number of timers is lim‐
144 ited by the RLIMIT_SIGPENDING resource limit (see setrlimit(2)).
145
146 The timers created by timer_create() are commonly known as "POSIX (in‐
147 terval) timers". The POSIX timers API consists of the following inter‐
148 faces:
149
150 * timer_create(): Create a timer.
151
152 * timer_settime(2): Arm (start) or disarm (stop) a timer.
153
154 * timer_gettime(2): Fetch the time remaining until the next expiration
155 of a timer, along with the interval setting of the timer.
156
157 * timer_getoverrun(2): Return the overrun count for the last timer ex‐
158 piration.
159
160 * timer_delete(2): Disarm and delete a timer.
161
162 Since Linux 3.10, the /proc/[pid]/timers file can be used to list the
163 POSIX timers for the process with PID pid. See proc(5) for further in‐
164 formation.
165
166 Since Linux 4.10, support for POSIX timers is a configurable option
167 that is enabled by default. Kernel support can be disabled via the
168 CONFIG_POSIX_TIMERS option.
169
170 C library/kernel differences
171 Part of the implementation of the POSIX timers API is provided by
172 glibc. In particular:
173
174 * Much of the functionality for SIGEV_THREAD is implemented within
175 glibc, rather than the kernel. (This is necessarily so, since the
176 thread involved in handling the notification is one that must be
177 managed by the C library POSIX threads implementation.) Although
178 the notification delivered to the process is via a thread, inter‐
179 nally the NPTL implementation uses a sigev_notify value of
180 SIGEV_THREAD_ID along with a real-time signal that is reserved by
181 the implementation (see nptl(7)).
182
183 * The implementation of the default case where evp is NULL is handled
184 inside glibc, which invokes the underlying system call with a suit‐
185 ably populated sigevent structure.
186
187 * The timer IDs presented at user level are maintained by glibc, which
188 maps these IDs to the timer IDs employed by the kernel.
189
190 The POSIX timers system calls first appeared in Linux 2.6. Prior to
191 this, glibc provided an incomplete user-space implementation (CLOCK_RE‐
192 ALTIME timers only) using POSIX threads, and in glibc versions before
193 2.17, the implementation falls back to this technique on systems run‐
194 ning pre-2.6 Linux kernels.
195
197 The program below takes two arguments: a sleep period in seconds, and a
198 timer frequency in nanoseconds. The program establishes a handler for
199 the signal it uses for the timer, blocks that signal, creates and arms
200 a timer that expires with the given frequency, sleeps for the specified
201 number of seconds, and then unblocks the timer signal. Assuming that
202 the timer expired at least once while the program slept, the signal
203 handler will be invoked, and the handler displays some information
204 about the timer notification. The program terminates after one invoca‐
205 tion of the signal handler.
206
207 In the following example run, the program sleeps for 1 second, after
208 creating a timer that has a frequency of 100 nanoseconds. By the time
209 the signal is unblocked and delivered, there have been around ten mil‐
210 lion overruns.
211
212 $ ./a.out 1 100
213 Establishing handler for signal 34
214 Blocking signal 34
215 timer ID is 0x804c008
216 Sleeping for 1 seconds
217 Unblocking signal 34
218 Caught signal 34
219 sival_ptr = 0xbfb174f4; *sival_ptr = 0x804c008
220 overrun count = 10004886
221
222 Program source
223
224 #include <stdint.h>
225 #include <stdlib.h>
226 #include <unistd.h>
227 #include <stdio.h>
228 #include <signal.h>
229 #include <time.h>
230
231 #define CLOCKID CLOCK_REALTIME
232 #define SIG SIGRTMIN
233
234 #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
235 } while (0)
236
237 static void
238 print_siginfo(siginfo_t *si)
239 {
240 timer_t *tidp;
241 int or;
242
243 tidp = si->si_value.sival_ptr;
244
245 printf(" sival_ptr = %p; ", si->si_value.sival_ptr);
246 printf(" *sival_ptr = %#jx\n", (uintmax_t) *tidp);
247
248 or = timer_getoverrun(*tidp);
249 if (or == -1)
250 errExit("timer_getoverrun");
251 else
252 printf(" overrun count = %d\n", or);
253 }
254
255 static void
256 handler(int sig, siginfo_t *si, void *uc)
257 {
258 /* Note: calling printf() from a signal handler is not safe
259 (and should not be done in production programs), since
260 printf() is not async-signal-safe; see signal-safety(7).
261 Nevertheless, we use printf() here as a simple way of
262 showing that the handler was called. */
263
264 printf("Caught signal %d\n", sig);
265 print_siginfo(si);
266 signal(sig, SIG_IGN);
267 }
268
269 int
270 main(int argc, char *argv[])
271 {
272 timer_t timerid;
273 struct sigevent sev;
274 struct itimerspec its;
275 long long freq_nanosecs;
276 sigset_t mask;
277 struct sigaction sa;
278
279 if (argc != 3) {
280 fprintf(stderr, "Usage: %s <sleep-secs> <freq-nanosecs>\n",
281 argv[0]);
282 exit(EXIT_FAILURE);
283 }
284
285 /* Establish handler for timer signal. */
286
287 printf("Establishing handler for signal %d\n", SIG);
288 sa.sa_flags = SA_SIGINFO;
289 sa.sa_sigaction = handler;
290 sigemptyset(&sa.sa_mask);
291 if (sigaction(SIG, &sa, NULL) == -1)
292 errExit("sigaction");
293
294 /* Block timer signal temporarily. */
295
296 printf("Blocking signal %d\n", SIG);
297 sigemptyset(&mask);
298 sigaddset(&mask, SIG);
299 if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1)
300 errExit("sigprocmask");
301
302 /* Create the timer. */
303
304 sev.sigev_notify = SIGEV_SIGNAL;
305 sev.sigev_signo = SIG;
306 sev.sigev_value.sival_ptr = &timerid;
307 if (timer_create(CLOCKID, &sev, &timerid) == -1)
308 errExit("timer_create");
309
310 printf("timer ID is %#jx\n", (uintmax_t) timerid);
311
312 /* Start the timer. */
313
314 freq_nanosecs = atoll(argv[2]);
315 its.it_value.tv_sec = freq_nanosecs / 1000000000;
316 its.it_value.tv_nsec = freq_nanosecs % 1000000000;
317 its.it_interval.tv_sec = its.it_value.tv_sec;
318 its.it_interval.tv_nsec = its.it_value.tv_nsec;
319
320 if (timer_settime(timerid, 0, &its, NULL) == -1)
321 errExit("timer_settime");
322
323 /* Sleep for a while; meanwhile, the timer may expire
324 multiple times. */
325
326 printf("Sleeping for %d seconds\n", atoi(argv[1]));
327 sleep(atoi(argv[1]));
328
329 /* Unlock the timer signal, so that timer notification
330 can be delivered. */
331
332 printf("Unblocking signal %d\n", SIG);
333 if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
334 errExit("sigprocmask");
335
336 exit(EXIT_SUCCESS);
337 }
338
340 clock_gettime(2), setitimer(2), timer_delete(2), timer_getoverrun(2),
341 timer_settime(2), timerfd_create(2), clock_getcpuclockid(3),
342 pthread_getcpuclockid(3), pthreads(7), sigevent(7), signal(7), time(7)
343
345 This page is part of release 5.12 of the Linux man-pages project. A
346 description of the project, information about reporting bugs, and the
347 latest version of this page, can be found at
348 https://www.kernel.org/doc/man-pages/.
349
350
351
352Linux 2021-03-22 TIMER_CREATE(2)