tools: use ppoll() where higher timeout resolution makes sense
authorBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Tue, 23 Apr 2024 10:04:50 +0000 (12:04 +0200)
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Wed, 24 Apr 2024 07:55:36 +0000 (09:55 +0200)
We allow timeout units to be specified in microseconds but for poll() we
need to round them up to milliseconds. Switch to ppoll() to avoid losing
precision.

Reviewed-by: Kent Gibson <warthog618@gmail.com>
Link: https://lore.kernel.org/r/20240423100452.32958-3-brgl@bgdev.pl
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
tools/gpiomon.c
tools/gpionotify.c

index 40e6ac2ff8f2c05ccf13bc35dca5b47d402ba2cf..7135843348dbb204208a7ae14fb60574b962f7ff 100644 (file)
@@ -176,7 +176,7 @@ static int parse_config(int argc, char **argv, struct config *cfg)
                        cfg->fmt = optarg;
                        break;
                case 'i':
-                       cfg->idle_timeout = parse_period_or_die(optarg) / 1000;
+                       cfg->idle_timeout = parse_period_or_die(optarg);
                        break;
                case 'l':
                        cfg->active_low = true;
@@ -362,6 +362,7 @@ int main(int argc, char **argv)
        int num_lines, events_done = 0;
        struct gpiod_edge_event *event;
        struct line_resolver *resolver;
+       struct timespec idle_timeout;
        struct gpiod_chip *chip;
        struct pollfd *pollfds;
        unsigned int *offsets;
@@ -450,10 +451,17 @@ int main(int argc, char **argv)
        if (cfg.banner)
                print_banner(argc, argv);
 
+       if (cfg.idle_timeout > 0) {
+               idle_timeout.tv_sec = cfg.idle_timeout / 1000000;
+               idle_timeout.tv_nsec =
+                               (cfg.idle_timeout % 1000000) * 1000;
+       }
+
        for (;;) {
                fflush(stdout);
 
-               ret = poll(pollfds, resolver->num_chips, cfg.idle_timeout);
+               ret = ppoll(pollfds, resolver->num_chips,
+                           cfg.idle_timeout > 0 ? &idle_timeout : NULL, NULL);
                if (ret < 0)
                        die_perror("error polling for events");
 
index d2aee152b0daa218f01a8e798d7cda93b05e36e8..08f5da93b6f516ae497928cec53920ef28e3322f 100644 (file)
@@ -132,7 +132,7 @@ static int parse_config(int argc, char **argv, struct config *cfg)
                        cfg->fmt = optarg;
                        break;
                case 'i':
-                       cfg->idle_timeout = parse_period_or_die(optarg) / 1000;
+                       cfg->idle_timeout = parse_period_or_die(optarg);
                        break;
                case 'n':
                        cfg->events_wanted = parse_uint_or_die(optarg);
@@ -374,6 +374,7 @@ int main(int argc, char **argv)
        int i, j, ret, events_done = 0, evtype;
        struct line_resolver *resolver;
        struct gpiod_info_event *event;
+       struct timespec idle_timeout;
        struct gpiod_chip **chips;
        struct gpiod_chip *chip;
        struct pollfd *pollfds;
@@ -419,10 +420,17 @@ int main(int argc, char **argv)
        if (cfg.banner)
                print_banner(argc, argv);
 
+       if (cfg.idle_timeout > 0) {
+               idle_timeout.tv_sec = cfg.idle_timeout / 1000000;
+               idle_timeout.tv_nsec =
+                               (cfg.idle_timeout % 1000000) * 1000;
+       }
+
        for (;;) {
                fflush(stdout);
 
-               ret = poll(pollfds, resolver->num_chips, cfg.idle_timeout);
+               ret = ppoll(pollfds, resolver->num_chips,
+                           cfg.idle_timeout > 0 ? &idle_timeout : NULL, NULL);
                if (ret < 0)
                        die_perror("error polling for events");