]> code.delx.au - gnu-emacs/blob - src/atimer.c
976b990f5ff070300ca5cbcce89d56c437e65fe8
[gnu-emacs] / src / atimer.c
1 /* Asynchronous timers.
2 Copyright (C) 2000-2015 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18
19 #include <config.h>
20 #include <stdio.h>
21
22 #include "lisp.h"
23 #include "syssignal.h"
24 #include "systime.h"
25 #include "atimer.h"
26 #include <unistd.h>
27
28 #ifdef HAVE_TIMERFD
29 #include <errno.h>
30 # include <sys/timerfd.h>
31 #endif
32
33 /* Free-list of atimer structures. */
34
35 static struct atimer *free_atimers;
36
37 /* List of currently not running timers due to a call to
38 lock_atimer. */
39
40 static struct atimer *stopped_atimers;
41
42 /* List of active atimers, sorted by expiration time. The timer that
43 will become ripe next is always at the front of this list. */
44
45 static struct atimer *atimers;
46
47 #ifdef HAVE_ITIMERSPEC
48 /* The alarm timer and whether it was properly initialized, if
49 POSIX timers are available. */
50 static timer_t alarm_timer;
51 static bool alarm_timer_ok;
52
53 # ifdef HAVE_TIMERFD
54 /* File descriptor for timer, or -1 if it could not be created. */
55 static int timerfd;
56 # else
57 enum { timerfd = -1 };
58 # endif
59 #endif
60
61 /* Block/unblock SIGALRM. */
62
63 static void
64 block_atimers (sigset_t *oldset)
65 {
66 sigset_t blocked;
67 sigemptyset (&blocked);
68 sigaddset (&blocked, SIGALRM);
69 sigaddset (&blocked, SIGINT);
70 pthread_sigmask (SIG_BLOCK, &blocked, oldset);
71 }
72 static void
73 unblock_atimers (sigset_t const *oldset)
74 {
75 pthread_sigmask (SIG_SETMASK, oldset, 0);
76 }
77
78 /* Function prototypes. */
79
80 static void set_alarm (void);
81 static void schedule_atimer (struct atimer *);
82 static struct atimer *append_atimer_lists (struct atimer *,
83 struct atimer *);
84
85 /* Start a new atimer of type TYPE. TIMESTAMP specifies when the timer is
86 ripe. FN is the function to call when the timer fires.
87 CLIENT_DATA is stored in the client_data member of the atimer
88 structure returned and so made available to FN when it is called.
89
90 If TYPE is ATIMER_ABSOLUTE, TIMESTAMP is the absolute time at which the
91 timer fires.
92
93 If TYPE is ATIMER_RELATIVE, the timer is ripe TIMESTAMP seconds in the
94 future.
95
96 In both cases, the timer is automatically freed after it has fired.
97
98 If TYPE is ATIMER_CONTINUOUS, the timer fires every TIMESTAMP seconds.
99
100 Value is a pointer to the atimer started. It can be used in calls
101 to cancel_atimer; don't free it yourself. */
102
103 struct atimer *
104 start_atimer (enum atimer_type type, struct timespec timestamp,
105 atimer_callback fn, void *client_data)
106 {
107 struct atimer *t;
108 sigset_t oldset;
109
110 /* Round TIMESTAMP up to the next full second if we don't have itimers. */
111 #ifndef HAVE_SETITIMER
112 if (timestamp.tv_nsec != 0 && timestamp.tv_sec < TYPE_MAXIMUM (time_t))
113 timestamp = make_timespec (timestamp.tv_sec + 1, 0);
114 #endif /* not HAVE_SETITIMER */
115
116 /* Get an atimer structure from the free-list, or allocate
117 a new one. */
118 if (free_atimers)
119 {
120 t = free_atimers;
121 free_atimers = t->next;
122 }
123 else
124 t = xmalloc (sizeof *t);
125
126 /* Fill the atimer structure. */
127 memset (t, 0, sizeof *t);
128 t->type = type;
129 t->fn = fn;
130 t->client_data = client_data;
131
132 block_atimers (&oldset);
133
134 /* Compute the timer's expiration time. */
135 switch (type)
136 {
137 case ATIMER_ABSOLUTE:
138 t->expiration = timestamp;
139 break;
140
141 case ATIMER_RELATIVE:
142 t->expiration = timespec_add (current_timespec (), timestamp);
143 break;
144
145 case ATIMER_CONTINUOUS:
146 t->expiration = timespec_add (current_timespec (), timestamp);
147 t->interval = timestamp;
148 break;
149 }
150
151 /* Insert the timer in the list of active atimers. */
152 schedule_atimer (t);
153 unblock_atimers (&oldset);
154
155 /* Arrange for a SIGALRM at the time the next atimer is ripe. */
156 set_alarm ();
157
158 return t;
159 }
160
161
162 /* Cancel and free atimer TIMER. */
163
164 void
165 cancel_atimer (struct atimer *timer)
166 {
167 int i;
168 sigset_t oldset;
169
170 block_atimers (&oldset);
171
172 for (i = 0; i < 2; ++i)
173 {
174 struct atimer *t, *prev;
175 struct atimer **list = i ? &stopped_atimers : &atimers;
176
177 /* See if TIMER is active or stopped. */
178 for (t = *list, prev = NULL; t && t != timer; prev = t, t = t->next)
179 ;
180
181 /* If it is, take it off its list, and put in on the free-list.
182 We don't bother to arrange for setting a different alarm time,
183 since a too early one doesn't hurt. */
184 if (t)
185 {
186 if (prev)
187 prev->next = t->next;
188 else
189 *list = t->next;
190
191 t->next = free_atimers;
192 free_atimers = t;
193 break;
194 }
195 }
196
197 unblock_atimers (&oldset);
198 }
199
200
201 /* Append two lists of atimers LIST_1 and LIST_2 and return the
202 result list. */
203
204 static struct atimer *
205 append_atimer_lists (struct atimer *list_1, struct atimer *list_2)
206 {
207 if (list_1 == NULL)
208 return list_2;
209 else if (list_2 == NULL)
210 return list_1;
211 else
212 {
213 struct atimer *p;
214
215 for (p = list_1; p->next; p = p->next)
216 ;
217 p->next = list_2;
218 return list_1;
219 }
220 }
221
222
223 /* Stop all timers except timer T. T null means stop all timers. */
224
225 void
226 stop_other_atimers (struct atimer *t)
227 {
228 sigset_t oldset;
229 block_atimers (&oldset);
230
231 if (t)
232 {
233 struct atimer *p, *prev;
234
235 /* See if T is active. */
236 for (p = atimers, prev = NULL; p && p != t; prev = p, p = p->next)
237 ;
238
239 if (p == t)
240 {
241 if (prev)
242 prev->next = t->next;
243 else
244 atimers = t->next;
245 t->next = NULL;
246 }
247 else
248 /* T is not active. Let's handle this like T == 0. */
249 t = NULL;
250 }
251
252 stopped_atimers = append_atimer_lists (atimers, stopped_atimers);
253 atimers = t;
254 unblock_atimers (&oldset);
255 }
256
257
258 /* Run all timers again, if some have been stopped with a call to
259 stop_other_atimers. */
260
261 void
262 run_all_atimers (void)
263 {
264 if (stopped_atimers)
265 {
266 struct atimer *t = atimers;
267 struct atimer *next;
268 sigset_t oldset;
269
270 block_atimers (&oldset);
271 atimers = stopped_atimers;
272 stopped_atimers = NULL;
273
274 while (t)
275 {
276 next = t->next;
277 schedule_atimer (t);
278 t = next;
279 }
280
281 unblock_atimers (&oldset);
282 }
283 }
284
285
286 /* Arrange for a SIGALRM to arrive when the next timer is ripe. */
287
288 static void
289 set_alarm (void)
290 {
291 if (atimers)
292 {
293 #ifdef HAVE_SETITIMER
294 struct itimerval it;
295 #endif
296 struct timespec now, interval;
297
298 #ifdef HAVE_ITIMERSPEC
299 if (0 <= timerfd || alarm_timer_ok)
300 {
301 struct itimerspec ispec;
302 ispec.it_value = atimers->expiration;
303 ispec.it_interval.tv_sec = ispec.it_interval.tv_nsec = 0;
304 # ifdef HAVE_TIMERFD
305 if (timerfd_settime (timerfd, TFD_TIMER_ABSTIME, &ispec, 0) == 0)
306 {
307 add_timer_wait_descriptor (timerfd);
308 return;
309 }
310 # endif
311 if (alarm_timer_ok
312 && timer_settime (alarm_timer, TIMER_ABSTIME, &ispec, 0) == 0)
313 return;
314 }
315 #endif
316
317 /* Determine interval till the next timer is ripe.
318 Don't set the interval to 0; this disables the timer. */
319 now = current_timespec ();
320 interval = (timespec_cmp (atimers->expiration, now) <= 0
321 ? make_timespec (0, 1000 * 1000)
322 : timespec_sub (atimers->expiration, now));
323
324 #ifdef HAVE_SETITIMER
325
326 memset (&it, 0, sizeof it);
327 it.it_value = make_timeval (interval);
328 setitimer (ITIMER_REAL, &it, 0);
329 #else /* not HAVE_SETITIMER */
330 alarm (max (interval.tv_sec, 1));
331 #endif /* not HAVE_SETITIMER */
332 }
333 }
334
335
336 /* Insert timer T into the list of active atimers `atimers', keeping
337 the list sorted by expiration time. T must not be in this list
338 already. */
339
340 static void
341 schedule_atimer (struct atimer *t)
342 {
343 struct atimer *a = atimers, *prev = NULL;
344
345 /* Look for the first atimer that is ripe after T. */
346 while (a && timespec_cmp (a->expiration, t->expiration) < 0)
347 prev = a, a = a->next;
348
349 /* Insert T in front of the atimer found, if any. */
350 if (prev)
351 prev->next = t;
352 else
353 atimers = t;
354
355 t->next = a;
356 }
357
358 static void
359 run_timers (void)
360 {
361 struct timespec now = current_timespec ();
362
363 while (atimers && timespec_cmp (atimers->expiration, now) <= 0)
364 {
365 struct atimer *t = atimers;
366 atimers = atimers->next;
367 t->fn (t);
368
369 if (t->type == ATIMER_CONTINUOUS)
370 {
371 t->expiration = timespec_add (now, t->interval);
372 schedule_atimer (t);
373 }
374 else
375 {
376 t->next = free_atimers;
377 free_atimers = t;
378 }
379 }
380
381 set_alarm ();
382 }
383
384
385 /* Signal handler for SIGALRM. SIGNO is the signal number, i.e.
386 SIGALRM. */
387
388 static void
389 handle_alarm_signal (int sig)
390 {
391 pending_signals = 1;
392 }
393
394 #ifdef HAVE_TIMERFD
395
396 /* Called from wait_reading_process_output when FD, which
397 should be equal to TIMERFD, is available for reading. */
398
399 void
400 timerfd_callback (int fd, void *arg)
401 {
402 ptrdiff_t nbytes;
403 uint64_t expirations;
404
405 eassert (fd == timerfd);
406 nbytes = emacs_read (fd, &expirations, sizeof (expirations));
407
408 if (nbytes == sizeof (expirations))
409 {
410 /* Timer should expire just once. */
411 eassert (expirations == 1);
412 do_pending_atimers ();
413 }
414 else if (nbytes < 0)
415 /* For some not yet known reason, we may get weird event and no
416 data on timer descriptor. This can break Gnus at least, see:
417 http://lists.gnu.org/archive/html/emacs-devel/2014-07/msg00503.html. */
418 eassert (errno == EAGAIN);
419 else
420 /* I don't know what else can happen with this descriptor. */
421 emacs_abort ();
422 }
423
424 #endif /* HAVE_TIMERFD */
425
426 /* Do pending timers. */
427
428 void
429 do_pending_atimers (void)
430 {
431 if (atimers)
432 {
433 sigset_t oldset;
434 block_atimers (&oldset);
435 run_timers ();
436 unblock_atimers (&oldset);
437 }
438 }
439
440
441 /* Turn alarms on/off. This seems to be temporarily necessary on
442 some systems like HPUX (see process.c). */
443
444 void
445 turn_on_atimers (bool on)
446 {
447 if (on)
448 set_alarm ();
449 else
450 {
451 #ifdef HAVE_ITIMERSPEC
452 struct itimerspec ispec;
453 memset (&ispec, 0, sizeof ispec);
454 if (alarm_timer_ok)
455 timer_settime (alarm_timer, TIMER_ABSTIME, &ispec, 0);
456 # ifdef HAVE_TIMERFD
457 timerfd_settime (timerfd, TFD_TIMER_ABSTIME, &ispec, 0);
458 # endif
459 #endif
460 alarm (0);
461 }
462 }
463
464 /* This is intended to use from automated tests. */
465
466 #ifdef ENABLE_CHECKING
467
468 #define MAXTIMERS 10
469
470 struct atimer_result
471 {
472 /* Time when we expect this timer to trigger. */
473 struct timespec expected;
474
475 /* Timer status: -1 if not triggered, 0 if triggered
476 too early or too late, 1 if triggered timely. */
477 int intime;
478 };
479
480 static void
481 debug_timer_callback (struct atimer *t)
482 {
483 struct timespec now = current_timespec ();
484 struct atimer_result *r = (struct atimer_result *) t->client_data;
485 int result = timespec_cmp (now, r->expected);
486
487 if (result < 0)
488 /* Too early. */
489 r->intime = 0;
490 else if (result >= 0)
491 {
492 #ifdef HAVE_SETITIMER
493 struct timespec delta = timespec_sub (now, r->expected);
494 /* Too late if later than expected + 0.02s. FIXME:
495 this should depend from system clock resolution. */
496 if (timespec_cmp (delta, make_timespec (0, 20000000)) > 0)
497 r->intime = 0;
498 else
499 #endif /* HAVE_SETITIMER */
500 r->intime = 1;
501 }
502 }
503
504 DEFUN ("debug-timer-check", Fdebug_timer_check, Sdebug_timer_check, 0, 0, 0,
505 doc: /* Run internal self-tests to check timers subsystem.
506 Return t if all self-tests are passed, nil otherwise. */)
507 (void)
508 {
509 int i, ok;
510 struct atimer *timer;
511 struct atimer_result *results[MAXTIMERS];
512 struct timespec t = make_timespec (0, 0);
513
514 /* Arm MAXTIMERS relative timers to trigger with 0.1s intervals. */
515 for (i = 0; i < MAXTIMERS; i++)
516 {
517 results[i] = xmalloc (sizeof (struct atimer_result));
518 t = timespec_add (t, make_timespec (0, 100000000));
519 results[i]->expected = timespec_add (current_timespec (), t);
520 results[i]->intime = -1;
521 timer = start_atimer (ATIMER_RELATIVE, t,
522 debug_timer_callback, results[i]);
523 }
524
525 #ifdef HAVE_TIMERFD
526 /* Wait for 1s but process timers. */
527 wait_reading_process_output (1, 0, 0, false, Qnil, NULL, 0);
528 #else
529 /* If timerfd is not supported, wait_reading_process_output won't
530 pay attention to timers that expired, and the callbacks won't be
531 called. So we need to run the expired timers' callbacks by
532 hand. */
533 /* Wait 1.2 sec for the timers to expire. */
534 struct timespec tend =
535 timespec_add (current_timespec (), make_timespec (1, 200000000));
536
537 while (timespec_cmp (current_timespec (), tend) < 0)
538 {
539 /* Wait for 5 msec between iterations. */
540 wait_reading_process_output (0, 5000000, 0, false, Qnil, NULL, 0);
541 if (pending_signals)
542 do_pending_atimers ();
543 }
544 #endif
545 /* Shut up the compiler by "using" this variable. */
546 (void) timer;
547
548 for (i = 0, ok = 0; i < MAXTIMERS; i++)
549 ok += results[i]->intime, xfree (results[i]);
550
551 return ok == MAXTIMERS ? Qt : Qnil;
552 }
553
554 #endif /* ENABLE_CHECKING */
555
556 void
557 init_atimer (void)
558 {
559 #ifdef HAVE_ITIMERSPEC
560 # ifdef HAVE_TIMERFD
561 /* Until this feature is considered stable, you can ask to not use it. */
562 timerfd = (egetenv ("EMACS_IGNORE_TIMERFD") ? -1 :
563 timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC));
564 # endif
565 if (timerfd < 0)
566 {
567 struct sigevent sigev;
568 sigev.sigev_notify = SIGEV_SIGNAL;
569 sigev.sigev_signo = SIGALRM;
570 sigev.sigev_value.sival_ptr = &alarm_timer;
571 alarm_timer_ok
572 = timer_create (CLOCK_REALTIME, &sigev, &alarm_timer) == 0;
573 }
574 #endif
575 free_atimers = stopped_atimers = atimers = NULL;
576
577 /* pending_signals is initialized in init_keyboard. */
578 struct sigaction action;
579 emacs_sigaction_init (&action, handle_alarm_signal);
580 sigaction (SIGALRM, &action, 0);
581
582 #ifdef ENABLE_CHECKING
583 defsubr (&Sdebug_timer_check);
584 #endif
585 }