render: don’t create/destroy the title update timer each time

Create it once when instantiating the terminal. Add a boolean to track
whether the timer is running or not.
This commit is contained in:
Daniel Eklöf 2021-06-18 15:53:47 +02:00
parent 535c82d628
commit 07b455e882
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 45 additions and 37 deletions

View file

@ -3501,26 +3501,10 @@ fdm_hook_refresh_pending_terminals(struct fdm *fdm, void *data)
} }
} }
static bool
fdm_title_update(struct fdm *fdm, int fd, int events, void *data)
{
struct terminal *term = data;
fdm_del(fdm, fd);
term->render.title.timer_fd = -1;
render_update_title(term);
struct timeval now;
if (gettimeofday(&now, NULL) == 0)
term->render.title.last_update = now;
return true;
}
void void
render_refresh_title(struct terminal *term) render_refresh_title(struct terminal *term)
{ {
if (term->render.title.timer_fd >= 0) if (term->render.title.is_armed)
return; return;
struct timeval now; struct timeval now;
@ -3531,23 +3515,11 @@ render_refresh_title(struct terminal *term)
timersub(&now, &term->render.title.last_update, &diff); timersub(&now, &term->render.title.last_update, &diff);
if (diff.tv_sec == 0 && diff.tv_usec < 8333) { if (diff.tv_sec == 0 && diff.tv_usec < 8333) {
int fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
if (fd < 0)
return;
const struct itimerspec timeout = { const struct itimerspec timeout = {
.it_value = {.tv_nsec = 8333 * 1000 - diff.tv_usec * 1000}, .it_value = {.tv_nsec = 8333 * 1000 - diff.tv_usec * 1000},
}; };
if (timerfd_settime(fd, 0, &timeout, NULL) < 0) { timerfd_settime(term->render.title.timer_fd, 0, &timeout, NULL);
close(fd);
return;
}
if (!fdm_add(term->fdm, fd, EPOLLIN, &fdm_title_update, term))
close(fd);
else
term->render.title.timer_fd = fd;
} else { } else {
term->render.title.last_update = now; term->render.title.last_update = now;
render_update_title(term); render_update_title(term);

View file

@ -552,6 +552,31 @@ fdm_app_sync_updates_timeout(
return true; return true;
} }
static bool
fdm_title_update_timeout(struct fdm *fdm, int fd, int events, void *data)
{
if (events & EPOLLHUP)
return false;
struct terminal *term = data;
uint64_t unused;
ssize_t ret = read(term->render.title.timer_fd, &unused, sizeof(unused));
if (ret < 0) {
if (errno == EAGAIN)
return true;
LOG_ERRNO("failed to read title update throttle timer");
return false;
}
struct itimerspec reset = {{0}};
timerfd_settime(term->render.title.timer_fd, 0, &reset, NULL);
term->render.title.is_armed = false;
render_refresh_title(term);
return true;
}
static bool static bool
initialize_render_workers(struct terminal *term) initialize_render_workers(struct terminal *term)
{ {
@ -980,6 +1005,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
int delay_lower_fd = -1; int delay_lower_fd = -1;
int delay_upper_fd = -1; int delay_upper_fd = -1;
int app_sync_updates_fd = -1; int app_sync_updates_fd = -1;
int title_update_fd = -1;
struct terminal *term = malloc(sizeof(*term)); struct terminal *term = malloc(sizeof(*term));
if (unlikely(term == NULL)) { if (unlikely(term == NULL)) {
@ -987,27 +1013,33 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
return NULL; return NULL;
} }
if ((ptmx = posix_openpt(O_RDWR | O_NOCTTY)) == -1) { if ((ptmx = posix_openpt(O_RDWR | O_NOCTTY)) < 0) {
LOG_ERRNO("failed to open PTY"); LOG_ERRNO("failed to open PTY");
goto close_fds; goto close_fds;
} }
if ((flash_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK)) == -1) { if ((flash_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK)) < 0) {
LOG_ERRNO("failed to create flash timer FD"); LOG_ERRNO("failed to create flash timer FD");
goto close_fds; goto close_fds;
} }
if ((delay_lower_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK)) == -1 || if ((delay_lower_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK)) < 0 ||
(delay_upper_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK)) == -1) (delay_upper_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK)) < 0)
{ {
LOG_ERRNO("failed to create delayed rendering timer FDs"); LOG_ERRNO("failed to create delayed rendering timer FDs");
goto close_fds; goto close_fds;
} }
if ((app_sync_updates_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK)) == -1) if ((app_sync_updates_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK)) < 0)
{ {
LOG_ERRNO("failed to create application synchronized updates timer FD"); LOG_ERRNO("failed to create application synchronized updates timer FD");
goto close_fds; goto close_fds;
} }
if ((title_update_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK)) < 0)
{
LOG_ERRNO("failed to create title update throttle timer FD");
goto close_fds;
}
if (ioctl(ptmx, (unsigned int)TIOCSWINSZ, if (ioctl(ptmx, (unsigned int)TIOCSWINSZ,
&(struct winsize){.ws_row = 24, .ws_col = 80}) < 0) &(struct winsize){.ws_row = 24, .ws_col = 80}) < 0)
{ {
@ -1032,7 +1064,8 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
if (!fdm_add(fdm, flash_fd, EPOLLIN, &fdm_flash, term) || if (!fdm_add(fdm, flash_fd, EPOLLIN, &fdm_flash, term) ||
!fdm_add(fdm, delay_lower_fd, EPOLLIN, &fdm_delayed_render, term) || !fdm_add(fdm, delay_lower_fd, EPOLLIN, &fdm_delayed_render, term) ||
!fdm_add(fdm, delay_upper_fd, EPOLLIN, &fdm_delayed_render, term) || !fdm_add(fdm, delay_upper_fd, EPOLLIN, &fdm_delayed_render, term) ||
!fdm_add(fdm, app_sync_updates_fd, EPOLLIN, &fdm_app_sync_updates_timeout, term)) !fdm_add(fdm, app_sync_updates_fd, EPOLLIN, &fdm_app_sync_updates_timeout, term) ||
!fdm_add(fdm, title_update_fd, EPOLLIN, &fdm_title_update_timeout, term))
{ {
goto err; goto err;
} }
@ -1114,7 +1147,8 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
.scrollback_lines = conf->scrollback.lines, .scrollback_lines = conf->scrollback.lines,
.app_sync_updates.timer_fd = app_sync_updates_fd, .app_sync_updates.timer_fd = app_sync_updates_fd,
.title = { .title = {
.timer_fd = -1, .is_armed = false,
.timer_fd = title_update_fd,
}, },
.workers = { .workers = {
.count = conf->render_worker_count, .count = conf->render_worker_count,
@ -1220,6 +1254,7 @@ close_fds:
fdm_del(fdm, delay_lower_fd); fdm_del(fdm, delay_lower_fd);
fdm_del(fdm, delay_upper_fd); fdm_del(fdm, delay_upper_fd);
fdm_del(fdm, app_sync_updates_fd); fdm_del(fdm, app_sync_updates_fd);
fdm_del(fdm, title_update_fd);
free(term); free(term);
return NULL; return NULL;

View file

@ -490,6 +490,7 @@ struct terminal {
struct { struct {
struct timeval last_update; struct timeval last_update;
bool is_armed;
int timer_fd; int timer_fd;
} title; } title;