From: Youngjae Cho Date: Thu, 21 Jan 2021 09:42:32 +0000 (+0900) Subject: Support gpu, gem, swap memory usage information X-Git-Tag: submit/tizen/20210217.044338^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F96%2F251996%2F13;p=platform%2Fcore%2Fapi%2Fruntime-info.git Support gpu, gem, swap memory usage information Change-Id: Ic742215d586a1f7c7cd92ffe5a44c79136a9b0fb Signed-off-by: Youngjae Cho --- diff --git a/CMakeLists.txt b/CMakeLists.txt index ccd525b..4b27def 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(INC_DIR include) INCLUDE_DIRECTORIES(${INC_DIR}) -SET(requires "dlog vconf capi-base-common capi-system-info glib-2.0 gio-2.0") +SET(requires "dlog vconf capi-base-common capi-system-info glib-2.0 gio-2.0 hal-api-common hal-api-device") SET(pc_requires "capi-base-common") INCLUDE(FindPkgConfig) diff --git a/include/runtime_info-internal.h b/include/runtime_info-internal.h new file mode 100644 index 0000000..460f9c1 --- /dev/null +++ b/include/runtime_info-internal.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TIZEN_SYSTEM_RUNTIME_INFO_INTERNAL_H__ +#define __TIZEN_SYSTEM_RUNTIME_INFO_INTERNAL_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef enum { + RUNTIME_INFO_PROC_MEMORY_VSZ = 100, /**< Virtual memory size (KiB) */ + RUNTIME_INFO_PROC_MEMORY_RSS = 200, /**< Resident set size (KiB) */ + RUNTIME_INFO_PROC_MEMORY_PSS = 300, /**< Proportional set size (KiB) */ + RUNTIME_INFO_PROC_MEMORY_GPU = 400, /**< GPU memory size (KiB) */ + RUNTIME_INFO_PROC_MEMORY_GEM_RSS = 500, /**< Resident set size in graphic execution manager (KiB) */ + RUNTIME_INFO_PROC_MEMORY_SWAP = 600, /**< SWAP memory size (KiB) */ + RUNTIME_INFO_PROC_MEMORY_SHARED_CLEAN = 700, /**< Not modified and mapped by other processes (KiB) */ + RUNTIME_INFO_PROC_MEMORY_SHARED_DIRTY = 800, /**< Modified and mapped by other processes (KiB) */ + RUNTIME_INFO_PROC_MEMORY_PRIVATE_CLEAN = 900, /**< Not modified and available only to that process (KiB) */ + RUNTIME_INFO_PROC_MEMORY_PRIVATE_DIRTY = 1000,/**< Modified and available only to that process (KiB) */ +} process_memory_info_key_e; + +int runtime_info_get_process_memory_value_int(int *pid, int size, process_memory_info_key_e key, int **info); + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_SYSTEM_RUNTIME_INFO_INTERNAL_H__ */ diff --git a/packaging/capi-system-runtime-info.spec b/packaging/capi-system-runtime-info.spec index bab433b..39500d6 100644 --- a/packaging/capi-system-runtime-info.spec +++ b/packaging/capi-system-runtime-info.spec @@ -13,6 +13,8 @@ BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(hal-api-common) +BuildRequires: pkgconfig(hal-api-device) Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig @@ -82,7 +84,8 @@ install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj %{_libdir}/lib*.so.* %files devel -%{_includedir}/system/*.h +%{_includedir}/system/runtime_info.h +%{_includedir}/system/runtime_info-internal.h %{_libdir}/pkgconfig/*.pc %{_libdir}/lib*.so 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;