From e467ba95b017924b06f2f52a73ab5380d553543a Mon Sep 17 00:00:00 2001 From: Yongcong Du Date: Sat, 7 Jul 2012 21:52:56 +0800 Subject: [PATCH] cpuidle: add stats reporting support Signed-off-by: Fredrik Holmqvist --- headers/os/drivers/cpuidle.h | 9 +++++ src/add-ons/kernel/drivers/cpuidle/Jamfile | 2 + .../kernel/drivers/cpuidle/cpuidle.cpp | 39 +++++++++++++++++-- src/add-ons/kernel/idle/generic/cpuidle.cpp | 35 +++++++++++++++-- 4 files changed, 78 insertions(+), 7 deletions(-) diff --git a/headers/os/drivers/cpuidle.h b/headers/os/drivers/cpuidle.h index 7234429283..ed79be9622 100644 --- a/headers/os/drivers/cpuidle.h +++ b/headers/os/drivers/cpuidle.h @@ -44,6 +44,15 @@ struct CpuidleModuleInfo { }; +struct GenCpuidle { + module_info info; + int32 (*GetIdleStateCount)(void); + char * (*GetIdleStateName)(int32 state); + void (*GetIdleStateInfo)(int32 cpu, int32 state, + CpuidleStat *stat); +}; + + #ifdef __cplusplus } #endif diff --git a/src/add-ons/kernel/drivers/cpuidle/Jamfile b/src/add-ons/kernel/drivers/cpuidle/Jamfile index 50b92909b1..ce5f450017 100644 --- a/src/add-ons/kernel/drivers/cpuidle/Jamfile +++ b/src/add-ons/kernel/drivers/cpuidle/Jamfile @@ -1,5 +1,7 @@ SubDir HAIKU_TOP src add-ons kernel drivers cpuidle ; +UsePrivateKernelHeaders ; + KernelAddon cpuidle : cpuidle.cpp ; diff --git a/src/add-ons/kernel/drivers/cpuidle/cpuidle.cpp b/src/add-ons/kernel/drivers/cpuidle/cpuidle.cpp index 9440358dfe..82110c9253 100644 --- a/src/add-ons/kernel/drivers/cpuidle/cpuidle.cpp +++ b/src/add-ons/kernel/drivers/cpuidle/cpuidle.cpp @@ -6,6 +6,10 @@ * Yongcong Du */ +#include +#include +#include + #include #include @@ -15,7 +19,7 @@ int32 api_version = B_CUR_DRIVER_API_VERSION; -CpuidleModuleInfo *sCpuidleModule; +static GenCpuidle *sGenCpuidle; static status_t cpuidle_open(const char *name, uint32 flags, void **cookie) @@ -49,7 +53,36 @@ cpuidle_ioctl(void *cookie, uint32 op, void *buffer, size_t length) static status_t cpuidle_read(void *cookie, off_t pos, void *buffer, size_t *length) { - *length = 0; + if (pos != 0) { + *length = 0; + return B_OK; + } + char *str = (char *)buffer; + size_t max_len = *length; + int32 stateCount = sGenCpuidle->GetIdleStateCount(); + int32 bytes = snprintf(str, max_len, "C-STATE COUNT: %"B_PRId32"\n", stateCount); + max_len-= bytes; + str += bytes; + int32 cpu = smp_get_num_cpus(); + + for (int32 i = 0; i < cpu; i++) { + bytes = snprintf(str, max_len, "CPU%"B_PRId32"\n", i); + max_len-= bytes; + str += bytes; + for (int32 j = 1; j < stateCount; j++) { + CpuidleStat stat; + bytes = snprintf(str, max_len, "%s\n", sGenCpuidle->GetIdleStateName(j)); + max_len-= bytes; + str += bytes; + sGenCpuidle->GetIdleStateInfo(i, j, &stat); + bytes = snprintf(str, max_len, "%lld %lldus\n", + stat.usageCount, stat.usageTime); + max_len-= bytes; + str += bytes; + } + } + *length = strlen((char *)buffer); + return B_OK; } @@ -102,7 +135,7 @@ init_driver(void) { status_t err; - err = get_module(B_CPUIDLE_MODULE_NAME, (module_info **)&sCpuidleModule); + err = get_module(B_CPUIDLE_MODULE_NAME, (module_info **)&sGenCpuidle); if (err != B_OK) { dprintf("can't load "B_CPUIDLE_MODULE_NAME"\n"); } diff --git a/src/add-ons/kernel/idle/generic/cpuidle.cpp b/src/add-ons/kernel/idle/generic/cpuidle.cpp index 4338a16835..041b7298ca 100644 --- a/src/add-ons/kernel/idle/generic/cpuidle.cpp +++ b/src/add-ons/kernel/idle/generic/cpuidle.cpp @@ -106,10 +106,37 @@ std_ops(int32 op, ...) } -static module_info sModule = { - B_CPUIDLE_MODULE_NAME, - 0, - std_ops +static char * +GetIdleStateName(int32 state) +{ + return sCpuidleModule->cStates[state].name; +} + + +static int32 +GetIdleStateCount(void) +{ + return sCpuidleModule->cStateCount; +} + + +static void +GetIdleStateInfo(int32 cpu, int32 state, CpuidleStat *stat) +{ + memcpy(stat, &sPerCPU[cpu].stats[state], sizeof(CpuidleStat)); +} + + +static GenCpuidle sModule = { + { + B_CPUIDLE_MODULE_NAME, + 0, + std_ops + }, + + GetIdleStateCount, + GetIdleStateName, + GetIdleStateInfo };