#include <resource-monitor/resource-monitor.h>
struct system_resource_data {
- struct cpu_stat prev_avg;
- struct cpu_stat curr_avg;
-
int num_possible_cpus;
int num_online_cpus;
struct cpu_stat *prev_cpus;
total = (double)(diff.user + diff.system + diff.nice + diff.idle);
+ if (total < 1E-6)
+ return 0.0;
+
switch (id) {
case SYSTEM_ATTR_CPU_UTIL:
case SYSTEM_ATTR_PER_CPU_UTIL:
void *data)
{
struct system_resource_data *sysdata;
- double *util = (double *)data;
+ double util, sum = 0.0;
+ int i;
if (!res || !attr || !data)
return -EINVAL;
if (!sysdata)
return -EINVAL;
- *util = __calculate_cpu_util(attr->id, &sysdata->prev_avg, &sysdata->curr_avg);
- if (*util < 0) {
- _W("failed to calculate average cpu util (%s: %s)\n",
- get_resource_name(res), attr->name);
- *util = 0.0;
+ for (i = 0; i < sysdata->num_possible_cpus; i++) {
+ util = __calculate_cpu_util(attr->id,
+ &sysdata->prev_cpus[i],
+ &sysdata->curr_cpus[i]);
+ if (util < 0.0) {
+ _W("failed to calculate per-cpu util (%s: %s)\n",
+ get_resource_name(res), attr->name);
+ continue;
+ }
+
+ sum += util;
}
+ /*
+ * For offline cpus, it is reasonable to assume that the cpu utilization
+ * is 0%, so when calculating the average utilization, it is more
+ * accurate to average the number of possible cpus instead of the number
+ * of online cpus.
+ */
+ *(double *)data = sum / sysdata->num_possible_cpus;
+
return 0;
}
const char *res_name = get_resource_name(res);
int ret;
- /* Get the average cpu utilization of all cpus */
- memcpy(&sysdata->prev_avg, &sysdata->curr_avg, sizeof(sysdata->prev_avg));
- ret = kernel_get_total_cpu_stat(&sysdata->curr_avg);
- if (ret < 0) {
- _I("failed to calculate average cpu util (%s)\n", res_name);
- return ret;
- }
-
/* Get the per-cpu utilization */
memcpy(sysdata->prev_cpus, sysdata->curr_cpus,
sizeof(struct cpu_stat) * sysdata->num_possible_cpus);