]> git.itanic.dy.fi Git - rrdd/commitdiff
onewire_parser: Implement simultaneous reading
authorTimo Kokkonen <timo.t.kokkonen@iki.fi>
Thu, 22 Aug 2019 18:27:20 +0000 (21:27 +0300)
committerTimo Kokkonen <timo.t.kokkonen@iki.fi>
Thu, 22 Aug 2019 18:27:20 +0000 (21:27 +0300)
DS18S20 sensors support simultaneous reading (not if parasitic
powered). This speeds up reading of multiple sensors massively, as the
lengthy conversion is done by all sensors at the same time.

But it does not work unless explicitly started. Also we don't want to
re-start the procedure after each sensor, as that would be as slow as
reading one by one.

Thus, we add a global shared timestamp that gets set once we read the
first sensor. After that, we have 10 second time to read the rest of
the sensors until we set it again. This should be more than enough
time to read large number of sensors in very short time doing only one
parallel conversion.

Signed-off-by: Timo Kokkonen <timo.t.kokkonen@iki.fi>
onewire_parser.c

index e129e5c5e78efbcf47be588656d5abbc5af1c9bd..07d359b7c8dadf2c43035600816b2c0b5e1d1fd3 100644 (file)
@@ -5,6 +5,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <math.h>
+#include <time.h>
 
 #include "parser.h"
 #include "debug.h"
@@ -189,6 +190,52 @@ out_close:
        return ret;
 }
 
+static void enable_simultaneous_reading(const char *mountpoint)
+{
+       static time_t last_simultaneous;
+       static struct mutex lock = {
+               .lock = PTHREAD_MUTEX_INITIALIZER,
+       };
+
+       time_t now = time(0);
+       int fd;
+       int ret;
+       char path[4096];
+       char one = '1';
+
+       mutex_lock(&lock);
+       /* Arbitrary 10 second limit between simultaneous reads */
+       if (now < last_simultaneous + 10) {
+               mutex_unlock(&lock);
+               return;
+       }
+
+       last_simultaneous = now;
+       mutex_unlock(&lock);
+
+       /*
+        * We only protect setting the variable. From now on we have
+        * 10 seconds time until we could race writing multiple times
+        * to this file. If that happens, well, can't help it..
+        */
+
+       strncpy(path, mountpoint, sizeof(path) - 1);
+       strncat(path, "/simultaneous/temperature", sizeof(path) - 1);
+       path[sizeof(path) - 1 ] = '\0';
+
+       fd = open(path, O_WRONLY);
+       if (path < 0) {
+               pr_err("Failed to open %s for writing: %m\n", path);
+               return;
+       }
+
+       ret = write(fd, &one, 1);
+       if (ret < 0)
+               pr_warn("Failed to write to %s: %m\n", path);
+
+       close(fd);
+}
+
 static int is_mount_point(const char *str)
 {
        /*
@@ -258,6 +305,9 @@ undefined:
 
                parse_opts(parser_data[i], ow_path, sizeof(ow_path), &offset);
 
+               if (is_mountpoint)
+                       enable_simultaneous_reading(mount_point);
+
                while (1) {
                        int j;
                        char *tmp2;