replace gettimeofday with clock_gettime

POSIX.1-2008 has marked gettimeofday(2) as obsolete, recommending the
use of clock_gettime(2) instead.

CLOCK_MONOTONIC has been used instead of CLOCK_REALTIME because it is
unaffected by manual changes in the system clock. This makes it better
for our purposes, namely, measuring the difference between two points in
time.

tv_sec has been casted to long in most places since POSIX does not
define the actual type of time_t.
This commit is contained in:
Pranjal Kole 2022-01-15 14:56:13 +05:30
parent 0d649408a0
commit 0da19a81bc
12 changed files with 123 additions and 103 deletions

View file

@ -72,6 +72,8 @@
“en_US.UTF-8” if started with a non-UTF8 locale. If this fails, foot
will start, but only to display a window with an error (users shell
is not executed).
* `gettimeofday()` has been replaced with `clock_gettime()`, due to it being
marked as obsolete by POSIX.
### Deprecated

18
grid.c
View file

@ -557,8 +557,8 @@ grid_resize_and_reflow(
struct coord *const _tracking_points[static tracking_points_count])
{
#if defined(TIME_REFLOW) && TIME_REFLOW
struct timeval start;
gettimeofday(&start, NULL);
struct timespec start;
clock_gettime(CLOCK_MONOTONIC, &start);
#endif
struct row *const *old_grid = grid->rows;
@ -966,15 +966,15 @@ grid_resize_and_reflow(
tll_free(untranslated_sixels);
#if defined(TIME_REFLOW) && TIME_REFLOW
struct timeval stop;
gettimeofday(&stop, NULL);
struct timespec stop;
clock_gettime(CLOCK_MONOTONIC, &stop);
struct timeval diff;
timersub(&stop, &start, &diff);
LOG_INFO("reflowed %d -> %d rows in %llds %lldµs",
struct timespec diff;
timespec_sub(&stop, &start, &diff);
LOG_INFO("reflowed %d -> %d rows in %lds %ldns",
old_rows, new_rows,
(long long)diff.tv_sec,
(long long)diff.tv_usec);
(long)diff.tv_sec,
diff.tv_nsec);
#endif
}

View file

@ -8,7 +8,6 @@
#include <errno.h>
#include <wctype.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/timerfd.h>
#include <sys/epoll.h>
#include <fcntl.h>
@ -2164,12 +2163,12 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
/* Time since last click */
struct timeval now, since_last;
gettimeofday(&now, NULL);
timersub(&now, &seat->mouse.last_time, &since_last);
struct timespec now, since_last;
clock_gettime(CLOCK_MONOTONIC, &now);
timespec_sub(&now, &seat->mouse.last_time, &since_last);
if (seat->mouse.last_released_button == button &&
since_last.tv_sec == 0 && since_last.tv_usec <= 300 * 1000)
since_last.tv_sec == 0 && since_last.tv_nsec <= 300 * 1000 * 1000)
{
seat->mouse.count++;
} else

View file

@ -4,6 +4,7 @@
#include <wayland-client.h>
#include "wayland.h"
#include "misc.h"
/*
* Custom defines for mouse wheel left/right buttons.

13
misc.c
View file

@ -13,3 +13,16 @@ isword(wchar_t wc, bool spaces_only, const wchar_t *delimiters)
return iswgraph(wc);
}
void
timespec_sub(const struct timespec *a, const struct timespec *b,
struct timespec *res)
{
res->tv_sec = a->tv_sec - b->tv_sec;
res->tv_nsec = a->tv_nsec - b->tv_nsec;
/* tv_nsec may be negative */
if (res->tv_nsec < 0) {
res->tv_sec--;
res->tv_nsec += 1000 * 1000 * 1000;
}
}

3
misc.h
View file

@ -2,5 +2,8 @@
#include <stdbool.h>
#include <wchar.h>
#include <time.h>
bool isword(wchar_t wc, bool spaces_only, const wchar_t *delimiters);
void timespec_sub(const struct timespec *a, const struct timespec *b, struct timespec *res);

View file

