baylibre-acme: Optimize reading of values from sysfs.

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 <daniel.lezcano@free.fr>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This commit is contained in:
Daniel Lezcano 2015-05-27 20:22:02 +02:00 committed by Bartosz Golaszewski
parent fe473123ba
commit 4e88b86cc8
3 changed files with 72 additions and 11 deletions

View 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;

View 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)

View 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