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>
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index dc6ccaa..78b1610 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -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;