@ -948,8 +948,8 @@ grid_render_scroll(struct terminal *term, struct buffer *buf,
return;
#if TIME_SCROLL_DAMAGE
struct timeval start_time;
gettimeofday(&start_time, NULL);
struct timespec start_time;
clock_gettime(CLOCK_MONOTONIC, &start_time);
#endif
int dst_y = term->margins.top + (dmg->region.start + 0) * term->cell_height;
@ -1019,15 +1019,15 @@ grid_render_scroll(struct terminal *term, struct buffer *buf,
}
#if TIME_SCROLL_DAMAGE
struct timeval end_time;
gettimeofday(&end_time, NULL);
struct timespec end_time;
clock_gettime(CLOCK_MONOTONIC, &end_time);
struct timeval memmove_time;
timersub(&end_time, &start_time, &memmove_time);
LOG_INFO("scrolled %dKB (%d lines) using %s in %lds %ldus",
struct timespec memmove_time;
timespec_sub(&end_time, &start_time, &memmove_time);
LOG_INFO("scrolled %dKB (%d lines) using %s in %lds %ldns",
height * buf->stride / 1024, dmg->lines,
did_shm_scroll ? "SHM" : try_shm_scroll ? "memmove (SHM failed)" : "memmove",
memmove_time.tv_sec, memmove_time.tv_usec);
(long)memmove_time.tv_sec, memmove_time.tv_nsec);
#endif
wl_surface_damage_buffer(
@ -1049,8 +1049,8 @@ grid_render_scroll_reverse(struct terminal *term, struct buffer *buf,
return;
#if TIME_SCROLL_DAMAGE
struct timeval start_time;
gettimeofday(&start_time, NULL);
struct timespec start_time;
clock_gettime(CLOCK_MONOTONIC, &start_time);
#endif
int src_y = term->margins.top + (dmg->region.start + 0) * term->cell_height;
@ -1084,15 +1084,15 @@ grid_render_scroll_reverse(struct terminal *term, struct buffer *buf,
}
#if TIME_SCROLL_DAMAGE
struct timeval end_time;
gettimeofday(&end_time, NULL);
struct timespec end_time;
clock_gettime(CLOCK_MONOTONIC, &end_time);
struct timeval memmove_time;
timersub(&end_time, &start_time, &memmove_time);
LOG_INFO("scrolled REVERSE %dKB (%d lines) using %s in %lds %ldus",
struct timespec memmove_time;
timespec_sub(&end_time, &start_time, &memmove_time);
LOG_INFO("scrolled REVERSE %dKB (%d lines) using %s in %lds %ldns",
height * buf->stride / 1024, dmg->lines,
did_shm_scroll ? "SHM" : try_shm_scroll ? "memmove (SHM failed)" : "memmove",
memmove_time.tv_sec, memmove_time.tv_usec);
(long)memmove_time.tv_sec, memmove_time.tv_nsec);
#endif
wl_surface_damage_buffer(
@ -2285,12 +2285,12 @@ render_scrollback_position(struct terminal *term)
}
static void
render_render_timer(struct terminal *term, struct timeval render_time)
render_render_timer(struct terminal *term, struct timespec render_time)
{
struct wl_window *win = term->window;
wchar_t text[256];
double usecs = render_time.tv_sec * 1000000 + render_time.tv_usec;
double usecs = render_time.tv_sec * 1000000 + render_time.tv_nsec / 1000.0;
swprintf(text, sizeof(text) / sizeof(text[0]), L"%.2f µs", usecs);
const int scale = term->scale;
@ -2468,10 +2468,10 @@ grid_render(struct terminal *term)
if (term->shutdown.in_progress)
return;
struct timeval start_time, start_double_buffering = {0}, stop_double_buffering = {0};
struct timespec start_time, start_double_buffering = {0}, stop_double_buffering = {0};
if (term->conf->tweak.render_timer != RENDER_TIMER_NONE)
gettimeofday(&start_time, NULL);
clock_gettime(CLOCK_MONOTONIC, &start_time);
xassert(term->width > 0);
xassert(term->height > 0);
@ -2501,9 +2501,9 @@ grid_render(struct terminal *term)
xassert(term->render.last_buf->width == buf->width);
xassert(term->render.last_buf->height == buf->height);
gettimeofday(&start_double_buffering, NULL);
clock_gettime(CLOCK_MONOTONIC, &start_double_buffering);
reapply_old_damage(term, buf, term->render.last_buf);
gettimeofday(&stop_double_buffering, NULL);
clock_gettime(CLOCK_MONOTONIC, &stop_double_buffering);
}
if (term->render.last_buf != NULL) {
@ -2733,24 +2733,24 @@ grid_render(struct terminal *term)
render_scrollback_position(term);
if (term->conf->tweak.render_timer != RENDER_TIMER_NONE) {
struct timeval end_time;
gettimeofday(&end_time, NULL);
struct timespec end_time;
clock_gettime(CLOCK_MONOTONIC, &end_time);
struct timeval render_time;
timersub(&end_time, &start_time, &render_time);
struct timespec render_time;
timespec_sub(&end_time, &start_time, &render_time);
struct timeval double_buffering_time;
timersub(&stop_double_buffering, &start_double_buffering, &double_buffering_time);
struct timespec double_buffering_time;
timespec_sub(&stop_double_buffering, &start_double_buffering, &double_buffering_time);
switch (term->conf->tweak.render_timer) {
case RENDER_TIMER_LOG:
case RENDER_TIMER_BOTH:
LOG_INFO("frame rendered in %llds %lld µs "
"(%llds %lld µs double buffering)",
(long long)render_time.tv_sec,
(long long)render_time.tv_usec,
(long long)double_buffering_time.tv_sec,
(long long)double_buffering_time.tv_usec);
LOG_INFO("frame rendered in %lds %ldns "
"(%lds %ldns double buffering)",
(long)render_time.tv_sec,
render_time.tv_nsec,
(long)double_buffering_time.tv_sec,
double_buffering_time.tv_nsec);
break;
case RENDER_TIMER_OSD:
@ -3920,16 +3920,16 @@ render_refresh_title(struct terminal *term)
if (term->render.title.is_armed)
return;
struct timeval now;
if (gettimeofday(&now, NULL) < 0)
struct timespec now;
if (clock_gettime(CLOCK_MONOTONIC, &now) < 0)
return;
struct timeval diff;
timersub(&now, &term->render.title.last_update, &diff);
struct timespec diff;
timespec_sub(&now, &term->render.title.last_update, &diff);
if (diff.tv_sec == 0 && diff.tv_usec < 8333) {
if (diff.tv_sec == 0 && diff.tv_nsec < 8333 * 1000) {
const struct itimerspec timeout = {
.it_value = {.tv_nsec = 8333 * 1000 - diff.tv_usec * 1000},
.it_value = {.tv_nsec = 8333 * 1000 - diff.tv_nsec},
};
timerfd_settime(term->render.title.timer_fd, 0, &timeout, NULL);

View file

@ -4,6 +4,7 @@
#include "terminal.h"
#include "fdm.h"
#include "wayland.h"
#include "misc.h"
struct renderer;
struct renderer *render_init(struct fdm *fdm, struct wayland *wayl);

83
shm.c
View file

@ -5,11 +5,10 @@
#include <errno.h>
#include <unistd.h>
#include <limits.h>
#include <time.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <pixman.h>
@ -672,11 +671,11 @@ shm_scroll_forward(struct buffer_private *buf, int rows,
xassert(new_offset + buf->size <= max_pool_size);
#if TIME_SCROLL
struct timeval tot;
struct timeval time1;
gettimeofday(&time1, NULL);
struct timespec tot;
struct timespec time1;
clock_gettime(CLOCK_MONOTONIC, &time1);
struct timeval time2 = time1;
struct timespec time2 = time1;
#endif
if (top_keep_rows > 0) {
@ -690,9 +689,10 @@ shm_scroll_forward(struct buffer_private *buf, int rows,
top_keep_rows * stride);
#if TIME_SCROLL
gettimeofday(&time2, NULL);
timersub(&time2, &time1, &tot);
LOG_INFO("memmove (top region): %lds %ldus", tot.tv_sec, tot.tv_usec);
clock_gettime(CLOCK_MONOTONIC, &time2);
timespec_sub(&time2, &time1, &tot);
LOG_INFO("memmove (top region): %lds %ldns",
(long)tot.tv_sec, tot.tv_nsec);
#endif
}
@ -713,20 +713,20 @@ shm_scroll_forward(struct buffer_private *buf, int rows,
}
#if TIME_SCROLL
struct timeval time3;
gettimeofday(&time3, NULL);
timersub(&time3, &time2, &tot);
LOG_INFO("PUNCH HOLE: %lds %ldus", tot.tv_sec, tot.tv_usec);
struct timespec time3;
clock_gettime(CLOCK_MONOTONIC, &time3);
timespec_sub(&time3, &time2, &tot);
LOG_INFO("PUNCH HOLE: %lds %ldns", (long)tot.tv_sec, tot.tv_nsec);
#endif
/* Re-instantiate pixman+wl_buffer+raw pointersw */
bool ret = instantiate_offset(buf, new_offset);
#if TIME_SCROLL
struct timeval time4;
gettimeofday(&time4, NULL);
timersub(&time4, &time3, &tot);
LOG_INFO("instantiate offset: %lds %ldus", tot.tv_sec, tot.tv_usec);
struct timespec time4;
clock_gettime(CLOCK_MONOTONIC, &time4);
timespec_sub(&time4, &time3, &tot);
LOG_INFO("instantiate offset: %lds %ldns", (long)tot.tv_sec, tot.tv_nsec);
#endif
if (ret && bottom_keep_rows > 0) {
@ -741,11 +741,12 @@ shm_scroll_forward(struct buffer_private *buf, int rows,
bottom_keep_rows * stride);
#if TIME_SCROLL
struct timeval time5;
gettimeofday(&time5, NULL);
struct timespec time5;
clock_gettime(CLOCK_MONOTONIC, &time5);
timersub(&time5, &time4, &tot);
LOG_INFO("memmove (bottom region): %lds %ldus", tot.tv_sec, tot.tv_usec);
timespec_sub(&time5, &time4, &tot);
LOG_INFO("memmove (bottom region): %lds %ldns",
(long)tot.tv_sec, tot.tv_nsec);
#endif
}
@ -778,11 +779,11 @@ shm_scroll_reverse(struct buffer_private *buf, int rows,
xassert(new_offset <= max_pool_size);
#if TIME_SCROLL
struct timeval time0;
gettimeofday(&time0, NULL);
struct timespec time0;
clock_gettime(CLOCK_MONOTONIC, &time0);
struct timeval tot;
struct timeval time1 = time0;
struct timespec tot;
struct timespec time1 = time0;
#endif
if (bottom_keep_rows > 0) {
@ -797,9 +798,10 @@ shm_scroll_reverse(struct buffer_private *buf, int rows,
bottom_keep_rows * stride);
#if TIME_SCROLL
gettimeofday(&time1, NULL);
timersub(&time1, &time0, &tot);
LOG_INFO("memmove (bottom region): %lds %ldus", tot.tv_sec, tot.tv_usec);
clock_gettime(CLOCK_MONOTONIC, &time1);
timespec_sub(&time1, &time0, &tot);
LOG_INFO("memmove (bottom region): %lds %ldns",
(long)tot.tv_sec, tot.tv_nsec);
#endif
}
@ -819,20 +821,20 @@ shm_scroll_reverse(struct buffer_private *buf, int rows,
goto err;
}
#if TIME_SCROLL
struct timeval time2;
gettimeofday(&time2, NULL);
timersub(&time2, &time1, &tot);
LOG_INFO("fallocate: %lds %ldus", tot.tv_sec, tot.tv_usec);
struct timespec time2;
clock_gettime(CLOCK_MONOTONIC, &time2);
timespec_sub(&time2, &time1, &tot);
LOG_INFO("fallocate: %lds %ldns", (long)tot.tv_sec, tot.tv_nsec);
#endif
/* Re-instantiate pixman+wl_buffer+raw pointers */
bool ret = instantiate_offset(buf, new_offset);
#if TIME_SCROLL
struct timeval time3;
gettimeofday(&time3, NULL);
timersub(&time3, &time2, &tot);
LOG_INFO("instantiate offset: %lds %ldus", tot.tv_sec, tot.tv_usec);
struct timespec time3;
clock_gettime(CLOCK_MONOTONIC, &time3);
timespec_sub(&time3, &time2, &tot);
LOG_INFO("instantiate offset: %lds %ldns", (long)tot.tv_sec, tot.tv_nsec);
#endif
if (ret && top_keep_rows > 0) {
@ -846,10 +848,11 @@ shm_scroll_reverse(struct buffer_private *buf, int rows,
top_keep_rows * stride);
#if TIME_SCROLL
struct timeval time4;
gettimeofday(&time4, NULL);
timersub(&time4, &time2, &tot);
LOG_INFO("memmove (top region): %lds %ldus", tot.tv_sec, tot.tv_usec);
struct timespec time4;
clock_gettime(CLOCK_MONOTONIC, &time4);
timespec_sub(&time4, &time3, &tot);
LOG_INFO("memmove (top region): %lds %ldns",
(long)tot.tv_sec, tot.tv_nsec);
#endif
}

View file

@ -292,12 +292,11 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data)
clock_gettime(CLOCK_MONOTONIC, &now);
if (last.tv_sec > 0 || last.tv_nsec > 0) {
struct timeval diff;
struct timeval l = {last.tv_sec, last.tv_nsec / 1000};
struct timeval n = {now.tv_sec, now.tv_nsec / 1000};
struct timespec diff;
timersub(&n, &l, &diff);
LOG_INFO("waited %lu µs for more input", diff.tv_usec);
timespec_sub(&now, &last, &diff);
LOG_INFO("waited %lds %ldns for more input",
(long)diff.tv_sec, diff.tv_nsec);
}
last = now;
#endif

View file

@ -552,7 +552,7 @@ struct terminal {
bool urgency; /* Signal 'urgency' (paint borders red) */
struct {
struct timeval last_update;
struct timespec last_update;
bool is_armed;
int timer_fd;
} title;

View file

@ -2,8 +2,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <sys/time.h>
#include <time.h>
#include <wayland-client.h>
#include <xkbcommon/xkbcommon.h>
@ -247,7 +246,7 @@ struct seat {
/* Double- and triple click state */
int count;
int last_released_button;
struct timeval last_time;
struct timespec last_time;
/* We used a discrete axis event in the current pointer frame */
double aggregated[2];