cpuidle: add stats reporting support

Signed-off-by: Fredrik Holmqvist <fredrik.holmqvist@gmail.com>
This commit is contained in:
Yongcong Du 2012-07-07 21:52:56 +08:00 committed by Fredrik Holmqvist
parent 76877c9a51
commit e467ba95b0
4 changed files with 78 additions and 7 deletions

View File

@ -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

View File

@ -1,5 +1,7 @@
SubDir HAIKU_TOP src add-ons kernel drivers cpuidle ;
UsePrivateKernelHeaders ;
KernelAddon <driver>cpuidle :
cpuidle.cpp
;

View File

@ -6,6 +6,10 @@
* Yongcong Du <ycdu.vmcore@gmail.com>
*/
#include <stdio.h>
#include <string.h>
#include <smp.h>
#include <Drivers.h>
#include <KernelExport.h>
@ -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");
}

View File

@ -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
};