1
0
Fork 0

perf pmu: Factor out scale conversion code

Move the scale factor parsing code to an own function to reuse it in an
upcoming patch.

v2: Return error in case strdup returns NULL.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/r/20170103150833.6694-2-andi@firstfloor.org
[ Keep returning -ENOMEM when strdup() fails in perf_pmu__parse_scale()/convert_scale() ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
zero-colors
Andi Kleen 2017-01-03 07:08:23 -08:00 committed by Arnaldo Carvalho de Melo
parent 5b485629ba
commit d02fc6bcd5
1 changed files with 38 additions and 32 deletions

View File

@ -94,6 +94,43 @@ static int pmu_format(const char *name, struct list_head *format)
return 0;
}
static int convert_scale(const char *scale, char **end, double *sval)
{
char *lc;
int ret = 0;
/*
* save current locale
*/
lc = setlocale(LC_NUMERIC, NULL);
/*
* The lc string may be allocated in static storage,
* so get a dynamic copy to make it survive setlocale
* call below.
*/
lc = strdup(lc);
if (!lc) {
ret = -ENOMEM;
goto out;
}
/*
* force to C locale to ensure kernel
* scale string is converted correctly.
* kernel uses default C locale.
*/
setlocale(LC_NUMERIC, "C");
*sval = strtod(scale, end);
out:
/* restore locale */
setlocale(LC_NUMERIC, lc);
free(lc);
return ret;
}
static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
{
struct stat st;
@ -101,7 +138,6 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *
char scale[128];
int fd, ret = -1;
char path[PATH_MAX];
char *lc;
snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
@ -121,37 +157,7 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *
else
scale[sret] = '\0';
/*
* save current locale
*/
lc = setlocale(LC_NUMERIC, NULL);
/*
* The lc string may be allocated in static storage,
* so get a dynamic copy to make it survive setlocale
* call below.
*/
lc = strdup(lc);
if (!lc) {
ret = -ENOMEM;
goto error;
}
/*
* force to C locale to ensure kernel
* scale string is converted correctly.
* kernel uses default C locale.
*/
setlocale(LC_NUMERIC, "C");
alias->scale = strtod(scale, NULL);
/* restore locale */
setlocale(LC_NUMERIC, lc);
free(lc);
ret = 0;
ret = convert_scale(scale, NULL, &alias->scale);
error:
close(fd);
return ret;