cpu : provide utime and stime instead of fg and bg time 95/225095/4
authorKichan Kwon <k_c.kwon@samsung.com>
Mon, 17 Feb 2020 09:04:19 +0000 (18:04 +0900)
committerKichan Kwon <k_c.kwon@samsung.com>
Wed, 4 Mar 2020 06:25:13 +0000 (15:25 +0900)
Change-Id: Ic23a521b8e511a1bd086aff085627a4994f41cd2
Signed-off-by: Kichan Kwon <k_c.kwon@samsung.com>
plugin/common/include/bm_plugin_interface.h
plugin/cpu/src/bm_cpu_plugin.c

index 285c4f7..abbd83e 100644 (file)
@@ -110,9 +110,8 @@ typedef struct {
  * structure for "cpu" feature data.
  */
 typedef struct {
-       uint cpuTicks;                  /**< CPU Usage during the session */
-       uint cpuTimeBackground;         /**< Time spent in Background State average operating frequency will be used to calculate the power */
-       uint cpuTimeForeground;         /**< Time spent in Foreground state average operating frequency will be used to calculate the power */
+       uint utime;             /**< Total time in milliseconds during which CPU runs in user mode */
+       uint stime;             /**< Total time in milliseconds during which CPU runs in kernel mode */
        GSList *atm_list;               /**< application time map('app_time_map_st1') list for all active applications between start & stop */
        GSList *cpu_data_list;          /**< list of nodes of 'bm_cpu_st' for next consecutive sessions */
 } bm_cpu_st;
index 773c6f3..b3428c7 100644 (file)
 #include "bm_cpu_util.h"
 #include "bm_log.h"
 
-enum heart_cpu_status {
-       SERVICE = 0,
-       FOREG = 1,
-       BACKG = 2,
-};
+#define JIFFY_TO_MS_FACTOR 10  // 1000 / 100
+#define JIFFY_TO_MS(x) ((x) >= UINT_MAX / JIFFY_TO_MS_FACTOR ? UINT_MAX : (x) * JIFFY_TO_MS_FACTOR)
 
 struct app_status {
        pid_t pid;
-       time_t last_checkpoint; // Need to get usage from this time
        time_t used_time;       // utime + stime
-       enum heart_cpu_status last_status;
+};
+
+struct cpu_time {
+       uint utime;
+       uint stime;
 };
 
 static struct timeval last_requested_time;
+static struct cpu_time last_cpu_time;
 
 static GDBusConnection *dbus_connection;
 static GHashTable *running_app_list;   // Key(appid), Val(app_status)
@@ -80,6 +81,28 @@ bool is_running_app(const char *appid)
        return is_running;
 }
 
