]> sigrok.org Git - libsigrok.git/commitdiff
baylibre-acme: Optimize reading of values from sysfs.
authorDaniel Lezcano <redacted>
Wed, 27 May 2015 18:22:02 +0000 (20:22 +0200)
committerBartosz Golaszewski <redacted>
Mon, 29 Jun 2015 14:07:52 +0000 (16:07 +0200)
Opening a file has a cost (security, allocation, syscalls). The
read_sample() function always does an open/read/close sequence.

In order to optimize that, let's open the file at the moment the
acquisition starts, close it when the acquisition stops and make
read_sample() only lseek() to the beginning of the file and read
the value.

Signed-off-by: Daniel Lezcano <redacted>
Signed-off-by: Bartosz Golaszewski <redacted>
src/hardware/baylibre-acme/api.c
src/hardware/baylibre-acme/protocol.c
src/hardware/baylibre-acme/protocol.h

index 6827a16bfe5da763756f34318856411f0f220ee8..c91a9063fdfe949091b5f5a1ce546076f7512eb5 100644 (file)
@@ -318,6 +318,34 @@ static int config_list(uint32_t key, GVariant **data,
        return ret;
 }
 
+static void dev_acquisition_close(const struct sr_dev_inst *sdi)
+{
+       GSList *chl;
+       struct sr_channel *ch;
+
+       for (chl = sdi->channels; chl; chl = chl->next) {
+               ch = chl->data;
+               bl_acme_close_channel(ch);
+       }
+}
+
+static int dev_acquisition_open(const struct sr_dev_inst *sdi)
+{
+       GSList *chl;
+       struct sr_channel *ch;
+
+       for (chl = sdi->channels; chl; chl = chl->next) {
+               ch = chl->data;
+               if (bl_acme_open_channel(ch)) {
+                       sr_err("Error opening channel %s", ch->name);
+                       dev_acquisition_close(sdi);
+                       return SR_ERR;
+               }
+       }
+
+       return 0;
+}
+
 static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
 {
        struct dev_context *devc;
@@ -327,6 +355,9 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
        if (sdi->status != SR_ST_ACTIVE)
                return SR_ERR_DEV_CLOSED;
 
+       if (dev_acquisition_open(sdi))
+               return SR_ERR;
+
        devc = sdi->priv;
        devc->samples_read = 0;
 
index f8fdb595435a21a49dc18fa6dcb03fcc9e16b331..dfd634bb380ee60a121b9b6f5205a5068b7f1fb4 100644 (file)
@@ -33,6 +33,7 @@ struct channel_group_priv {
 
 struct channel_priv {
        int ch_type;
+       int fd;
        struct channel_group_priv *probe;
 };
 
@@ -494,10 +495,32 @@ static float adjust_data(int val, int type)
 static float read_sample(struct sr_channel *ch)
 {
        struct channel_priv *chp;
-       char path[64], *file, buf[16];
+       char buf[16];
        ssize_t len;
        int fd;
 
+       chp = ch->priv;
+       fd = chp->fd;
+
+       lseek(fd, 0, SEEK_SET);
+
+       len = read(fd, buf, sizeof(buf));
+       if (len < 0) {
+               sr_err("Error reading from channel %s (hwmon: %s): %s",
+                       ch->name, chp->probe->hwmon_num, strerror(errno));
+               ch->enabled = FALSE;
+               return -1.0;
+       }
+
+       return adjust_data(strtol(buf, NULL, 10), chp->ch_type);
+}
+
+SR_PRIV int bl_acme_open_channel(struct sr_channel *ch)
+{
+       struct channel_priv *chp;
+       char path[64], *file;
+       int fd;
+
        chp = ch->priv;
 
        switch (chp->ch_type) {
@@ -508,27 +531,31 @@ static float read_sample(struct sr_channel *ch)
        case TEMP_OUT:  file = "temp2_input";   break;
        default:
                sr_err("Invalid channel type: %d.", chp->ch_type);
-               return -1.0;
+               return SR_ERR;
        }
 
        snprintf(path, sizeof(path), "/sys/class/hwmon/hwmon%d/%s",
                 chp->probe->hwmon_num, file);
+
        fd = open(path, O_RDONLY);
        if (fd < 0) {
                sr_err("Error opening %s: %s", path, strerror(errno));
                ch->enabled = FALSE;
-               return -1.0;
+               return SR_ERR;
        }
 
-       len = read(fd, buf, sizeof(buf));
-       close(fd);
-       if (len < 0) {
-               sr_err("Error reading from %s: %s", path, strerror(errno));
-               ch->enabled = FALSE;
-               return -1.0;
-       }
+       chp->fd = fd;
 
-       return adjust_data(strtol(buf, NULL, 10), chp->ch_type);
+       return 0;
+}
+
+SR_PRIV void bl_acme_close_channel(struct sr_channel *ch)
+{
+       struct channel_priv *chp;
+
+       chp = ch->priv;
+       close(chp->fd);
+       chp->fd = -1;
 }
 
 SR_PRIV int bl_acme_receive_data(int fd, int revents, void *cb_data)
index 13c00fe684679b9ec3aaeae9935909f11240447e..4600211b29b2fe79f16aec44c3ab2b5fe0f3c6d7 100644 (file)
@@ -98,4 +98,7 @@ SR_PRIV int bl_acme_set_power_off(const struct sr_channel_group *cg,
 
 SR_PRIV int bl_acme_receive_data(int fd, int revents, void *cb_data);
 
+SR_PRIV int bl_acme_open_channel(struct sr_channel *ch);
+
+SR_PRIV void bl_acme_close_channel(struct sr_channel *ch);
 #endif