From 8fbc4323f4bd005b40a370c7de695cda981a5d24 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 19 May 2022 21:24:52 +0200 Subject: [PATCH] rate-limit progress counters for simple local operations, they could easily dominate the cpu load. also, over a slow remote tty, they could slow down things noticeably. --- src/main_sync.c | 51 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/main_sync.c b/src/main_sync.c index 3d3d90f..18fbc87 100644 --- a/src/main_sync.c +++ b/src/main_sync.c @@ -13,16 +13,17 @@ static int ops_any[2], trash_any[2]; static int chans_total, chans_done; static int boxes_total, boxes_done; -void -stats( void ) +static int stats_steps; +static int64_t stats_stamp; +static wakeup_t stats_wakeup; + +static void +print_stats( void ) { char buf[3][64]; char *cs; static int cols = -1; - if (!(DFlags & PROGRESS)) - return; - if (cols < 0 && (!(cs = getenv( "COLUMNS" )) || !(cols = atoi( cs )))) cols = 80; int ll = sprintf( buf[2], "C: %d/%d B: %d/%d", chans_done, chans_total, boxes_done, boxes_total ); @@ -38,6 +39,37 @@ stats( void ) progress( "\r%s F: %.*s N: %.*s", buf[2], cls, buf[0], cls, buf[1] ); } +static void +stats_timeout( void *aux ATTR_UNUSED ) +{ + stats_steps = -1; + conf_wakeup( &stats_wakeup, 200 ); + print_stats(); +} + +void +stats( void ) +{ + if (!(DFlags & PROGRESS)) + return; + + // If the main loop appears to be running, skip the sync path. + if (stats_steps < 0) + return; + + // Rate-limit the (somewhat) expensive timer queries. + if (++stats_steps < 10) + return; + stats_steps = 0; + + int64_t now = get_now(); + if (now < stats_stamp + 300) + return; + stats_stamp = now; + + print_stats(); +} + static void summary( void ) { @@ -339,8 +371,10 @@ sync_chans( core_vars_t *cvars, char **argv ) } mvars->chanptr = chans; - if (!cvars->list) - stats(); + if (!cvars->list && (DFlags & PROGRESS)) { + init_wakeup( &stats_wakeup, stats_timeout, NULL ); + stats_timeout( NULL ); + } do_sync_chans( mvars ); main_loop(); if (!cvars->list) { @@ -398,6 +432,7 @@ static void do_sync_chans( main_vars_t *mvars ) { while (mvars->chanptr) { + stats_steps = 0; // Determine main loop use afresh mvars->chan = mvars->chanptr->conf; info( "Channel %s\n", mvars->chan->name ); for (int t = 0; t < 2; t++) { @@ -445,6 +480,8 @@ do_sync_chans( main_vars_t *mvars ) advance_chan( mvars ); } cleanup_drivers(); + if (!mvars->cvars->list && (DFlags & PROGRESS)) + wipe_wakeup( &stats_wakeup ); } static void