+int get_cpu_time(struct cpu_time *cpu_time)
+{
+       int ret;
+       FILE *fp = NULL;
+
+       fp = fopen("/proc/stat", "r");
+       if (!fp) {
+               _E("fopen failed : %m");
+               return errno;
+       }
+
+       ret = fscanf(fp, "%*s %u %*s %u", &(cpu_time->utime), &(cpu_time->stime));
+       fclose(fp);
+
+       if (ret < 2) {
+               _E("fscanf failed (%d)", ret);
+               return EIO;
+       }
+
+       return 0;
+}
+
 int deinit()
 {
        ENTER;
@@ -102,6 +125,7 @@ int init()
 {
        ENTER;
 
+       int ret;
        GError *g_err = NULL;
 
        if (gettimeofday(&last_requested_time, NULL) != 0) {
@@ -109,6 +133,12 @@ int init()
                goto failed;
        }
 
+       ret = get_cpu_time(&last_cpu_time);
+       if (ret != 0) {
+               _E("Failed to get CPU time (%d)", ret);
+               goto failed;
+       }
+
        dbus_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &g_err);
        if (!dbus_connection) {
                _E("g_bus_get_sync failed : %s", g_err->message ? g_err->message : NULL);
@@ -142,6 +172,7 @@ int get_feature_data(bm_data_h *handle, bm_plugin_data_type_e type)
        bm_cpu_st *usage = NULL;
 
        struct timeval tv;
+       struct cpu_time cur_cpu_time;
 
        GError *g_err = NULL;
        GDBusMessage *msg_req, *msg_reply;
@@ -152,7 +183,6 @@ int get_feature_data(bm_data_h *handle, bm_plugin_data_type_e type)
        char query[128];
 
        /* DB row */
-       unsigned int time;
        const char *appid;
        const char *data;
        unsigned int utime, stime, pid, status;
@@ -183,6 +213,30 @@ int get_feature_data(bm_data_h *handle, bm_plugin_data_type_e type)
                return BM_PLUGIN_ERROR_OUT_OF_MEMORY;
        }
 
+       /* Get total CPU time */
+       ret = get_cpu_time(&cur_cpu_time);
+       if (ret != 0) {
+               _E("Failed to get CPU time (%d)", ret);
+
+               EXIT;
+               return BM_PLUGIN_ERROR_NO_DATA;
+       }
+
+       /* Check total CPU usage */
+       if (cur_cpu_time.utime < last_cpu_time.utime || cur_cpu_time.stime < last_cpu_time.stime) {
+               _E("Negative CPU usage. Nothing to return");
+
+               EXIT;
+               return BM_PLUGIN_ERROR_NO_DATA;
+       }
+
+       if (cur_cpu_time.utime == last_cpu_time.utime && cur_cpu_time.stime == last_cpu_time.stime) {
+               _I("System doesn't use CPU. Nothing to return");
+
+               EXIT;
+               return BM_PLUGIN_ERROR_NO_DATA;
+       }
+
        /* Request for resourced to update HEART-CPU DB */
        msg_req = g_dbus_message_new_method_call(
                        "org.tizen.resourced",
@@ -239,17 +293,22 @@ int get_feature_data(bm_data_h *handle, bm_plugin_data_type_e type)
                return BM_PLUGIN_ERROR_OUT_OF_MEMORY;
        }
 
+       /* Update total CPU time */
+       usage->utime = JIFFY_TO_MS(cur_cpu_time.utime - last_cpu_time.utime);
+       usage->stime = JIFFY_TO_MS(cur_cpu_time.stime - last_cpu_time.stime);
+
+       _D("Total CPU usage : %u", JIFFY_TO_MS(usage->utime + usage->stime));
+
        /* Read data from HEART-CPU DB */
        _I("Gather CPU usage : %ld ~ %ld", last_requested_time.tv_sec, tv.tv_sec);
-       snprintf(query, 128, "SELECT time,appid,data FROM cpu WHERE time >= %ld", last_requested_time.tv_sec);
+       snprintf(query, 128, "SELECT appid,data FROM cpu WHERE time >= %ld", last_requested_time.tv_sec);
        ret = sqlite3_prepare_v2(db, query, -1, &stmt, 0);
        while (sqlite3_step(stmt) == SQLITE_ROW) {
-               time = sqlite3_column_int(stmt, 0);
-               appid = (const char *)sqlite3_column_text(stmt, 1);
-               data = (const char *)sqlite3_column_text(stmt, 2);
+               appid = (const char *)sqlite3_column_text(stmt, 0);
+               data = (const char *)sqlite3_column_text(stmt, 1);
                sscanf(data, "%u %u %u %u", &utime, &stime, &pid, &status);
 
-               //_D("time(%u), appid(%s), utime(%u), stime(%u), pid(%u), status(%u)", time, appid, utime, stime, pid, status);
+               //_D("appid(%s), utime(%u), stime(%u), pid(%u), status(%u)", appid, utime, stime, pid, status);
 
                /* Ignore terminated app */
                if (!is_running_app(appid)) {
@@ -270,9 +329,7 @@ int get_feature_data(bm_data_h *handle, bm_plugin_data_type_e type)
                                goto clean_atm;
                        }
                        new_app_status->pid = pid;
-                       new_app_status->last_checkpoint = time;
-                       new_app_status->used_time = utime + stime;
-                       new_app_status->last_status = status;
+                       new_app_status->used_time = JIFFY_TO_MS(utime + stime);
                        g_hash_table_insert(running_app_list, g_strdup(appid), new_app_status);
                        continue;
                }
@@ -281,31 +338,18 @@ int get_feature_data(bm_data_h *handle, bm_plugin_data_type_e type)
                if (app_status->pid != pid) {
                        _D("%s is restarted", appid);
                        app_status->pid = pid;
-                       app_status->last_checkpoint = time;
-                       app_status->used_time = utime + stime;
-                       app_status->last_status = status;
+                       app_status->used_time = JIFFY_TO_MS(utime + stime);
                        continue;
                }
 
                /* Ignore CPU unused app */
-               elapsed = utime + stime - app_status->used_time;
+               elapsed = JIFFY_TO_MS(utime + stime) - app_status->used_time;
                if (elapsed <= 0) {
                        _D("%s doesn't use CPU. Ignore it", appid);
                        continue;
                }
 
-               /* Accumulate used time */
-               _D("%s uses CPU (+%d)", appid, elapsed);
-               usage->cpuTicks += elapsed;
-               switch (app_status->last_status) {
-               case FOREG:
-                       usage->cpuTimeForeground += elapsed;
-                       break;
-               case BACKG:
-               case SERVICE:
-                       usage->cpuTimeBackground += elapsed;
-                       break;
-               }
+               _D("%s uses CPU (+%d ms)", appid, elapsed);
 
                /* Insert the app using CPU in the ATM list */
                if (!g_slist_find_custom(usage->atm_list, appid, find_app_time)) {
@@ -321,15 +365,12 @@ int get_feature_data(bm_data_h *handle, bm_plugin_data_type_e type)
                                ret = BM_PLUGIN_ERROR_OUT_OF_MEMORY;
                                goto clean_atm;
                        }
-                       app_time_map->time = tv.tv_sec - app_status->last_checkpoint;
-                       if (app_time_map->time <= 0)
-                               app_time_map->time = 1;
+                       app_time_map->time = elapsed;
                        usage->atm_list = g_slist_append(usage->atm_list, app_time_map);
                }
 
                /* Update app status */
