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>
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
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
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
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
117 This system call is available since Linux 2.6.
118
120 POSIX.1-2001, POSIX.1-2008.
121
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
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
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
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)