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>
This commit is contained in:
parent
5b485629ba
commit
d02fc6bcd5
|
@ -94,6 +94,43 @@ static int pmu_format(const char *name, struct list_head *format)
|
||||||
return 0;
|
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)
|
static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
@ -101,7 +138,6 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *
|
||||||
char scale[128];
|
char scale[128];
|
||||||
int fd, ret = -1;
|
int fd, ret = -1;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
char *lc;
|
|
||||||
|
|
||||||
snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
|
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
|
else
|
||||||
scale[sret] = '\0';
|
scale[sret] = '\0';
|
||||||
|
|
||||||
/*
|
ret = convert_scale(scale, NULL, &alias->scale);
|
||||||
* 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;
|
|
||||||
error:
|
error:
|
||||||
close(fd);
|
close(fd);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in a new issue