-               app_status->used_time = utime + stime;
-               app_status->last_status = status;
+               app_status->used_time += elapsed;
        }
 
        /* Update all running apps with current value */
@@ -352,27 +393,15 @@ int get_feature_data(bm_data_h *handle, bm_plugin_data_type_e type)
                        continue;
                }
 
-               app_status->last_checkpoint = tv.tv_sec;
-
                /* Ignore CPU unused app */
-               elapsed = cpu_usage->utime + cpu_usage->stime - app_status->used_time;
+               elapsed = JIFFY_TO_MS(cpu_usage->utime + cpu_usage->stime) - app_status->used_time;
+               free(cpu_usage);
                if (elapsed <= 0) {
                        _D("%s doesn't use CPU. Ignore it", appid);
                        continue;
                }
 
-               /* Update CPU time */
-               _D("%s uses CPU (+%d)", appid, elapsed);
-               usage->cpuTicks += elapsed;
-               switch (app_status->last_status) {
-               case FOREG:
-                       usage->cpuTimeForeground += elapsed;
-                       break;
-               case BACKG:
-               case SERVICE:
-                       usage->cpuTimeBackground += elapsed;
-                       break;
-               }
+               _D("%s uses CPU (+%d ms)", appid, elapsed);
 
                /* Insert the app using CPU in the ATM list */
                if (!g_slist_find_custom(usage->atm_list, appid, find_app_time)) {
@@ -388,21 +417,21 @@ int get_feature_data(bm_data_h *handle, bm_plugin_data_type_e type)
                                ret = BM_PLUGIN_ERROR_OUT_OF_MEMORY;
                                goto clean_atm;
                        }
-                       app_time_map->time = tv.tv_sec - last_requested_time.tv_sec;
-                       if (app_time_map->time <= 0)
-                               app_time_map->time = 1;
+                       app_time_map->time = elapsed;
                        usage->atm_list = g_slist_append(usage->atm_list, app_time_map);
                }
 
-               app_status->used_time = cpu_usage->utime + cpu_usage->stime;
-
-               free(cpu_usage);
+               app_status->used_time += elapsed;
        }
 
        /* Update last requested time */
        last_requested_time.tv_sec = tv.tv_sec;
        last_requested_time.tv_usec = tv.tv_usec;
 
+       /* Update last CPU time */
+       last_cpu_time.utime = cur_cpu_time.utime;
+       last_cpu_time.stime = cur_cpu_time.stime;
+
        /* Return result */
        usage_head->cpu_data_list = g_slist_append(usage_head->cpu_data_list, usage);
        *handle = usage_head;