2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include <libsyscommon/dbus-system.h>
27 #include <runtime_info.h>
28 #include <runtime_info_private.h>
29 #include <runtime_info-internal.h>
33 #include <hal/device/hal-memory.h>
35 #define RESOURCED_BUS_NAME "org.tizen.resourced"
36 #define RESOURCED_USAGE_OBJECT_NAME "/Org/Tizen/ResourceD/Process"
37 #define RESOURCED_USAGE_INTERFACE_NAME "org.tizen.resourced.process"
38 #define DBUS_REPLY_TIMEOUT (120 * 1000)
41 USAGE_TYPE_PROCESS_MEMORY,
42 USAGE_TYPE_PROCESS_CPU,
43 USAGE_TYPE_APP_MEMORY,
45 USAGE_TYPE_PROCESS_SWAP,
46 } runtime_info_usage_type_e;
49 const char *method_name;
51 } runtime_info_dbus_info_s;
53 /* The index of this array must be matched with runtime_info_usage_type_e */
54 static const runtime_info_dbus_info_s dbus_info[] = {
55 { "ProcMemoryUsage", "process memory" },
56 { "ProcCpuUsage", "process cpu" },
57 { "GetMemoryList", "all apps memory" },
58 { "GetCpuList", "all apps cpu" },
59 { "ProcSwapUsage", "process swap" },
62 #define ULONGtoINT(ulong) (int)(MIN((ulong), INT_MAX))
64 /* ((val << 12) >> 10) = (val << 2) */
65 #define pagetoKiB(val) ((val) <= 0) ? 0 : (int)MIN(((long long)(val) << 2), INT_MAX)
67 /* Convert int array to GVariant("ai") */
68 static GVariant *runtime_info_append_args(int *args, int size)
70 GVariantBuilder builder, *sub_builder;
73 g_variant_builder_init(&builder, G_VARIANT_TYPE_TUPLE);
74 sub_builder = g_variant_builder_new(G_VARIANT_TYPE("ai"));
76 for (i = 0; i < size; i++)
77 g_variant_builder_add(sub_builder, "i", args[i]);
79 g_variant_builder_add_value(&builder, g_variant_new("ai", sub_builder));
80 g_variant_builder_unref(sub_builder);
82 return g_variant_builder_end(&builder);
85 /* Handler function which handles dbus related instructions
86 * Creates the method call to resourced and receives the reply (if successful)
87 * Return the received usage information (if received) else NULL to signify failed call to resourced
89 static GVariant *runtime_info_dbus_request_usage_info(runtime_info_usage_type_e type,
90 int *pid, int size, int *error)
92 GVariant *args_in = NULL;
93 GVariant *args_out = NULL;
98 case USAGE_TYPE_PROCESS_MEMORY:
99 case USAGE_TYPE_PROCESS_CPU:
100 case USAGE_TYPE_PROCESS_SWAP:
101 if (!pid || size <= 0) {
102 //LCOV_EXCL_START : system error
103 _E("INVALID_PARAMETER(0x%08x): pid list cannot be null",
104 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
106 *error = RUNTIME_INFO_ERROR_INVALID_PARAMETER;
111 case USAGE_TYPE_APP_MEMORY:
112 case USAGE_TYPE_APP_CPU:
114 //LCOV_EXCL_START : system error
115 _E("INVALID_PARAMETER(0x%08x): error parameter cannot be null",
116 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
122 //LCOV_EXCL_START : system error
123 _E("INVALID_PARAMETER(0x%08x): invalid type parameter",
124 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
125 *error = RUNTIME_INFO_ERROR_INVALID_PARAMETER;
130 /* Make argument for requesting */
132 case USAGE_TYPE_PROCESS_MEMORY:
133 case USAGE_TYPE_PROCESS_CPU:
134 case USAGE_TYPE_PROCESS_SWAP:
135 _D("Process %d: received query to get %s usage of %d processes",
136 getpid(), dbus_info[type].caption, size);
137 args_in = runtime_info_append_args(pid, size);
139 //LCOV_EXCL_START : system error
140 _E("DBUS_METHOD_CALL: not able to append pid array to message");
141 *error = RUNTIME_INFO_ERROR_IO_ERROR;
146 case USAGE_TYPE_APP_MEMORY:
147 case USAGE_TYPE_APP_CPU:
148 _D("Process %d: received query to get %s usage of all apps",
149 getpid(), dbus_info[type].caption);
154 _D("Process %d: Sending dbus message to resourced for %s info",
155 getpid(), dbus_info[type].caption);
156 args_out = dbus_handle_method_sync_with_reply_var(RESOURCED_BUS_NAME,
157 RESOURCED_USAGE_OBJECT_NAME,
158 RESOURCED_USAGE_INTERFACE_NAME,
159 dbus_info[type].method_name,
163 //LCOV_EXCL_START : system error
164 _E("DBUS_METHOD_CALL: not able to send message");
170 usage = g_variant_get_child_value(args_out, 0);
171 g_variant_unref(args_out);
176 static int runtime_info_get_all_apps_usage(runtime_info_usage_type_e type,
182 struct app_usages_s *usages;
187 _E("INVALID_PARAMETER(0x%08x) : invalid output param",
188 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
189 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
192 reply = runtime_info_dbus_request_usage_info(type, NULL, 0, &error);
194 //LCOV_EXCL_START : system error
195 _E("DBUS_METHOD_CALL: call to resourced not successful");
200 /* Check whether the received usage has expected format or not */
201 if (g_strcmp0(g_variant_get_type_string(reply), "a(su)")) {
202 //LCOV_EXCL_START : system error
203 _E("DBUS_METHOD_CALL: received dbus message is not in expected format");
204 g_variant_unref(reply);
205 return RUNTIME_INFO_ERROR_REMOTE_IO;
209 /* Populate the entries of info array using the data received from resourced */
210 len = g_variant_n_children(reply);
212 _E("NO_DATA(0x%08x) : there is no registered app", RUNTIME_INFO_ERROR_NO_DATA);
213 g_variant_unref(reply);
214 return RUNTIME_INFO_ERROR_NO_DATA;
217 usages = calloc(1, sizeof(struct app_usages_s));
219 _E("OUT_OF_MEMORY(0x%08x)", RUNTIME_INFO_ERROR_OUT_OF_MEMORY);
220 g_variant_unref(reply);
221 return RUNTIME_INFO_ERROR_OUT_OF_MEMORY;
224 usages->len = (int)len;
226 usages->list = calloc(len, sizeof(struct app_usage_s));
228 _E("OUT_OF_MEMORY(0x%08x)", RUNTIME_INFO_ERROR_OUT_OF_MEMORY);
230 g_variant_unref(reply);
231 return RUNTIME_INFO_ERROR_OUT_OF_MEMORY;
234 g_variant_iter_init(&iter, reply);
235 for (i = 0; i < len; i++)
236 g_variant_iter_next(&iter, "(su)",
237 &(usages->list[i].appid), &(usages->list[i].usage));
238 g_variant_unref(reply);
242 return RUNTIME_INFO_ERROR_NONE;
245 API int runtime_info_get_system_memory_info(runtime_memory_info_s *info)
250 unsigned long mem_total = 0;
251 unsigned long mem_free = 0;
252 unsigned long cached = 0;
253 unsigned long mem_available = 0;
254 unsigned long swap_total = 0;
255 unsigned long swap_free = 0;
258 _E("INVALID_PARAMETER(0x%08x) : invalid output param",
259 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
260 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
263 swap_total = swap_free = mem_available = 0;
265 fp = fopen("/proc/meminfo", "r");
267 _E("IO_ERROR(0x%08x) : failed to open file to read memory usage",
268 RUNTIME_INFO_ERROR_IO_ERROR);
269 return RUNTIME_INFO_ERROR_IO_ERROR;
272 info->total = info->free = info->cache = 0;
273 while (fgets(buf, sizeof(buf), fp) != NULL) {
274 if (sscanf(buf, "MemTotal: %lu", &mem_total) == 1)
275 info->total = ULONGtoINT(mem_total);
276 else if (sscanf(buf, "MemFree: %lu", &mem_free) == 1)
277 info->free = ULONGtoINT(mem_free);
278 else if (sscanf(buf, "Cached: %lu", &cached) == 1)
279 info->cache = ULONGtoINT(cached);
280 else if (sscanf(buf, "MemAvailable: %lu", &value) == 1)
281 mem_available = value;
282 else if (sscanf(buf, "SwapTotal: %lu", &value) == 1)
284 else if (sscanf(buf, "SwapFree: %lu", &value) == 1)
289 if (mem_available > 0) {
290 if (mem_total > mem_available)
291 info->used = ULONGtoINT(mem_total - mem_available);
295 if (mem_total > mem_free && mem_total - mem_free > cached)
296 info->used = ULONGtoINT(mem_total - mem_free - cached);
301 info->swap = (swap_total > swap_free) ? ULONGtoINT(swap_total - swap_free) : 0;
303 return RUNTIME_INFO_ERROR_NONE;
306 API int runtime_info_get_process_memory_info(int *pid, int size, process_memory_info_s **info)
313 if (!pid || size <= 0) {
314 _E("INVALID_PARAMETER(0x%08x) : invalid input param",
315 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
316 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
320 _E("INVALID_PARAMETER(0x%08x) : invalid output param",
321 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
322 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
327 /* Get the needed information from resourced daemon using dbus */
328 usages = runtime_info_dbus_request_usage_info(USAGE_TYPE_PROCESS_MEMORY, pid, size, &error);
330 //LCOV_EXCL_START : system error
331 _E("DBUS_METHOD_CALL: call to resourced not successful");
336 /* Check whether the received usage has expected format or not */
337 if (g_strcmp0(g_variant_get_type_string(usages), "a(iiiiiii)") ||
338 g_variant_n_children(usages) != size) {
339 //LCOV_EXCL_START : system error
340 _E("DBUS_METHOD_CALL: received dbus message is not in expected format");
341 g_variant_unref(usages);
342 return RUNTIME_INFO_ERROR_REMOTE_IO;
346 /* Populate the entries of info array using the data received from resourced */
347 *info = (process_memory_info_s *)malloc(size * sizeof(process_memory_info_s));
349 _E("OUT_OF_MEMORY(0x%08x)", RUNTIME_INFO_ERROR_OUT_OF_MEMORY);
350 g_variant_unref(usages);
351 return RUNTIME_INFO_ERROR_OUT_OF_MEMORY;
354 g_variant_iter_init(&iter, usages);
355 for (i = 0; i < size; i++)
356 g_variant_iter_next(&iter, "(iiiiiii)",
360 &((*info)[i].shared_clean),
361 &((*info)[i].shared_dirty),
362 &((*info)[i].private_clean),
363 &((*info)[i].private_dirty));
365 g_variant_unref(usages);
367 return RUNTIME_INFO_ERROR_NONE;
370 static runtime_info_error_e hal_error_to_runtime_info_error(int err)
374 return RUNTIME_INFO_ERROR_NONE;
376 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
378 return RUNTIME_INFO_ERROR_OUT_OF_MEMORY;
381 return RUNTIME_INFO_ERROR_IO_ERROR;
384 return RUNTIME_INFO_ERROR_PERMISSION_DENIED;
386 return RUNTIME_INFO_ERROR_NOT_SUPPORTED;
388 // TODO: what is the runtime-info error for this default case?
389 return RUNTIME_INFO_ERROR_NO_DATA;
393 static int get_process_memory_info_direct(int *pid, int size, process_memory_info_key_e key, int **info)
396 struct gpu_info gpu_info;
397 struct gem_info gem_info;
399 int err = RUNTIME_INFO_ERROR_NONE;
401 result = (int *)calloc(size, sizeof(int));
403 err = RUNTIME_INFO_ERROR_OUT_OF_MEMORY;
408 case RUNTIME_INFO_PROC_MEMORY_GPU:
409 for (i = 0; i < size; ++i) {
410 ret = hal_device_memory_get_gpu_info(pid[i], &gpu_info);
412 err = hal_error_to_runtime_info_error(ret);
415 result[i] = gpu_info.used_pages;
419 case RUNTIME_INFO_PROC_MEMORY_GEM_RSS:
420 for (i = 0; i < size; ++i) {
421 ret = hal_device_memory_get_gem_info(pid[i], &gem_info);
423 err = hal_error_to_runtime_info_error(ret);
426 result[i] = gem_info.rss;
431 err = RUNTIME_INFO_ERROR_INVALID_PARAMETER;
436 if (err != RUNTIME_INFO_ERROR_NONE)
442 static int get_process_memory_swap_info(int *pid, int size, int **info)
449 if (!pid || size <= 0) {
450 _E("INVALID_PARAMETER(0x%08x) : invalid input param",
451 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
452 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
456 _E("INVALID_PARAMETER(0x%08x) : invalid output param",
457 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
458 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
463 /* Get the needed information from resourced daemon using dbus */
464 usages = runtime_info_dbus_request_usage_info(USAGE_TYPE_PROCESS_SWAP, pid, size, &error);
466 //LCOV_EXCL_START : system error
467 _E("DBUS_METHOD_CALL: call to resourced not successful");
472 /* Check whether the received usage has expected format or not */
473 if (g_strcmp0(g_variant_get_type_string(usages), "a(i)") ||
474 g_variant_n_children(usages) != size) {
475 //LCOV_EXCL_START : system error
476 _E("DBUS_METHOD_CALL: received dbus message is not in expected format");
477 g_variant_unref(usages);
478 return RUNTIME_INFO_ERROR_REMOTE_IO;
482 /* Populate the entries of info array using the data received from resourced */
483 *info = (int *)malloc(size * sizeof(int));
485 _E("OUT_OF_MEMORY(0x%08x)", RUNTIME_INFO_ERROR_OUT_OF_MEMORY);
486 g_variant_unref(usages);
487 return RUNTIME_INFO_ERROR_OUT_OF_MEMORY;
490 g_variant_iter_init(&iter, usages);
491 for (i = 0; i < size; i++) {
492 g_variant_iter_next(&iter, "(i)", &temp);
496 g_variant_unref(usages);
498 return RUNTIME_INFO_ERROR_NONE;
501 static int get_process_memory_info(int *pid, int size, process_memory_info_key_e key, int **info)
506 process_memory_info_s *base = NULL;
508 ret = RUNTIME_INFO_ERROR_NONE;
510 result = (int *)calloc(size, sizeof(int));
512 ret = RUNTIME_INFO_ERROR_OUT_OF_MEMORY;
516 ret = runtime_info_get_process_memory_info(pid, size, &base);
517 if (ret != RUNTIME_INFO_ERROR_NONE)
521 case RUNTIME_INFO_PROC_MEMORY_VSZ:
522 for (i = 0; i < size; ++i)
523 result[i] = base[i].vsz;
525 case RUNTIME_INFO_PROC_MEMORY_RSS:
526 for (i = 0; i < size; ++i)
527 result[i] = base[i].rss;
529 case RUNTIME_INFO_PROC_MEMORY_PSS:
530 for (i = 0; i < size; ++i)
531 result[i] = base[i].pss;
533 case RUNTIME_INFO_PROC_MEMORY_SHARED_CLEAN:
534 for (i = 0; i < size; ++i)
535 result[i] = base[i].shared_clean;
537 case RUNTIME_INFO_PROC_MEMORY_SHARED_DIRTY:
538 for (i = 0; i < size; ++i)
539 result[i] = base[i].shared_dirty;
541 case RUNTIME_INFO_PROC_MEMORY_PRIVATE_CLEAN:
542 for (i = 0; i < size; ++i)
543 result[i] = base[i].private_clean;
545 case RUNTIME_INFO_PROC_MEMORY_PRIVATE_DIRTY:
546 for (i = 0; i < size; ++i)
547 result[i] = base[i].private_dirty;
550 ret = RUNTIME_INFO_ERROR_INVALID_PARAMETER;
557 if (ret != RUNTIME_INFO_ERROR_NONE)
564 API int runtime_info_get_process_memory_value_int(int *pid, int size, process_memory_info_key_e key, int **info)
567 case RUNTIME_INFO_PROC_MEMORY_GPU:
568 case RUNTIME_INFO_PROC_MEMORY_GEM_RSS:
569 return get_process_memory_info_direct(pid, size, key, info);
570 case RUNTIME_INFO_PROC_MEMORY_SWAP:
571 return get_process_memory_swap_info(pid, size, info);
572 case RUNTIME_INFO_PROC_MEMORY_VSZ:
573 case RUNTIME_INFO_PROC_MEMORY_RSS:
574 case RUNTIME_INFO_PROC_MEMORY_PSS:
575 case RUNTIME_INFO_PROC_MEMORY_SHARED_CLEAN:
576 case RUNTIME_INFO_PROC_MEMORY_SHARED_DIRTY:
577 case RUNTIME_INFO_PROC_MEMORY_PRIVATE_CLEAN:
578 case RUNTIME_INFO_PROC_MEMORY_PRIVATE_DIRTY:
579 return get_process_memory_info(pid, size, key, info);
581 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
585 API int runtime_info_get_cpu_usage(runtime_cpu_usage_s *usage)
589 unsigned long long user = 0;
590 unsigned long long nice = 0;
591 unsigned long long system = 0;
592 unsigned long long idle = 0;
593 unsigned long long iowait = 0;
594 unsigned long long irq = 0;
595 unsigned long long softirq = 0;
596 unsigned long long total_uptime = 0;
599 _E("INVALID_PARAMETER(0x%08x) : invalid output param",
600 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
601 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
604 cpuinfo_fp = fopen("/proc/stat", "r");
605 if (cpuinfo_fp == NULL) {
606 _E("IO_ERROR(0x%08x) : failed to open file to read cpu usage",
607 RUNTIME_INFO_ERROR_IO_ERROR);
608 return RUNTIME_INFO_ERROR_IO_ERROR;
611 while (fgets(buf, sizeof(buf), cpuinfo_fp) != NULL) {
612 if (!strncmp(buf, "cpu ", 4) &&
613 sscanf(buf + 4, "%llu %llu %llu %llu %llu %llu %llu",
614 &user, &nice, &system, &idle,
615 &iowait, &irq, &softirq) == 7)
620 total_uptime = user + nice + system + idle + iowait + irq + softirq;
622 if (total_uptime > 0) {
623 usage->user = (double)user * 100 / total_uptime;
624 usage->nice = (double)nice * 100 / total_uptime;
625 usage->system = (double)system * 100 / total_uptime;
626 usage->iowait = (double)iowait * 100 / total_uptime;
634 return RUNTIME_INFO_ERROR_NONE;
637 API int runtime_info_get_process_cpu_usage(int *pid, int size, process_cpu_usage_s **usage)
644 if (!pid || size <= 0) {
645 _E("INVALID_PARAMETER(0x%08x) : invalid input param",
646 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
647 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
651 _E("INVALID_PARAMETER(0x%08x) : invalid output param",
652 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
653 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
658 /* Get the needed information from resourced daemon using dbus */
659 usages = runtime_info_dbus_request_usage_info(USAGE_TYPE_PROCESS_CPU, pid, size, &error);
661 //LCOV_EXCL_START : system error
662 _E("DBUS_METHOD_CALL: call to resourced not successful");
667 /* Check whether the received usage has expected format or not */
668 if (g_strcmp0(g_variant_get_type_string(usages), "a(ii)") ||
669 g_variant_n_children(usages) != size) {
670 //LCOV_EXCL_START : system error
671 _E("DBUS_METHOD_CALL: received dbus message is not in expected format");
672 g_variant_unref(usages);
673 return RUNTIME_INFO_ERROR_REMOTE_IO;
677 /* Populate the entries of info array using the data received from resourced */
678 *usage = (process_cpu_usage_s *)malloc(size * sizeof(process_cpu_usage_s));
680 //LCOV_EXCL_START : system error
681 _E("OUT_OF_MEMORY(0x%08x)", RUNTIME_INFO_ERROR_OUT_OF_MEMORY);
682 g_variant_unref(usages);
683 return RUNTIME_INFO_ERROR_OUT_OF_MEMORY;
687 g_variant_iter_init(&iter, usages);
688 for (i = 0; i < size; i++)
689 g_variant_iter_next(&iter, "(ii)", &((*usage)[i].utime), &((*usage)[i].stime));
691 g_variant_unref(usages);
693 return RUNTIME_INFO_ERROR_NONE;
696 API int runtime_info_get_processor_count(int *num_core)
703 _E("INVALID_PARAMETER(0x%08x) : invalid output parameter",
704 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
705 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
708 cpuinfo_fp = fopen("/sys/devices/system/cpu/possible", "r");
709 if (cpuinfo_fp == NULL) {
710 //LCOV_EXCL_START : system error
711 _E("IO_ERROR(0x%08x) : failed to open file to read cpu information",
712 RUNTIME_INFO_ERROR_IO_ERROR);
713 return RUNTIME_INFO_ERROR_IO_ERROR;
717 if (!fscanf(cpuinfo_fp, "%d-%d", &buf, &result)) {
718 //LCOV_EXCL_START : system error
719 _E("IO_ERROR(0x%08x) : there is no information in the system file",
720 RUNTIME_INFO_ERROR_IO_ERROR);
722 return RUNTIME_INFO_ERROR_IO_ERROR;
726 *num_core = result + 1;
729 return RUNTIME_INFO_ERROR_NONE;
732 API int runtime_info_get_processor_current_frequency(int core_idx, int *cpu_freq)
736 if (runtime_info_get_processor_count(&num_core)
737 != RUNTIME_INFO_ERROR_NONE) {
738 _E("runtime_info_get_processor_count is failed");
739 return RUNTIME_INFO_ERROR_IO_ERROR;
742 if (core_idx < 0 || core_idx >= num_core) {
743 _E("INVALID_PARAMETER(0x%08x) : invalid input parameter",
744 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
745 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
749 _E("INVALID_PARAMETER(0x%08x) : invalid output parameter",
750 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
751 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
754 if (runtime_info_get_frequency_cpufreq(core_idx, "cur", cpu_freq)
755 != RUNTIME_INFO_ERROR_NONE) {
756 //LCOV_EXCL_START : system error
757 _I("This system doesn't support cpufreq. Use cpuinfo instead.");
759 switch (runtime_info_get_frequency_cpuinfo(core_idx, cpu_freq)) {
760 case RUNTIME_INFO_ERROR_NONE:
761 _I("Notice : it is max CPU frequency");
763 case RUNTIME_INFO_ERROR_NO_DATA:
764 _E("This system doesn't support MHz information in the cpuinfo");
765 return RUNTIME_INFO_ERROR_NO_DATA;
767 _E("Fail to get current CPU frequency");
768 return RUNTIME_INFO_ERROR_IO_ERROR;
773 return RUNTIME_INFO_ERROR_NONE;
776 API int runtime_info_get_processor_max_frequency(int core_idx, int *cpu_freq)
780 if (runtime_info_get_processor_count(&num_core)
781 != RUNTIME_INFO_ERROR_NONE) {
782 _E("runtime_info_get_processor_count is failed");
783 return RUNTIME_INFO_ERROR_IO_ERROR;
786 if (core_idx < 0 || core_idx >= num_core) {
787 _E("INVALID_PARAMETER(0x%08x) : invalid input parameter",
788 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
789 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
793 _E("INVALID_PARAMETER(0x%08x) : invalid output parameter",
794 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
795 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
798 if (runtime_info_get_frequency_cpufreq(core_idx, "max", cpu_freq)
799 != RUNTIME_INFO_ERROR_NONE) {
800 //LCOV_EXCL_START : system error
801 _I("This system doesn't support cpufreq. Use cpuinfo instead.");
803 switch (runtime_info_get_frequency_cpuinfo(core_idx, cpu_freq)) {
804 case RUNTIME_INFO_ERROR_NONE:
806 case RUNTIME_INFO_ERROR_NO_DATA:
807 _E("This system doesn't support MHz information in the cpuinfo");
808 return RUNTIME_INFO_ERROR_NO_DATA;
810 _E("Fail to get current CPU frequency");
811 return RUNTIME_INFO_ERROR_IO_ERROR;
816 return RUNTIME_INFO_ERROR_NONE;
819 API int runtime_info_get_physical_memory_size(int *size)
824 FILE *fp = fopen("/proc/zoneinfo", "r");
826 _E("IO_ERROR(0x%08x) : failed to open file to read memory size",
827 RUNTIME_INFO_ERROR_IO_ERROR);
828 return RUNTIME_INFO_ERROR_IO_ERROR;
832 _E("INVALID PARAMETER(0x%08x) : invalid output parameter",
833 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
835 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
839 while (fgets(buf, sizeof(buf), fp) != NULL)
840 if (sscanf(buf, " spanned %lu", &value) == 1)
842 *size = pagetoKiB(sum);
846 return RUNTIME_INFO_ERROR_NONE;
849 API int runtime_info_app_usage_destroy(app_usage_h handle)
852 struct app_usage_s *list;
853 struct app_usages_s *usages = handle;
856 _E("INVALID PARAMETER(0x%08x) : invalid input parameter",
857 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
858 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
863 for (i = 0; i < usages->len; i++)
871 return RUNTIME_INFO_ERROR_NONE;
874 API int runtime_info_app_usage_get_count(app_usage_h handle, int *count)
876 struct app_usages_s *usages = handle;
879 _E("INVALID PARAMETER(0x%08x) : invalid input parameter",
880 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
881 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
885 _E("INVALID PARAMETER(0x%08x) : invalid output parameter",
886 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
887 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
890 *count = usages->len;
892 return RUNTIME_INFO_ERROR_NONE;
895 API int runtime_info_app_usage_get_appid(app_usage_h handle, int index, char **appid)
897 struct app_usages_s *usages = handle;
899 if (!usages || index < 0 || index >= usages->len) {
900 _E("INVALID PARAMETER(0x%08x) : invalid input parameter",
901 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
902 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
906 _E("INVALID PARAMETER(0x%08x) : invalid output parameter",
907 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
908 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
911 *appid = strndup(usages->list[index].appid, strlen(usages->list[index].appid));
913 return RUNTIME_INFO_ERROR_NONE;
916 API int runtime_info_app_usage_get_usage(app_usage_h handle, int index, unsigned int *usage)
918 struct app_usages_s *usages = handle;
920 if (!usages || index < 0 || index >= usages->len) {
921 _E("INVALID PARAMETER(0x%08x) : invalid input parameter",
922 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
923 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
927 _E("INVALID PARAMETER(0x%08x) : invalid output parameter",
928 RUNTIME_INFO_ERROR_INVALID_PARAMETER);
929 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
932 *usage = usages->list[index].usage;
934 return RUNTIME_INFO_ERROR_NONE;
937 API int runtime_info_get_all_apps_memory_usage(app_usage_h *usage)
939 return runtime_info_get_all_apps_usage(USAGE_TYPE_APP_MEMORY, usage);
942 API int runtime_info_get_all_apps_cpu_rate(app_usage_h *rate)
944 return runtime_info_get_all_apps_usage(USAGE_TYPE_APP_CPU, rate);