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 *evp,
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 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 evp argument points to a sigevent structure that specifies how the
51 caller should be notified when the timer expires. This structure is
52 defined something like the following:
53
54 union sigval {
55 int sival_int;
56 void *sival_ptr;
57 };
58
59 struct sigevent {
60 int sigev_notify; /* Notification method */
61 int sigev_signo; /* Timer expiration signal */
62 union sigval sigev_value; /* Value accompanying signal or
63 passed to thread function */
64 void (*sigev_notify_function) (union sigval);
65 /* Function used for thread
66 notifications (SIGEV_THREAD) */
67 void *sigev_notify_attributes;
68 /* Attributes for notification thread
69 (SIGEV_THREAD) */
70 pid_t sigev_notify_thread_id;
71 /* ID of thread to signal (SIGEV_THREAD_ID) */
72 };
73
74 Some of these fields may be defined as part of a union: a program
75 should only employ those fields relevant to the value specified in
76 sigev_notify. This field can have the following values:
77
78 SIGEV_NONE
79 Don't asynchronously notify when the timer expires. Progress of
80 the timer can be monitored using timer_gettime(2).
81
82 SIGEV_SIGNAL
83 Upon timer expiration, generate the signal sigev_signo for the
84 process. If sigev_signo is a real-time signal, then it will be
85 accompanied by the data specified in sigev_value (like the sig‐
86 nal-accompanying data for sigqueue(2)). At any point in time,
87 at most one signal is queued to the process for a given timer;
88 see timer_getoverrun(2) for more details.
89
90 SIGEV_THREAD
91 Upon timer expiration, invoke sigev_notify_function as if it
92 were the start function of a new thread. (Among the implementa‐
93 tion possibilities here are that each timer notification could
94 result in the creation of a new thread, or that a single thread
95 is created to receive all notifications.) The function is
96 invoked with sigev_value as its sole argument. If
97 sigev_notify_attributes is not NULL, it should point to a
98 pthread_attr_t structure that defines attributes for the new
99 thread (see pthread_attr_init(3)).
100
101 SIGEV_THREAD_ID (Linux-specific)
102 As for SIGEV_SIGNAL, but the signal is targeted at the thread
103 whose ID is given in sigev_notify_thread_id, which must be a
104 thread in the same process as the caller. The
105 sigev_notify_thread_id field specifies a kernel thread ID, that
106 is, the value returned by clone(2) or gettid(2). This flag is
107 only intended for use by threading libraries.
108
109 Specifying evp as NULL is equivalent to specifying a pointer to a
110 sigevent structure in which sigev_notify is SIGEV_SIGNAL, sigev_signo
111 is SIGALRM, and sigev_value.sival_int is the timer ID.
112
114 On success, timer_create() returns 0, and the ID of the new timer is
115 placed in *timerid. On failure, -1 is returned, and errno is set to
116 indicate the error.
117
119 EAGAIN Temporary error during kernel allocation of timer structures.
120
121 EINVAL Clock ID, sigev_notify, sigev_signo, or sigev_notify_thread_id
122 is invalid.
123
124 ENOMEM Could not allocate memory.
125
127 This system call is available since Linux 2.6.
128
130 POSIX.1-2001
131
133 A program may create multiple interval timers using timer_create().
134
135 Timers are not inherited by the child of a fork(2), and are disarmed
136 and deleted during an execve(2).
137
138 The kernel preallocates a "queued real-time signal" for each timer cre‐
139 ated using timer_create(). Consequently, the number of timers is lim‐
140 ited by the RLIMIT_SIGPENDING resource limit (see setrlimit(2)).
141
142 The timers created by timer_create() are commonly known as "POSIX
143 (interval) timers". The POSIX timers API consists of the following
144 interfaces:
145
146 * timer_create(): Create a timer.
147
148 * timer_settime(2): Arm (start) or disarm (stop) a timer.
149
150 * timer_gettime(2): Fetch the time remaining until the next expiration
151 of a timer, along with the interval setting of the timer.
152
153 * timer_getoverrun(2): Return the overrun count for the last timer
154 expiration.
155
156 * timer_delete(2): Disarm and delete a timer.
157
158 Part of the implementation of the POSIX timers API is provided by
159 glibc. In particular:
160
161 * The functionality for SIGEV_THREAD is implemented within glibc,
162 rather than the kernel.
163
164 * The timer IDs presented at user level are maintained by glibc, which
165 maps these IDs to the timer IDs employed by the kernel.
166
167 The POSIX timers system calls first appeared in Linux 2.6. Prior to
168 this, glibc provided an incomplete userspace implementation
169 (CLOCK_REALTIME timers only) using POSIX threads, and current glibc
170 falls back to this implementation on systems running pre-2.6 Linux ker‐
171 nels.
172
174 The program below takes two arguments: a sleep period in seconds, and a
175 timer frequency in nanoseconds. The program establishes a handler for
176 the signal it uses for the timer, blocks that signal, creates and arms
177 a timer that expires with the given frequency, sleeps for the specified
178 number of seconds, and then unblocks the timer signal. Assuming that
179 the timer expired at least once while the program slept, the signal
180 handler will be invoked, and the handler displays some information
181 about the timer notification. The program terminates after one invoca‐
182 tion of the signal handler.
183
184 In the following example run, the program sleeps for 1 second, after
185 creating a timer that has a frequency of 100 nanoseconds. By the time
186 the signal is unblocked and delivered, there have been around ten mil‐
187 lion overruns.
188
189 $ ./a.out 1 10
190 Establishing handler for signal 34
191 Blocking signal 34
192 timer ID is 0x804c008
193 Sleeping for 1 seconds
194 Unblocking signal 34
195 Caught signal 34
196 sival_ptr = 0xbfb174f4; *sival_ptr = 0x804c008
197 overrun count = 10004886
198
199 Program Source
200
201 #include <stdlib.h>
202 #include <unistd.h>
203 #include <stdio.h>
204 #include <signal.h>
205 #include <time.h>
206
207 #define CLOCKID CLOCK_REALTIME
208 #define SIG SIGRTMIN
209
210 #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
211 } while (0)
212
213 static void
214 print_siginfo(siginfo_t *si)
215 {
216 timer_t *tidp;
217 int or;
218
219 tidp = si->si_value.sival_ptr;
220
221 printf(" sival_ptr = %p; ", si->si_value.sival_ptr);
222 printf(" *sival_ptr = 0x%lx\n", (long) *tidp);
223
224 or = timer_getoverrun(*tidp);
225 if (or == -1)
226 errExit("timer_getoverrun");
227 else
228 printf(" overrun count = %d\n", or);
229 }
230
231 static void
232 handler(int sig, siginfo_t *si, void *uc)
233 {
234 /* Note: calling printf() from a signal handler is not
235 strictly correct, since printf() is not async-signal-safe;
236 see signal(7) */
237
238 printf("Caught signal %d\n", sig);
239 print_siginfo(si);
240 signal(sig, SIG_IGN);
241 }
242
243 int
244 main(int argc, char *argv[])
245 {
246 timer_t timerid;
247 struct sigevent sev;
248 struct itimerspec its;
249 long long freq_nanosecs;
250 sigset_t mask;
251 struct sigaction sa;
252
253 if (argc != 3) {
254 fprintf(stderr, "Usage: %s <sleep-secs> <freq-nanosecs>\n",
255 argv[0]);
256 exit(EXIT_FAILURE);
257 }
258
259 /* Establish handler for timer signal */
260
261 printf("Establishing handler for signal %d\n", SIG);
262 sa.sa_flags = SA_SIGINFO;
263 sa.sa_sigaction = handler;
264 sigemptyset(&sa.sa_mask);
265 if (sigaction(SIG, &sa, NULL) == -1)
266 errExit("sigaction");
267
268 /* Block timer signal temporarily */
269
270 printf("Blocking signal %d\n", SIG);
271 sigemptyset(&mask);
272 sigaddset(&mask, SIG);
273 if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1)
274 errExit("sigprocmask");
275
276 /* Create the timer */
277
278 sev.sigev_notify = SIGEV_SIGNAL;
279 sev.sigev_signo = SIG;
280 sev.sigev_value.sival_ptr = &timerid;
281 if (timer_create(CLOCKID, &sev, &timerid) == -1)
282 errExit("timer_create");
283
284 printf("timer ID is 0x%lx\n", (long) timerid);
285
286 /* Start the timer */
287
288 freq_nanosecs = atoll(argv[2]);
289 its.it_value.tv_sec = freq_nanosecs / 1000000000;
290 its.it_value.tv_nsec = freq_nanosecs % 1000000000;
291 its.it_interval.tv_sec = its.it_value.tv_sec;
292 its.it_interval.tv_nsec = its.it_value.tv_nsec;
293
294 if (timer_settime(timerid, 0, &its, NULL) == -1)
295 errExit("timer_settime");
296
297 /* Sleep for a while; meanwhile, the timer may expire
298 multiple times */
299
300 printf("Sleeping for %d seconds\n", atoi(argv[1]));
301 sleep(atoi(argv[1]));
302
303 /* Unlock the timer signal, so that timer notification
304 can be delivered */
305
306 printf("Unblocking signal %d\n", SIG);
307 if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
308 errExit("sigprocmask");
309
310 exit(EXIT_SUCCESS);
311 }
312
314 clock_gettime(2), setitimer(2), timer_delete(2), timer_settime(2),
315 timer_getoverrun(2), timerfd_create(2), clock_getcpuclockid(3),
316 pthread_getcpuclockid(3), pthreads(7), signal(7), time(7)
317
319 This page is part of release 3.25 of the Linux man-pages project. A
320 description of the project, and information about reporting bugs, can
321 be found at http://www.kernel.org/doc/man-pages/.
322
323
324
325Linux 2009-02-20 TIMER_CREATE(2)