diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e2d0d6c..6ca77fb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 (user’s shell is not executed). +* `gettimeofday()` has been replaced with `clock_gettime()`, due to it being + marked as obsolete by POSIX. ### Deprecated diff --git a/grid.c b/grid.c index 17158c3b..844ea90c 100644 --- a/grid.c +++ b/grid.c @@ -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 } diff --git a/input.c b/input.c index 885ae02e..10d36b04 100644 --- a/input.c +++ b/input.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -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 diff --git a/input.h b/input.h index 8430eef9..ea488a86 100644 --- a/input.h +++ b/input.h @@ -4,6 +4,7 @@ #include #include "wayland.h" +#include "misc.h" /* * Custom defines for mouse wheel left/right buttons. diff --git a/misc.c b/misc.c index feb5e73b..ea89e94e 100644 --- a/misc.c +++ b/misc.c @@ -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; + } +} diff --git a/misc.h b/misc.h index 3c897336..9bbc4744 100644 --- a/misc.h +++ b/misc.h @@ -2,5 +2,8 @@ #include #include +#include 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); diff --git a/render.c b/render.c index 4288f395..8cdcd3ce 100644 --- a/render.c +++ b/render.c @@ -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); diff --git a/render.h b/render.h index 145aaba8..644b4d00 100644 --- a/render.h +++ b/render.h @@ -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); diff --git a/shm.c b/shm.c index 62afd76d..005d030e 100644 --- a/shm.c +++ b/shm.c @@ -5,11 +5,10 @@ #include #include #include +#include #include #include -#include -#include #include #include @@ -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 } diff --git a/terminal.c b/terminal.c index f985ec54..c639d3d1 100644 --- a/terminal.c +++ b/terminal.c @@ -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 diff --git a/terminal.h b/terminal.h index 3d29c4ae..e6c82f41 100644 --- a/terminal.h +++ b/terminal.h @@ -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; diff --git a/wayland.h b/wayland.h index e84ce237..718ad9a2 100644 --- a/wayland.h +++ b/wayland.h @@ -2,8 +2,7 @@ #include #include - -#include +#include #include #include @@ -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];