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 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
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
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
98 This system call is available since Linux 2.6.
99
101 POSIX.1-2001.
102
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
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
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
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)