[API-NEXT,v2,4/5] linux-generic: sysinfo: add API to get current CPU frequency

Message ID 1435833923-28361-5-git-send-email-hongbo.zhang@freescale.com
State New
Headers show

Commit Message

hongbo.zhang@freescale.com July 2, 2015, 10:45 a.m.
From: Hongbo Zhang <hongbo.zhang@linaro.org>

This patch add API to return the current frequency of the CPU on which
the thread is running.

Only x86 platform is now implemented, others are to be done.

Signed-off-by: Hongbo Zhang <hongbo.zhang@linaro.org>
---
 include/odp/api/system_info.h            |  7 ++++
 platform/linux-generic/odp_system_info.c | 58 ++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

Patch

diff --git a/include/odp/api/system_info.h b/include/odp/api/system_info.h
index 8627d97..3737aa0 100644
--- a/include/odp/api/system_info.h
+++ b/include/odp/api/system_info.h
@@ -38,6 +38,13 @@  uint64_t odp_sys_cpu_hz(void);
 uint64_t odp_sys_cpu_hz_amp(int cpu);
 
 /**
+ * CPU current frequency in Hz
+ *
+ * @return CPU current frequency in Hz, -1 on error
+ */
+uint64_t odp_sys_cpu_hz_current(void);
+
+/**
  * Huge page size in bytes
  *
  * @return Huge page size in bytes
diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c
index 00b8d4d..c275c5c 100644
--- a/platform/linux-generic/odp_system_info.c
+++ b/platform/linux-generic/odp_system_info.c
@@ -145,6 +145,43 @@  static int cpuinfo_x86(FILE *file, odp_system_info_t *sysinfo)
 	return 0;
 }
 
+static uint64_t arch_cpu_hz_current(void)
+{
+	char str[1024];
+	FILE *file;
+	int cpu_curr, cpu;
+	char *pos;
+	double mhz = 0.0;
+
+	file = fopen("/proc/cpuinfo", "rt");
+	cpu_curr = sched_getcpu();
+
+	/* find the correct processor instance */
+	while (fgets(str, sizeof(str), file) != NULL) {
+		pos = strstr(str, "processor");
+		if (pos) {
+			sscanf(pos, "processor : %d", &cpu);
+			if (cpu == cpu_curr)
+				break;
+		}
+	}
+
+	/* extract the cpu current speed */
+	while (fgets(str, sizeof(str), file) != NULL) {
+		pos = strstr(str, "cpu MHz");
+		if (pos) {
+			sscanf(pos, "cpu MHz : %lf", &mhz);
+			break;
+		}
+	}
+
+	fclose(file);
+	if (mhz)
+		return (uint64_t)(mhz * 1000000.0);
+
+	return -1;
+}
+
 #elif defined __arm__ || defined __aarch64__
 
 static int cpuinfo_arm(FILE *file ODP_UNUSED,
@@ -153,6 +190,11 @@  odp_system_info_t *sysinfo ODP_UNUSED)
 	return 0;
 }
 
+static uint64_t arch_cpu_hz_current(void)
+{
+	return -1;
+}
+
 #elif defined __OCTEON__
 
 static int cpuinfo_octeon(FILE *file, odp_system_info_t *sysinfo)
@@ -194,6 +236,12 @@  static int cpuinfo_octeon(FILE *file, odp_system_info_t *sysinfo)
 
 	return 0;
 }
+
+static uint64_t arch_cpu_hz_current(void)
+{
+	return -1;
+}
+
 #elif defined __powerpc__
 static int cpuinfo_powerpc(FILE *file, odp_system_info_t *sysinfo)
 {
@@ -235,6 +283,11 @@  static int cpuinfo_powerpc(FILE *file, odp_system_info_t *sysinfo)
 	return 0;
 }
 
+static uint64_t arch_cpu_hz_current(void)
+{
+	return -1;
+}
+
 #else
 	#error GCC target not found
 #endif
@@ -378,6 +431,11 @@  uint64_t odp_sys_cpu_hz_amp(int cpu)
 		return -1;
 }
 
+uint64_t odp_sys_cpu_hz_current(void)
+{
+	return arch_cpu_hz_current();
+}
+
 uint64_t odp_sys_huge_page_size(void)
 {
 	return odp_global_data.system_info.huge_page_size;