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:
parent
fe473123ba
commit
4e88b86cc8
|
@ -318,6 +318,34 @@ static int config_list(uint32_t key, GVariant **data,
|
||||||
return ret;
|
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)
|
static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
|
||||||
{
|
{
|
||||||
struct dev_context *devc;
|
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)
|
if (sdi->status != SR_ST_ACTIVE)
|
||||||
return SR_ERR_DEV_CLOSED;
|
return SR_ERR_DEV_CLOSED;
|
||||||
|
|
||||||
|
if (dev_acquisition_open(sdi))
|
||||||
|
return SR_ERR;
|
||||||
|
|
||||||
devc = sdi->priv;
|
devc = sdi->priv;
|
||||||
devc->samples_read = 0;
|
devc->samples_read = 0;
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ struct channel_group_priv {
|
||||||
|
|
||||||
struct channel_priv {
|
struct channel_priv {
|
||||||
int ch_type;
|
int ch_type;
|
||||||
|
int fd;
|
||||||
struct channel_group_priv *probe;
|
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)
|
static float read_sample(struct sr_channel *ch)
|
||||||
{
|
{
|
||||||
struct channel_priv *chp;
|
struct channel_priv *chp;
|
||||||
char path[64], *file, buf[16];
|
char buf[16];
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
int fd;
|
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;
|
chp = ch->priv;
|
||||||
|
|
||||||
switch (chp->ch_type) {
|
switch (chp->ch_type) {
|
||||||
|
@ -508,27 +531,31 @@ static float read_sample(struct sr_channel *ch)
|
||||||
case TEMP_OUT: file = "temp2_input"; break;
|
case TEMP_OUT: file = "temp2_input"; break;
|
||||||
default:
|
default:
|
||||||
sr_err("Invalid channel type: %d.", chp->ch_type);
|
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",
|
snprintf(path, sizeof(path), "/sys/class/hwmon/hwmon%d/%s",
|
||||||
chp->probe->hwmon_num, file);
|
chp->probe->hwmon_num, file);
|
||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
sr_err("Error opening %s: %s", path, strerror(errno));
|
sr_err("Error opening %s: %s", path, strerror(errno));
|
||||||
ch->enabled = FALSE;
|
ch->enabled = FALSE;
|
||||||
return -1.0;
|
return SR_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = read(fd, buf, sizeof(buf));
|
chp->fd = fd;
|
||||||
close(fd);
|
|
||||||
if (len < 0) {
|
|
||||||
sr_err("Error reading from %s: %s", path, strerror(errno));
|
|
||||||
ch->enabled = FALSE;
|
|
||||||
return -1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
SR_PRIV int bl_acme_receive_data(int fd, int revents, void *cb_data)
|
||||||
|
|
|
@ -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_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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue