static void run_timers (void) { EMACS_TIME now; EMACS_GET_TIME (now); while (atimers && (pending_atimers = interrupt_input_blocked) == 0 && EMACS_TIME_LE (atimers->expiration, now)) { struct atimer *t; t = atimers; atimers = atimers->next; #ifndef DARWIN_OS t->fn (t); #endif if (t->type == ATIMER_CONTINUOUS) { EMACS_ADD_TIME (t->expiration, now, t->interval); schedule_atimer (t); } else { t->next = free_atimers; free_atimers = t; } #ifdef DARWIN_OS /* Fix for Ctrl-G. Perhaps this should apply to all platforms. */ t->fn (t); #endif EMACS_GET_TIME (now); } if (! atimers) pending_atimers = 0; #ifdef SYNC_INPUT if (pending_atimers) pending_signals = 1; else { pending_signals = interrupt_input_pending; set_alarm (); } #else if (! pending_atimers) set_alarm (); #endif }
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 int emacs_tty_event_pending_p (int user_p) { if (!user_p) { EMACS_TIME sometime; /* see if there's a pending timeout. */ EMACS_GET_TIME (sometime); if (tty_timer_queue && EMACS_TIME_EQUAL_OR_GREATER (sometime, tty_timer_queue->time)) return 1; } return poll_fds_for_input (user_p ? tty_only_mask : non_fake_input_wait_mask); }
static char *get_time(void) { int sz; if (watch_not_started) exit(1); /* call reset_watch first ! */ EMACS_GET_TIME(TV2); if (TV1.tv_usec > TV2.tv_usec) { TV2.tv_usec += 1000000; TV2.tv_sec--; } sz = snprintf(time_string, sizeof(time_string), "%lu.%06lu", (unsigned long)TV2.tv_sec - TV1.tv_sec, (unsigned long)TV2.tv_usec - TV1.tv_usec); assert(sz >= 0 && (size_t)sz < sizeof(time_string)); return time_string; }
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; }
static void reset_watch(void) { EMACS_GET_TIME(TV1); watch_not_started = 0; }