Skip to content

Commit 7b33959

Browse files
committed
eval: Use xtimer_start() for status bar updates
1 parent f6f0613 commit 7b33959

1 file changed

Lines changed: 76 additions & 36 deletions

File tree

src/eval.c

Lines changed: 76 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "stat.h"
2929
#include "trie.h"
3030
#include "xregex.h"
31+
#include "xtime.h"
3132

3233
#include <errno.h>
3334
#include <fcntl.h>
@@ -42,6 +43,7 @@
4243
#include <string.h>
4344
#include <strings.h>
4445
#include <sys/resource.h>
46+
#include <sys/time.h>
4547
#include <sys/types.h>
4648
#include <time.h>
4749
#include <unistd.h>
@@ -1146,20 +1148,7 @@ bool eval_comma(const struct bfs_expr *expr, struct bfs_eval *state) {
11461148
}
11471149

11481150
/** Update the status bar. */
1149-
static void eval_status(struct bfs_eval *state, struct bfs_bar *bar, struct timespec *last_status, size_t count) {
1150-
struct timespec now;
1151-
if (eval_gettime(state, &now) == 0) {
1152-
struct timespec elapsed = {0};
1153-
timespec_elapsed(&elapsed, last_status, &now);
1154-
1155-
// Update every 0.1s
1156-
if (elapsed.tv_sec > 0 || elapsed.tv_nsec >= 100000000L) {
1157-
*last_status = now;
1158-
} else {
1159-
return;
1160-
}
1161-
}
1162-
1151+
static void eval_status(struct bfs_eval *state, struct bfs_bar *bar, size_t count) {
11631152
size_t width = bfs_bar_width(bar);
11641153
if (width < 3) {
11651154
return;
@@ -1389,9 +1378,13 @@ struct callback_args {
13891378

13901379
/** The status bar. */
13911380
struct bfs_bar *bar;
1392-
/** The time of the last status update. */
1393-
struct timespec last_status;
1394-
/** Flag set by SIGINFO hook. */
1381+
/** The SIGALRM hook. */
1382+
struct sighook *alrm_hook;
1383+
/** The interval timer. */
1384+
struct timer *timer;
1385+
/** Flag set by SIGALRM. */
1386+
atomic bool alrm_flag;
1387+
/** Flag set by SIGINFO. */
13951388
atomic bool info_flag;
13961389

13971390
/** The number of files visited so far. */
@@ -1406,6 +1399,64 @@ struct callback_args {
14061399
int ret;
14071400
};
14081401

1402+
/** Update the status bar in response to SIGALRM. */
1403+
static void eval_sigalrm(int sig, siginfo_t *info, void *ptr) {
1404+
struct callback_args *args = ptr;
1405+
store(&args->alrm_flag, true, relaxed);
1406+
}
1407+
1408+
/** Show/hide the bar in response to SIGINFO. */
1409+
static void eval_siginfo(int sig, siginfo_t *info, void *ptr) {
1410+
struct callback_args *args = ptr;
1411+
store(&args->info_flag, true, relaxed);
1412+
}
1413+
1414+
/** Show the status bar. */
1415+
static void eval_show_bar(struct callback_args *args) {
1416+
args->alrm_hook = sighook(SIGALRM, eval_sigalrm, args, SH_CONTINUE);
1417+
if (!args->alrm_hook) {
1418+
goto fail;
1419+
}
1420+
1421+
args->bar = bfs_bar_show();
1422+
if (!args->bar) {
1423+
goto fail;
1424+
}
1425+
1426+
// Update the bar every 0.1s
1427+
struct timespec ival = { .tv_nsec = 100 * 1000 * 1000 };
1428+
args->timer = xtimer_start(&ival);
1429+
if (!args->timer) {
1430+
goto fail;
1431+
}
1432+
1433+
// Update the bar immediately
1434+
store(&args->alrm_flag, true, relaxed);
1435+
1436+
return;
1437+
1438+
fail:
1439+
bfs_warning(args->ctx, "Couldn't show status bar: %s.\n\n", errstr());
1440+
1441+
bfs_bar_hide(args->bar);
1442+
args->bar = NULL;
1443+
1444+
sigunhook(args->alrm_hook);
1445+
args->alrm_hook = NULL;
1446+
}
1447+
1448+
/** Hide the status bar. */
1449+
static void eval_hide_bar(struct callback_args *args) {
1450+
xtimer_stop(args->timer);
1451+
args->timer = NULL;
1452+
1453+
sigunhook(args->alrm_hook);
1454+
args->alrm_hook = NULL;
1455+
1456+
bfs_bar_hide(args->bar);
1457+
args->bar = NULL;
1458+
}
1459+
14091460
/**
14101461
* bftw() callback.
14111462
*/
@@ -1426,18 +1477,14 @@ static enum bftw_action eval_callback(const struct BFTW *ftwbuf, void *ptr) {
14261477
// Check whether SIGINFO was delivered and show/hide the bar
14271478
if (exchange(&args->info_flag, false, relaxed)) {
14281479
if (args->bar) {
1429-
bfs_bar_hide(args->bar);
1430-
args->bar = NULL;
1480+
eval_hide_bar(args);
14311481
} else {
1432-
args->bar = bfs_bar_show();
1433-
if (!args->bar) {
1434-
bfs_warning(ctx, "Couldn't show status bar: %s.\n", errstr());
1435-
}
1482+
eval_show_bar(args);
14361483
}
14371484
}
14381485

1439-
if (args->bar) {
1440-
eval_status(&state, args->bar, &args->last_status, args->count);
1486+
if (exchange(&args->alrm_flag, false, relaxed)) {
1487+
eval_status(&state, args->bar, args->count);
14411488
}
14421489

14431490
if (ftwbuf->type == BFS_ERROR) {
@@ -1509,12 +1556,6 @@ static enum bftw_action eval_callback(const struct BFTW *ftwbuf, void *ptr) {
15091556
return state.action;
15101557
}
15111558

1512-
/** Show/hide the bar in response to SIGINFO. */
1513-
static void eval_siginfo(int sig, siginfo_t *info, void *ptr) {
1514-
struct callback_args *args = ptr;
1515-
store(&args->info_flag, true, relaxed);
1516-
}
1517-
15181559
/** Raise RLIMIT_NOFILE if possible, and return the new limit. */
15191560
static int raise_fdlimit(struct bfs_ctx *ctx) {
15201561
rlim_t cur = ctx->orig_nofile.rlim_cur;
@@ -1671,10 +1712,7 @@ int bfs_eval(struct bfs_ctx *ctx) {
16711712
};
16721713

16731714
if (ctx->status) {
1674-
args.bar = bfs_bar_show();
1675-
if (!args.bar) {
1676-
bfs_warning(ctx, "Couldn't show status bar: %s.\n\n", errstr());
1677-
}
1715+
eval_show_bar(&args);
16781716
}
16791717

16801718
#ifdef SIGINFO
@@ -1752,7 +1790,9 @@ int bfs_eval(struct bfs_ctx *ctx) {
17521790
}
17531791

17541792
sigunhook(info_hook);
1755-
bfs_bar_hide(args.bar);
1793+
if (args.bar) {
1794+
eval_hide_bar(&args);
1795+
}
17561796

17571797
if (ctx->ignore_errors && args.nerrors > 0) {
17581798
bfs_warning(ctx, "Suppressed errors: %zu\n", args.nerrors);

0 commit comments

Comments
 (0)