X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fruntime_info_usage.c;h=dacf4a58635f93aa8a6130a7d7c40bbf23073443;hb=1b512c54b2d9eccea1288ff2e2f9064193d118bd;hp=19f632069cdeeb4336b9cc065386d0462b3422ac;hpb=85a5849583f5792ea1820bd5bb30ff640957dd4b;p=platform%2Fcore%2Fapi%2Fruntime-info.git diff --git a/src/runtime_info_usage.c b/src/runtime_info_usage.c index 19f6320..dacf4a5 100644 --- a/src/runtime_info_usage.c +++ b/src/runtime_info_usage.c @@ -19,15 +19,19 @@ #include #include #include +#include #include #include #include +#include #include #include +#include + #define RESOURCED_BUS_NAME "org.tizen.resourced" #define RESOURCED_USAGE_OBJECT_NAME "/Org/Tizen/ResourceD/Process" #define RESOURCED_USAGE_INTERFACE_NAME "org.tizen.resourced.process" @@ -38,6 +42,7 @@ typedef enum { USAGE_TYPE_PROCESS_CPU, USAGE_TYPE_APP_MEMORY, USAGE_TYPE_APP_CPU, + USAGE_TYPE_PROCESS_SWAP, } runtime_info_usage_type_e; typedef struct { @@ -51,6 +56,7 @@ static const runtime_info_dbus_info_s dbus_info[] = { { "ProcCpuUsage", "process cpu" }, { "GetMemoryList", "all apps memory" }, { "GetCpuList", "all apps cpu" }, + { "ProcSwapUsage", "process swap" }, }; #define ULONGtoINT(ulong) (int)(MIN((ulong), INT_MAX)) @@ -93,6 +99,7 @@ static GVariant *runtime_info_dbus_request_usage_info(runtime_info_usage_type_e switch (type) { case USAGE_TYPE_PROCESS_MEMORY: case USAGE_TYPE_PROCESS_CPU: + case USAGE_TYPE_PROCESS_SWAP: if (!pid || size <= 0) { //LCOV_EXCL_START : system error _E("INVALID_PARAMETER(0x%08x): pid list cannot be null", @@ -126,6 +133,7 @@ static GVariant *runtime_info_dbus_request_usage_info(runtime_info_usage_type_e switch (type) { case USAGE_TYPE_PROCESS_MEMORY: case USAGE_TYPE_PROCESS_CPU: + case USAGE_TYPE_PROCESS_SWAP: _D("Process %d: received query to get %s usage of %d processes", getpid(), dbus_info[type].caption, size); args_in = runtime_info_append_args(pid, size); @@ -382,6 +390,221 @@ API int runtime_info_get_process_memory_info(int *pid, int size, process_memory_ return RUNTIME_INFO_ERROR_NONE; } +static runtime_info_error_e hal_error_to_runtime_info_error(int err) +{ + switch (err) { + case 0: + return RUNTIME_INFO_ERROR_NONE; + case -EINVAL: + return RUNTIME_INFO_ERROR_INVALID_PARAMETER; + case -ENOMEM: + return RUNTIME_INFO_ERROR_OUT_OF_MEMORY; + case -EIO: + case -ENOENT: + return RUNTIME_INFO_ERROR_IO_ERROR; + case -EPERM: + case -EACCES: + return RUNTIME_INFO_ERROR_PERMISSION_DENIED; + case -ENOTSUP: + return RUNTIME_INFO_ERROR_NOT_SUPPORTED; + default: + // TODO: what is the runtime-info error for this default case? + return RUNTIME_INFO_ERROR_NO_DATA; + } +} + +static int get_process_memory_info_direct(int *pid, int size, process_memory_info_key_e key, int **info) +{ + int ret, i; + struct gpu_info gpu_info; + struct gem_info gem_info; + int *result; + int err = RUNTIME_INFO_ERROR_NONE; + + result = (int *)calloc(size, sizeof(int)); + if (!result) { + err = RUNTIME_INFO_ERROR_OUT_OF_MEMORY; + goto out; + } + + switch (key) { + case RUNTIME_INFO_PROC_MEMORY_GPU: + for (i = 0; i < size; ++i) { + ret = hal_device_memory_get_gpu_info(pid[i], &gpu_info); + if (ret != 0) { + err = hal_error_to_runtime_info_error(ret); + goto out; + } + result[i] = gpu_info.used_pages; + } + *info = result; + break; + case RUNTIME_INFO_PROC_MEMORY_GEM_RSS: + for (i = 0; i < size; ++i) { + ret = hal_device_memory_get_gem_info(pid[i], &gem_info); + if (ret != 0) { + err = hal_error_to_runtime_info_error(ret); + goto out; + } + result[i] = gem_info.rss; + } + *info = result; + break; + default: + err = RUNTIME_INFO_ERROR_INVALID_PARAMETER; + break; + } + +out: + if (err != RUNTIME_INFO_ERROR_NONE) + free(result); + + return err; +} + +static int get_process_memory_swap_info(int *pid, int size, int **info) +{ + int i, temp; + int error; + GVariant *usages; + GVariantIter iter; + + if (!pid || size <= 0) { + _E("INVALID_PARAMETER(0x%08x) : invalid input param", + RUNTIME_INFO_ERROR_INVALID_PARAMETER); + return RUNTIME_INFO_ERROR_INVALID_PARAMETER; + } + + if (!info) { + _E("INVALID_PARAMETER(0x%08x) : invalid output param", + RUNTIME_INFO_ERROR_INVALID_PARAMETER); + return RUNTIME_INFO_ERROR_INVALID_PARAMETER; + } + + *info = NULL; + + /* Get the needed information from resourced daemon using dbus */ + usages = runtime_info_dbus_request_usage_info(USAGE_TYPE_PROCESS_SWAP, pid, size, &error); + if (!usages) { + //LCOV_EXCL_START : system error + _E("DBUS_METHOD_CALL: call to resourced not successful"); + return error; + //LCOV_EXCL_STOP + } + + /* Check whether the received usage has expected format or not */ + if (g_strcmp0(g_variant_get_type_string(usages), "a(i)") || + g_variant_n_children(usages) != size) { + //LCOV_EXCL_START : system error + _E("DBUS_METHOD_CALL: received dbus message is not in expected format"); + g_variant_unref(usages); + return RUNTIME_INFO_ERROR_REMOTE_IO; + //LCOV_EXCL_STOP + } + + /* Populate the entries of info array using the data received from resourced */ + *info = (int *)malloc(size * sizeof(int)); + if (!(*info)) { + _E("OUT_OF_MEMORY(0x%08x)", RUNTIME_INFO_ERROR_OUT_OF_MEMORY); + g_variant_unref(usages); + return RUNTIME_INFO_ERROR_OUT_OF_MEMORY; + } + + g_variant_iter_init(&iter, usages); + for (i = 0; i < size; i++) { + g_variant_iter_next(&iter, "(i)", &temp); + (*info)[i] = temp; + } + + g_variant_unref(usages); + + return RUNTIME_INFO_ERROR_NONE; +} + +static int get_process_memory_info(int *pid, int size, process_memory_info_key_e key, int **info) +{ + int i; + int ret; + int *result; + process_memory_info_s *base = NULL; + + ret = RUNTIME_INFO_ERROR_NONE; + + result = (int *)calloc(size, sizeof(int)); + if (!result) { + ret = RUNTIME_INFO_ERROR_OUT_OF_MEMORY; + goto out; + } + + ret = runtime_info_get_process_memory_info(pid, size, &base); + if (ret != RUNTIME_INFO_ERROR_NONE) + goto out; + + switch (key) { + case RUNTIME_INFO_PROC_MEMORY_VSZ: + for (i = 0; i < size; ++i) + result[i] = base[i].vsz; + break; + case RUNTIME_INFO_PROC_MEMORY_RSS: + for (i = 0; i < size; ++i) + result[i] = base[i].rss; + break; + case RUNTIME_INFO_PROC_MEMORY_PSS: + for (i = 0; i < size; ++i) + result[i] = base[i].pss; + break; + case RUNTIME_INFO_PROC_MEMORY_SHARED_CLEAN: + for (i = 0; i < size; ++i) + result[i] = base[i].shared_clean; + break; + case RUNTIME_INFO_PROC_MEMORY_SHARED_DIRTY: + for (i = 0; i < size; ++i) + result[i] = base[i].shared_dirty; + break; + case RUNTIME_INFO_PROC_MEMORY_PRIVATE_CLEAN: + for (i = 0; i < size; ++i) + result[i] = base[i].private_clean; + break; + case RUNTIME_INFO_PROC_MEMORY_PRIVATE_DIRTY: + for (i = 0; i < size; ++i) + result[i] = base[i].private_dirty; + break; + default: + ret = RUNTIME_INFO_ERROR_INVALID_PARAMETER; + goto out; + } + + *info = result; + +out: + if (ret != RUNTIME_INFO_ERROR_NONE) + free(result); + free(base); + + return ret; +} + +API int runtime_info_get_process_memory_value_int(int *pid, int size, process_memory_info_key_e key, int **info) +{ + switch (key) { + case RUNTIME_INFO_PROC_MEMORY_GPU: + case RUNTIME_INFO_PROC_MEMORY_GEM_RSS: + return get_process_memory_info_direct(pid, size, key, info); + case RUNTIME_INFO_PROC_MEMORY_SWAP: + return get_process_memory_swap_info(pid, size, info); + case RUNTIME_INFO_PROC_MEMORY_VSZ: + case RUNTIME_INFO_PROC_MEMORY_RSS: + case RUNTIME_INFO_PROC_MEMORY_PSS: + case RUNTIME_INFO_PROC_MEMORY_SHARED_CLEAN: + case RUNTIME_INFO_PROC_MEMORY_SHARED_DIRTY: + case RUNTIME_INFO_PROC_MEMORY_PRIVATE_CLEAN: + case RUNTIME_INFO_PROC_MEMORY_PRIVATE_DIRTY: + return get_process_memory_info(pid, size, key, info); + default: + return RUNTIME_INFO_ERROR_INVALID_PARAMETER; + } +} + API int runtime_info_get_cpu_usage(runtime_cpu_usage_s *usage) { FILE *cpuinfo_fp;