Some improvements in vc
[emacs.git] / src / atimer.c
blob70d9bf52bc27588194be88faccf3998fbd216f6d
1 /* Asynchronous timers.
2 Copyright (C) 2000-2016 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
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 (at
9 your option) any later version.
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.
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/>. */
19 #include <config.h>
20 #include <stdio.h>
22 #include "lisp.h"
23 #include "syssignal.h"
24 #include "systime.h"
25 #include "atimer.h"
26 #include <unistd.h>
28 #ifdef HAVE_TIMERFD
29 #include <errno.h>
30 # include <sys/timerfd.h>
31 #endif
33 /* Free-list of atimer structures. */
35 static struct atimer *free_atimers;
37 /* List of currently not running timers due to a call to
38 lock_atimer. */
40 static struct atimer *stopped_atimers;
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. */
45 static struct atimer *atimers;
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;
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
61 /* Block/unblock SIGALRM. */
63 static void
64 block_atimers (sigset_t *oldset)
66 sigset_t blocked;
67 sigemptyset (&blocked);
68 sigaddset (&blocked, SIGALRM);
69 sigaddset (&blocked, SIGINT);
70 pthread_sigmask (SIG_BLOCK, &blocked, oldset);
72 static void
73 unblock_atimers (sigset_t const *oldset)
75 pthread_sigmask (SIG_SETMASK, oldset, 0);
78 /* Function prototypes. */
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 *);
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.
90 If TYPE is ATIMER_ABSOLUTE, TIMESTAMP is the absolute time at which the
91 timer fires.
93 If TYPE is ATIMER_RELATIVE, the timer is ripe TIMESTAMP seconds in the
94 future.
96 In both cases, the timer is automatically freed after it has fired.
98 If TYPE is ATIMER_CONTINUOUS, the timer fires every TIMESTAMP seconds.
100 Value is a pointer to the atimer started. It can be used in calls
101 to cancel_atimer; don't free it yourself. */
103 struct atimer *
104 start_atimer (enum atimer_type type, struct timespec timestamp,
105 atimer_callback fn, void *client_data)
107 struct atimer *t;
108 sigset_t oldset;
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 */
116 /* Get an atimer structure from the free-list, or allocate
117 a new one. */
118 if (free_atimers)
120 t = free_atimers;
121 free_atimers = t->next;
123 else
124 t = xmalloc (sizeof *t);
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;
132 block_atimers (&oldset);
134 /* Compute the timer's expiration time. */
135 switch (type)
137 case ATIMER_ABSOLUTE:
138 t->expiration = timestamp;
139 break;
141 case ATIMER_RELATIVE:
142 t->expiration = timespec_add (current_timespec (), timestamp);
143 break;
145 case ATIMER_CONTINUOUS:
146 t->expiration = timespec_add (current_timespec (), timestamp);
147 t->interval = timestamp;
148 break;
151 /* Insert the timer in the list of active atimers. */
152 schedule_atimer (t);
153 unblock_atimers (&oldset);
155 /* Arrange for a SIGALRM at the time the next atimer is ripe. */
156 set_alarm ();
158 return t;
162 /* Cancel and free atimer TIMER. */
164 void
165 cancel_atimer (struct atimer *timer)
167 int i;
168 sigset_t oldset;
170 block_atimers (&oldset);
172 for (i = 0; i < 2; ++i)
174 struct atimer *t, *prev;
175 struct atimer **list = i ? &stopped_atimers : &atimers;
177 /* See if TIMER is active or stopped. */
178 for (t = *list, prev = NULL; t && t != timer; prev = t, t = t->next)
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)
186 if (prev)
187 prev->next = t->next;
188 else
189 *list = t->next;
191 t->next = free_atimers;
192 free_atimers = t;
193 break;
197 unblock_atimers (&oldset);
201 /* Append two lists of atimers LIST_1 and LIST_2 and return the
202 result list. */
204 static struct atimer *
205 append_atimer_lists (struct atimer *list_1, struct atimer *list_2)
207 if (list_1 == NULL)
208 return list_2;
209 else if (list_2 == NULL)
210 return list_1;
211 else
213 struct atimer *p;
215 for (p = list_1; p->next; p = p->next)
217 p->next = list_2;
218 return list_1;
223 /* Stop all timers except timer T. T null means stop all timers. */
225 void
226 stop_other_atimers (struct atimer *t)
228 sigset_t oldset;
229 block_atimers (&oldset);
231 if (t)
233 struct atimer *p, *prev;
235 /* See if T is active. */
236 for (p = atimers, prev = NULL; p && p != t; prev = p, p = p->next)
239 if (p == t)
241 if (prev)
242 prev->next = t->next;
243 else
244 atimers = t->next;
245 t->next = NULL;
247 else
248 /* T is not active. Let's handle this like T == 0. */
249 t = NULL;
252 stopped_atimers = append_atimer_lists (atimers, stopped_atimers);
253 atimers = t;
254 unblock_atimers (&oldset);
258 /* Run all timers again, if some have been stopped with a call to
259 stop_other_atimers. */
261 void
262 run_all_atimers (void)
264 if (stopped_atimers)
266 struct atimer *t = atimers;
267 struct atimer *next;
268 sigset_t oldset;
270 block_atimers (&oldset);
271 atimers = stopped_atimers;
272 stopped_atimers = NULL;
274 while (t)
276 next = t->next;
277 schedule_atimer (t);
278 t = next;
281 unblock_atimers (&oldset);
286 /* Arrange for a SIGALRM to arrive when the next timer is ripe. */
288 static void
289 set_alarm (void)
291 if (atimers)
293 #ifdef HAVE_SETITIMER
294 struct itimerval it;
295 #endif
296 struct timespec now, interval;
298 #ifdef HAVE_ITIMERSPEC
299 if (0 <= timerfd || alarm_timer_ok)
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)
307 add_timer_wait_descriptor (timerfd);
308 return;
310 # endif
311 if (alarm_timer_ok
312 && timer_settime (alarm_timer, TIMER_ABSTIME, &ispec, 0) == 0)
313 return;
315 #endif
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));
324 #ifdef HAVE_SETITIMER
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 */
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. */
340 static void
341 schedule_atimer (struct atimer *t)
343 struct atimer *a = atimers, *prev = NULL;
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;
349 /* Insert T in front of the atimer found, if any. */
350 if (prev)
351 prev->next = t;
352 else
353 atimers = t;
355 t->next = a;
358 static void
359 run_timers (void)
361 struct timespec now = current_timespec ();
363 while (atimers && timespec_cmp (atimers->expiration, now) <= 0)
365 struct atimer *t = atimers;
366 atimers = atimers->next;
367 t->fn (t);
369 if (t->type == ATIMER_CONTINUOUS)
371 t->expiration = timespec_add (now, t->interval);
372 schedule_atimer (t);
374 else
376 t->next = free_atimers;
377 free_atimers = t;
381 set_alarm ();
385 /* Signal handler for SIGALRM. SIGNO is the signal number, i.e.
386 SIGALRM. */
388 static void
389 handle_alarm_signal (int sig)
391 pending_signals = 1;
394 #ifdef HAVE_TIMERFD
396 /* Called from wait_reading_process_output when FD, which
397 should be equal to TIMERFD, is available for reading. */
399 void
400 timerfd_callback (int fd, void *arg)
402 ptrdiff_t nbytes;
403 uint64_t expirations;
405 eassert (fd == timerfd);
406 nbytes = emacs_read (fd, &expirations, sizeof (expirations));
408 if (nbytes == sizeof (expirations))
410 /* Timer should expire just once. */
411 eassert (expirations == 1);
412 do_pending_atimers ();
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 ();
424 #endif /* HAVE_TIMERFD */
426 /* Do pending timers. */
428 void
429 do_pending_atimers (void)
431 if (atimers)
433 sigset_t oldset;
434 block_atimers (&oldset);
435 run_timers ();
436 unblock_atimers (&oldset);
441 /* Turn alarms on/off. This seems to be temporarily necessary on
442 some systems like HPUX (see process.c). */
444 void
445 turn_on_atimers (bool on)
447 if (on)
448 set_alarm ();
449 else
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);
464 /* This is intended to use from automated tests. */
466 #ifdef ENABLE_CHECKING
468 #define MAXTIMERS 10
470 struct atimer_result
472 /* Time when we expect this timer to trigger. */
473 struct timespec expected;
475 /* Timer status: -1 if not triggered, 0 if triggered
476 too early or too late, 1 if triggered timely. */
477 int intime;
480 static void
481 debug_timer_callback (struct atimer *t)
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);
487 if (result < 0)
488 /* Too early. */
489 r->intime = 0;
490 else if (result >= 0)
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;
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)
509 int i, ok;
510 struct atimer *timer;
511 struct atimer_result *results[MAXTIMERS];
512 struct timespec t = make_timespec (0, 0);
514 /* Arm MAXTIMERS relative timers to trigger with 0.1s intervals. */
515 for (i = 0; i < MAXTIMERS; i++)
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]);
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));
537 while (timespec_cmp (current_timespec (), tend) < 0)
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 ();
544 #endif
545 /* Shut up the compiler by "using" this variable. */
546 (void) timer;
548 for (i = 0, ok = 0; i < MAXTIMERS; i++)
549 ok += results[i]->intime, xfree (results[i]);
551 return ok == MAXTIMERS ? Qt : Qnil;
554 #endif /* ENABLE_CHECKING */
556 void
557 init_atimer (void)
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)
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;
574 #endif
575 free_atimers = stopped_atimers = atimers = NULL;
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);
582 #ifdef ENABLE_CHECKING
583 defsubr (&Sdebug_timer_check);
584 #endif