struct atimer * start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn, void *client_data) { struct atimer *t; /* Round TIME up to the next full second if we don't have itimers. */ #ifndef HAVE_SETITIMER if (EMACS_NSECS (timestamp) != 0 && EMACS_SECS (timestamp) < TYPE_MAXIMUM (time_t)) timestamp = make_emacs_time (EMACS_SECS (timestamp) + 1, 0); #endif /* not HAVE_SETITIMER */ /* Get an atimer structure from the free-list, or allocate a new one. */ if (free_atimers) { t = free_atimers; free_atimers = t->next; } else t = xmalloc (sizeof *t); /* Fill the atimer structure. */ memset (t, 0, sizeof *t); t->type = type; t->fn = fn; t->client_data = client_data; block_atimers (); /* Compute the timer's expiration time. */ switch (type) { case ATIMER_ABSOLUTE: t->expiration = timestamp; break; case ATIMER_RELATIVE: t->expiration = add_emacs_time (current_emacs_time (), timestamp); break; case ATIMER_CONTINUOUS: t->expiration = add_emacs_time (current_emacs_time (), timestamp); t->interval = timestamp; break; } /* Insert the timer in the list of active atimers. */ schedule_atimer (t); unblock_atimers (); /* Arrange for a SIGALRM at the time the next atimer is ripe. */ set_alarm (); return t; }
static void set_alarm (void) { if (atimers) { EMACS_TIME now, timestamp; #ifdef HAVE_SETITIMER struct itimerval it; #endif /* Determine s/us till the next timer is ripe. */ EMACS_GET_TIME (now); EMACS_SUB_TIME (timestamp, atimers->expiration, now); #ifdef HAVE_SETITIMER /* Don't set the interval to 0; this disables the timer. */ if (EMACS_TIME_LE (atimers->expiration, now)) { EMACS_SET_SECS (timestamp, 0); EMACS_SET_USECS (timestamp, 1000); } memset (&it, 0, sizeof it); it.it_value = timestamp; setitimer (ITIMER_REAL, &it, 0); #else /* not HAVE_SETITIMER */ alarm (max (EMACS_SECS (timestamp), 1)); #endif /* not HAVE_SETITIMER */ } }
char * get_time () { if (watch_not_started) exit (EXIT_FAILURE); /* call reset_watch first ! */ EMACS_GET_TIME (TV2); EMACS_SUB_TIME (TV2, TV2, TV1); sprintf (time_string, "%lu.%06lu", (unsigned long)EMACS_SECS (TV2), (unsigned long)EMACS_USECS (TV2)); return time_string; }
static char * get_time (void) { EMACS_TIME TV2 = sub_emacs_time (current_emacs_time (), TV1); uintmax_t s = EMACS_SECS (TV2); int ns = EMACS_NSECS (TV2); if (watch_not_started) exit (EXIT_FAILURE); /* call reset_watch first ! */ sprintf (time_string, "%"PRIuMAX".%0*d", s, LOG10_EMACS_TIME_RESOLUTION, ns); return time_string; }
static void reset_interval_timer (void) { EMACS_TIME interval; /* Get the interval to set. If an interval is available, make sure it's not zero (this is a valid return, but it will cause the timer to get disabled, so convert it to a very short time). */ if (get_low_level_timeout_interval (async_timer_queue, &interval)) { if (EMACS_SECS (interval) == 0 && EMACS_USECS (interval) == 0) EMACS_SET_USECS (interval, 1); } else /* A time of 0 means "disable". */ EMACS_SET_SECS_USECS (interval, 0, 0); set_one_shot_timer (interval); }
static void set_alarm (void) { if (atimers) { #ifdef HAVE_SETITIMER struct itimerval it; #endif EMACS_TIME now, interval; #ifdef HAVE_ITIMERSPEC if (alarm_timer_ok) { struct itimerspec ispec; ispec.it_value = atimers->expiration; ispec.it_interval.tv_sec = ispec.it_interval.tv_nsec = 0; if (timer_settime (alarm_timer, 0, &ispec, 0) == 0) return; } #endif /* Determine interval till the next timer is ripe. Don't set the interval to 0; this disables the timer. */ now = current_emacs_time (); interval = (EMACS_TIME_LE (atimers->expiration, now) ? make_emacs_time (0, 1000 * 1000) : sub_emacs_time (atimers->expiration, now)); #ifdef HAVE_SETITIMER memset (&it, 0, sizeof it); it.it_value = make_timeval (interval); setitimer (ITIMER_REAL, &it, 0); #else /* not HAVE_SETITIMER */ alarm (max (EMACS_SECS (interval), 1)); #endif /* not HAVE_SETITIMER */ } }
struct atimer * start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn, void *client_data) { struct atimer *t; /* Round TIME up to the next full second if we don't have itimers. */ #ifndef HAVE_SETITIMER if (EMACS_USECS (timestamp) != 0) { EMACS_SET_USECS (timestamp, 0); EMACS_SET_SECS (timestamp, EMACS_SECS (timestamp) + 1); } #endif /* not HAVE_SETITIMER */ /* Get an atimer structure from the free-list, or allocate a new one. */ if (free_atimers) { t = free_atimers; free_atimers = t->next; } else t = (struct atimer *) xmalloc (sizeof *t); /* Fill the atimer structure. */ memset (t, 0, sizeof *t); t->type = type; t->fn = fn; t->client_data = client_data; BLOCK_ATIMERS; /* Compute the timer's expiration time. */ switch (type) { case ATIMER_ABSOLUTE: t->expiration = timestamp; break; case ATIMER_RELATIVE: EMACS_GET_TIME (t->expiration); EMACS_ADD_TIME (t->expiration, t->expiration, timestamp); break; case ATIMER_CONTINUOUS: EMACS_GET_TIME (t->expiration); EMACS_ADD_TIME (t->expiration, t->expiration, timestamp); t->interval = timestamp; break; } /* Insert the timer in the list of active atimers. */ schedule_atimer (t); UNBLOCK_ATIMERS; /* Arrange for a SIGALRM at the time the next atimer is ripe. */ set_alarm (); return t; }