4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
8 * Jaewon Lim <jaewon81.lim@samsung.com>
9 * Woojin Jung <woojin2.jung@samsung.com>
10 * Juyoung Kim <j0.kim@samsung.com>
11 * Cherepanov Vitaliy <v.cherepanov@samsung.com>
12 * Nikita Kalyazin <n.kalyazin@samsung.com>
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
18 * http://www.apache.org/licenses/LICENSE-2.0
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
28 * - Samsung RnD Institute Russia
38 #include <sys/types.h>
50 #include "da_protocol.h"
54 #include "device_system_info.h"
55 #include "device_vconf.h"
56 #include "device_camera.h"
59 // defines for runtime environment
62 #define BUFFER_MAX 1024
63 #define LARGE_BUFFER 512
64 #define MIDDLE_BUFFER 256
65 #define SMALL_BUFFER 64
66 #define PROCPATH_MAX 32
67 #define STATUS_STRING_MAX 16
68 #define MAX_NUM_OF_FREQ 16
70 #define MEM_SLOT_TOTAL 0
71 #define MEM_SLOT_FREE 1
72 #define MEM_SLOT_BUFFER 2
73 #define MEM_SLOT_CACHED 3
74 #define MEM_SLOT_MAX 4
76 #define MIN_TICKS_FOR_LOAD 8
77 #define MIN_TOTAL_TICK 10
78 #define SYS_INFO_TICK 100 // TODO : change to (Hertz * profiling period)
80 #define CPUMHZ "cpu MHz"
81 #define DA_PROBE_TIZEN_SONAME "da_probe_tizen.so"
82 #define DA_PROBE_OSP_SONAME "da_probe_osp.so"
84 // define for correct difference of system feature vars
85 #define val_diff(v_new, v_old) ((v_new < v_old) ? v_new : v_new - v_old)
93 // declared by greatim
95 static int num_of_cpu = 0;
96 static int num_of_freq = 0;
97 static uint64_t mem_slot_array[MEM_SLOT_MAX];
98 static CPU_t* cpus = NULL;
99 static unsigned long probe_so_size = 0;
102 static int get_file_status_no_open(int pfd, const char *filename)
105 char buf[STATUS_STRING_MAX];
107 if (unlikely(pfd < 0)) {
112 lseek(pfd, 0, SEEK_SET); // rewind to start of file
115 if (unlikely(read(pfd, buf, STATUS_STRING_MAX) == -1))
122 // daemon api : get status from file
123 // pfd must not be null
124 int get_file_status(int *pfd, const char *filename)
128 if (likely(pfd != NULL)) {
129 //open if is not open
130 if (unlikely(*pfd < 0)) {
132 *pfd = open(filename, O_RDONLY);
133 if (unlikely(*pfd == -1)) {
134 /* This file may absent in the system */
139 if (unlikely(*pfd < 0)) {
140 //file is open. lets read
141 status = get_file_status_no_open(*pfd, filename);
149 // =============================================================================
150 // device status information getter functions
151 // =============================================================================
153 static void init_brightness_status()
157 struct dirent *dir_entry;
158 char fullpath[PATH_MAX];
160 dir_info = opendir(BRIGHTNESS_PARENT_DIR);
161 if (dir_info != NULL) {
162 while ((dir_entry = readdir(dir_info)) != NULL) {
163 if (strcmp(dir_entry->d_name, ".") == 0 ||
164 strcmp(dir_entry->d_name, "..") == 0)
166 else { /* first directory */
168 BRIGHTNESS_PARENT_DIR "/%s/"
171 get_file_status(&manager.fd.brightness,
180 get_file_status(&manager.fd.brightness, EMUL_BRIGHTNESSFD);
184 static int get_brightness_status()
186 return get_file_status_no_open(manager.fd.brightness, EMUL_BRIGHTNESSFD);
189 static int get_max_brightness()
191 int maxbrightnessfd = -1;
192 static int max_brightness = -1;
194 if (__builtin_expect(max_brightness < 0, 0)) {
197 struct dirent* dir_entry;
198 char fullpath[PATH_MAX];
200 dir_info = opendir(BRIGHTNESS_PARENT_DIR);
201 if (dir_info != NULL) {
202 while((dir_entry = readdir(dir_info)) != NULL) {
203 if (strcmp(dir_entry->d_name, ".") == 0 ||
204 strcmp(dir_entry->d_name, "..") == 0)
208 BRIGHTNESS_PARENT_DIR "/%s/" MAX_BRIGHTNESS_FILENAME,
210 max_brightness = get_file_status(&maxbrightnessfd, fullpath);
217 #else /* DEVICE_ONLY */
218 max_brightness = get_file_status(&maxbrightnessfd, EMUL_MAX_BRIGHTNESSFD);
219 #endif /* DEVICE_ONLY */
222 if (maxbrightnessfd != -1)
223 close(maxbrightnessfd);
225 return max_brightness;
228 static void init_video_status()
230 manager.fd.video = fopen(MFCFD, "r");
233 static int get_video_status()
235 int video_status = 0;
237 FILE *video_fp = manager.fd.video;
240 if (video_fp == NULL) // file is not open
246 ret = fscanf(video_fp, "%s", stat);
249 if(strncmp(stat,"active",6) == 0)
255 static void init_voltage_status()
257 get_file_status(&manager.fd.voltage, VOLTAGEFD);
260 static int get_voltage_status()
262 return get_file_status_no_open(manager.fd.voltage, VOLTAGEFD);
265 // =====================================================================
266 // cpu information getter functions
267 // =====================================================================
268 static void get_cpu_frequency(float *freqs)
270 char filename[MIDDLE_BUFFER];
271 char freq_str[SMALL_BUFFER];
276 for (cpu_n = 0; cpu_n < num_of_cpu; cpu_n++)
282 snprintf(filename, MIDDLE_BUFFER,
283 "/sys/devices/system/cpu/cpu%d/online", cpu_n);
285 f = fopen(filename, "r");
287 LOGI_th_samp("file not found <%s\n>", filename);
293 snprintf(filename, MIDDLE_BUFFER,
294 "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", cpu_n);
295 f = fopen(filename, "r");
299 LOGI_th_samp("core #%d diasabled\n", cpu_n);
302 //core enabled, get frequency
303 fscanf(f, "%s", freq_str);
304 freqs[cpu_n] = atof(freq_str);
305 LOGI_th_samp("core #%d freq = %.0f\n", cpu_n, freqs[cpu_n]);
315 // ========================================================================
316 // get cpu and memory info for each process and whole system
317 // ========================================================================
318 typedef struct _proc_node {
320 unsigned long long saved_utime;
321 unsigned long long saved_stime;
323 struct _proc_node *next;
326 static procNode *prochead = NULL;
327 static procNode *thread_prochead = NULL;
329 static procNode* find_node(procNode *head, pid_t pid)
334 if (t->proc_data.pid == pid)
344 static procNode* add_node(procNode **head, pid_t pid)
348 n = (procNode *) malloc(sizeof(procNode));
350 LOGE("Not enough memory, add cpu info node failied");
354 n->proc_data.pid = pid;
362 static int del_node(procNode **head, pid_t pid)
369 /* LOGI("dell t=%d\n",t); */
371 if (t->proc_data.pid == pid) {
373 prev->next = t->next;
375 *head = (*head)->next;
383 /* LOGI("ret 0\n"); */
387 static int del_notfound_node(procNode **head)
389 procNode *proc, *prev;
391 for(proc = *head; proc != NULL; )
397 prev->next = proc->next;
403 *head = (*head)->next;
417 static int reset_found_node(procNode *head)
420 for(proc = head; proc != NULL; proc = proc->next)
427 // return 0 for normal case
428 // return negative value for error case
429 static int parse_proc_stat_file_bypid(char *path, proc_t* P)
431 char filename[PROCPATH_MAX];
432 char buf[BUFFER_MAX];
436 // read from stat file
437 sprintf(filename, "%s/stat", path);
438 fd = open(filename, O_RDONLY, 0);
440 if(unlikely(fd == -1)){
444 num = read(fd, buf, BUFFER_MAX);
447 if(unlikely(num <= 0)){
448 LOGE("nothing read from '%s'\n", filename);
450 } else if(num == BUFFER_MAX)
458 abuf = strchr(buf, '(') + 1;
459 bbuf = strrchr(buf, ')');
461 if(unlikely(num >= sizeof(P->command)))
462 num = sizeof(P->command) - 1;
463 memcpy(P->command, abuf, num);
464 P->command[num] = '\0';
472 "%lu %lu %lu %lu %lu "
473 "%Lu %Lu %Lu %Lu " // utime stime cutime cstime
481 &P->ppid, &P->pgrp, &P->sid, &P->tty_nr, &P->tty_pgrp,
482 &P->flags, &P->minor_fault, &P->cminor_fault, &P->major_fault, &P->cmajor_fault,
483 &P->utime, &P->stime, &P->cutime, &P->cstime,
484 &P->priority, &P->nice,
492 if(P->numofthread == 0)
498 // return 0 for normal case
499 // return negative value for error case
500 static int parse_proc_smaps_file_bypid(char *path, proc_t* P)
502 #define MIN_SMAP_BLOCKLINE 50
504 char filename[PROCPATH_MAX];
505 char buf[MIDDLE_BUFFER];
506 char numbuf[SMALL_BUFFER];
509 // reset pss size of proc_t
513 // read from smaps file
514 sprintf(filename, "%s/smaps", path);
515 fp = fopen(filename, "r");
521 if(unlikely(probe_so_size == 0)) // probe so size is not abtained
524 while(fgets(buf, MIDDLE_BUFFER, fp) != NULL)
526 if(strncmp(buf, "Pss:", 4) == 0) // line is started with "Pss:"
528 sscanf(buf, "Pss:%s kB", numbuf);
529 P->pss += atoi(numbuf);
532 probe_so_size += atoi(numbuf);
533 is_probe_so = 0; // reset search flag
536 else if(strncmp(buf, "Shared", 6) == 0) // line is started with "Shared"
539 p = strstr(buf, ":");
541 sscanf(p, ":%s kB", numbuf);
542 P->sh_mem += atoi(numbuf);
548 if (is_probe_so == 0 && strlen(buf) > MIN_SMAP_BLOCKLINE)
550 // first we find probe so section
551 if(strstr(buf, DA_PROBE_TIZEN_SONAME) != NULL ||
552 strstr(buf, DA_PROBE_OSP_SONAME) != NULL)
569 else // we know about probe.so size already
571 while(fgets(buf, MIDDLE_BUFFER, fp) != NULL)
573 if(strncmp(buf, "Pss:", 4) == 0)
575 sscanf(buf, "Pss:%s kB", numbuf);
576 P->pss += atoi(numbuf);
578 else if(strncmp(buf, "Shared", 6) == 0) // line is started with "Shared"
581 p = strstr(buf, ":");
583 sscanf(p, ":%s kB", numbuf);
584 P->sh_mem += atoi(numbuf);
590 P->pss -= probe_so_size;
597 // return 0 for normal case
598 // return positive value for non critical case
599 // return negative value for critical case
600 static int update_process_data(int* pidarray, int pidcount, enum PROCESS_DATA datatype)
602 static struct stat sb;
604 char buf[PROCPATH_MAX];
607 for(i = 0; i < pidcount; i++)
609 /* LOGI("#%d\n", i); */
610 if (pidarray[i] == 0) // pid is invalid
616 sprintf(buf, "/proc/%d", pidarray[i]);
617 /* LOGI("#->%s\n", buf); */
618 if (unlikely(stat(buf, &sb) == -1)) // cannot access anymore
620 /* LOGI("#del from prochead=%d\n", prochead); */
621 del_node(&prochead, pidarray[i]);
626 /* LOGI("find node = %d\n", procnode); */
627 if ((procnode = find_node(prochead, pidarray[i])) == NULL) // new process
629 /* LOGI("proc node1 = %d\n", procnode); */
630 procnode = add_node(&prochead, pidarray[i]);
631 if(datatype == PROCDATA_STAT)
633 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
635 LOGE("Failed to get proc stat file by pid(%d)\n", pidarray[i]);
639 procnode->saved_utime = procnode->proc_data.utime;
640 procnode->saved_stime = procnode->proc_data.stime;
643 else if(datatype == PROCDATA_SMAPS)
645 if (unlikely((ret = parse_proc_smaps_file_bypid(buf, &(procnode->proc_data))) < 0))
647 LOGE("Failed to get proc smaps file by pid(%d)\n", pidarray[i]);
659 /* LOGI("proc node2 = %d\n", procnode); */
660 if(datatype == PROCDATA_STAT)
662 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
664 LOGE("Failed to get proc stat file by pid(%d)\n", pidarray[i]);
670 else if(datatype == PROCDATA_SMAPS)
672 if (unlikely((ret = parse_proc_smaps_file_bypid(buf, &(procnode->proc_data))) < 0))
674 LOGE("Failed to get proc smaps file by pid(%d)\n", pidarray[i]);
685 /* LOGI("del_notfound_node\n"); */
686 del_notfound_node(&prochead);
687 /* LOGI("reset_found_node\n"); */
688 reset_found_node(prochead);
690 /* LOGI("ret %d\n", ret); */
694 static int update_system_cpu_frequency(int cur_index)
696 char buf[SMALL_BUFFER];
697 char filename[SMALL_BUFFER];
701 // execute this block only once
702 if(unlikely(num_of_freq <= 0))
706 if((fp = fopen(CPUNUM_OF_FREQ, "r")) != NULL)
708 while(fgets(buf, SMALL_BUFFER, fp) != NULL)
716 /* This file may absent in the system */
719 for(i = 0; i < num_of_cpu; i++)
721 if(cpus[i].pfreq == NULL && num_of_freq)
723 cpus[i].pfreq = (cpufreq_t*) calloc(num_of_freq, sizeof(cpufreq_t));
728 sprintf(filename, CPUNUM_OF_FREQ);
729 // update cpu frequency information
730 for(i = 0; i < num_of_cpu; i++)
732 filename[27] = (char)('0' + i);
733 fp = fopen(filename, "r");
736 for(j = 0; j < num_of_freq; j++)
738 if(fgets(buf, SMALL_BUFFER, fp) != NULL)
740 sscanf(buf, "%lu %Lu", &(cpus[i].pfreq[j].freq),
741 &(cpus[i].pfreq[j].tick));
743 else // cannot read anymore from frequency info file
748 cpus[i].cur_freq_index = cur_index;
750 else // cannot load cpu frequency information
758 // return 0 for normal case
759 // return negative value for error
760 static void init_system_cpu_data()
762 manager.fd.procstat = fopen(PROCSTAT, "r");
765 static int update_system_cpu_data(int cur_index)
769 FILE* fp = manager.fd.procstat;
771 char buf[BUFFER_MAX];
779 if(fgets(buf, sizeof(buf), fp) == NULL)
781 LOGE("Failed to read first line of " PROCSTAT "\n");
785 /* LOGI("scan; cpus = %d\n", cpus); */
787 cpus[num_of_cpu].x = 0;
788 cpus[num_of_cpu].y = 0;
789 cpus[num_of_cpu].z = 0;
790 num = sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
800 cpus[num_of_cpu].cur_load_index = cur_index;
803 LOGE("Failed to read from " PROCSTAT "\n");
809 /* LOGI("cpu num = %d\n", num_of_cpu); */
810 // and just in case we're 2.2.xx compiled without SMP support...
813 cpus[0].id = cpus[1].id = 0;
814 memcpy(cpus, &cpus[1], sizeof(tic_t) * 8);
815 cpus[0].cur_load_index = cur_index;
817 else if(num_of_cpu > 1)
820 // now value each separate cpu's tics
821 for(i = 0; i < num_of_cpu; i++)
823 if(fgets(buf, sizeof(buf), fp) != NULL)
828 num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
830 &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i,
831 &cpus[i].w, &cpus[i].x, &cpus[i].y, &cpus[i].z);
834 LOGI_th_samp("Readed %d stats of %dth cpu\n", num, i);
835 cpus[i].cur_load_index = cur_index;
837 else // buf is not cpu core tick information
841 else // cannot read anymore from /proc/stat file
855 // return 0 for normal case
856 // return negative value for error
857 static void init_update_system_memory_data()
859 manager.fd.procmeminfo = open(PROCMEMINFO, O_RDONLY);
862 static int update_system_memory_data(uint64_t *memtotal, uint64_t *memused)
864 int meminfo_fd = manager.fd.procmeminfo;
867 char buf[BUFFER_MAX];
868 static const mem_t mem_table[] = {
869 {"Buffers", (unsigned long *)&mem_slot_array[MEM_SLOT_BUFFER]},
870 {"Cached", (unsigned long *)&mem_slot_array[MEM_SLOT_CACHED]},
871 {"MemFree", (unsigned long *)&mem_slot_array[MEM_SLOT_FREE]},
872 {"MemTotal", (unsigned long *)&mem_slot_array[MEM_SLOT_TOTAL]},
874 const int mem_table_size = sizeof(mem_table) / sizeof(mem_t);
876 if (meminfo_fd == -1)
879 lseek(meminfo_fd, 0L, SEEK_SET);
880 if((num = read(meminfo_fd, buf, BUFFER_MAX)) < 0)
882 LOGE("Failed to read from " PROCMEMINFO "\n");
886 if(num == BUFFER_MAX)
890 // LOGI("buffer=<%s>\n", buf);
892 num = 0; // number of found element
894 for( ;num < mem_table_size ; )
896 tail = strchr(head, ':');
900 for(i = 0; i < mem_table_size; i++)
902 if(strcmp(head, mem_table[i].name) == 0) // found
905 *(mem_table[i].slot) = strtoul(head, &tail, 10);
910 if(i == mem_table_size) // cannot find entry
914 tail = strchr(head, '\n');
919 /* LOGI("Buffers = %016LX\n", mem_slot_array[MEM_SLOT_BUFFER]); */
920 /* LOGI("Cached = %016LX\n", mem_slot_array[MEM_SLOT_CACHED]); */
921 /* LOGI("MemFree = %016LX\n", mem_slot_array[MEM_SLOT_FREE]); */
922 /* LOGI("MemTotal= %016LX\n", mem_slot_array[MEM_SLOT_TOTAL]); */
923 if(num == mem_table_size) // find all element
925 *memtotal = mem_slot_array[MEM_SLOT_TOTAL];
926 *memused = mem_slot_array[MEM_SLOT_TOTAL] - mem_slot_array[MEM_SLOT_FREE] -
927 mem_slot_array[MEM_SLOT_BUFFER] - mem_slot_array[MEM_SLOT_CACHED];
930 *memtotal *= 1024; // change to Byte
931 *memused *= 1024; // change to Byte
936 LOGE("Cannot find all neccessary element in meminfo\n");
942 // return 0 for error case
943 // return system total memory in MB
945 static unsigned long get_system_total_memory(void)
947 int meminfo_fd = manager.fd.procmeminfo;
950 char buf[BUFFER_MAX];
951 static const char* memtotalstr = "MemTotal";
952 unsigned long totalmem = 0;
954 if (meminfo_fd == -1)
957 lseek(meminfo_fd, 0L, SEEK_SET);
959 if((num = read(meminfo_fd, buf, BUFFER_MAX)) < 0)
961 LOGE("Failed to read from " PROCMEMINFO "\n");
965 if(num == BUFFER_MAX)
972 tail = strchr(head, ':');
976 if(strcmp(head, memtotalstr) == 0) // found
979 totalmem = strtoul(head, &tail, 10);
984 tail = strchr(head, '\n');
990 return (totalmem * 1024);
993 // ===============================================================
994 // disk information getter functions
995 // ===============================================================
996 static int get_fsinfo(const char* path, int type)
1002 if (statfs(path, &buf) < 0)
1007 total = (int)((long long)(buf.f_bsize / 1024LL * buf.f_blocks) / 1024LL);
1008 free = (int)((long long)(buf.f_bsize / 1024LL * buf.f_bavail) / 1024LL);
1010 /* LOGI("File storage total(%d), free(%d)\n", total, free); */
1011 if (type == FSINFO_TYPE_TOTAL)
1015 else if (type == FSINFO_TYPE_FREE)
1023 static int stat_get_storageinfo(int type)
1025 return get_fsinfo(UMSFD, type);
1028 static int stat_get_cardinfo(int type)
1030 if (access(MMCBLKFD, F_OK) < 0)
1035 return get_fsinfo(MMCFD, type);
1039 static int get_total_drive()
1042 int storage = stat_get_storageinfo(FSINFO_TYPE_TOTAL);
1043 int card = stat_get_cardinfo(FSINFO_TYPE_TOTAL);
1045 if (storage < 0 && card < 0)
1050 total = storage + card;
1055 static int get_total_used_drive()
1059 int storage = stat_get_storageinfo(FSINFO_TYPE_FREE);
1060 int card = stat_get_cardinfo(FSINFO_TYPE_FREE);
1062 if (storage < 0 && card < 0)
1064 LOGI_th_samp("total_used_drive = -1\n");
1068 free = storage + card;
1069 total = get_total_drive() - free;
1071 LOGI_th_samp("total_used_drive = %d\n", total);
1076 static int update_thread_data(int pid)
1078 static struct stat sb;
1080 char path[PROCPATH_MAX];
1081 char buf[PROCPATH_MAX];
1083 DIR *taskdir = NULL;
1084 struct dirent *entry = NULL;
1087 sprintf(path, "/proc/%d/task", pid);
1089 if(!(taskdir = opendir(path)))
1091 LOGE("task not found '%s'\n", path);
1095 while((entry = readdir(taskdir)) != NULL)
1097 if(*entry->d_name > '0' && *entry->d_name <= '9')
1099 tid = atoi(entry->d_name);
1100 sprintf(buf, "/proc/%d/task/%d", pid, tid);
1102 if(unlikely(stat(buf, &sb) == -1))
1104 del_node(&thread_prochead, tid);
1109 if((procnode = find_node(thread_prochead, tid)) == NULL)
1111 procnode = add_node(&thread_prochead, tid);
1112 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
1114 LOGE("Failed to get proc stat file by tid(%d). add node\n", tid);
1118 procnode->saved_utime = procnode->proc_data.utime;
1119 procnode->saved_stime = procnode->proc_data.stime;
1120 /* LOGI("data updated\n"); */
1125 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
1127 LOGE("Failed to get proc stat file by tid(%d). node exist\n", tid);
1133 del_notfound_node(&thread_prochead);
1134 reset_found_node(thread_prochead);
1140 // ========================================================================
1141 // overall information getter functions
1142 // ========================================================================
1144 static int get_device_network_type(char* buf, int buflen)
1148 if (is_cdma_available())
1149 len += sprintf(buf + len, "CDMA,");
1151 if (is_edge_available())
1152 len += sprintf(buf + len, "EDGE,");
1154 if (is_gprs_available())
1155 len += sprintf(buf + len, "GPRS,");
1157 if (is_gsm_available())
1158 len += sprintf(buf + len, "GSM,");
1160 if (is_hsdpa_available())
1161 len += sprintf(buf + len, "HSDPA,");
1163 if (is_hspa_available())
1164 len += sprintf(buf + len, "HSPA,");
1166 if (is_hsupa_available())
1167 len += sprintf(buf + len, "HSUPA,");
1169 if (is_umts_available())
1170 len += sprintf(buf + len, "UMTS,");
1172 if (is_lte_available())
1173 len += sprintf(buf + len, "LTE,");
1181 static int update_cpus_info(int event_num, float elapsed)
1185 // calculate for system cpu load
1187 for(i = 0; i < num_of_cpu; i++)
1189 for(i = num_of_cpu; i <= num_of_cpu; i++)
1192 LOGI_th_samp("CPU #%d\n", i);
1193 cpuptr = &(cpus[i]);
1195 if(cpuptr->cur_load_index == event_num)
1197 if(cpuptr->sav_load_index == event_num - 1) // previous sampling is just before 1 period
1199 cpuptr->idle_ticks = cpuptr->i - cpuptr->i_sav;
1200 if(unlikely(cpuptr->idle_ticks < 0))
1202 cpuptr->idle_ticks = 0;
1204 cpuptr->total_ticks = (cpuptr->u - cpuptr->u_sav) +
1205 (cpuptr->s - cpuptr->s_sav) +
1206 (cpuptr->n - cpuptr->n_sav) +
1207 cpuptr->idle_ticks +
1208 (cpuptr->w - cpuptr->w_sav) +
1209 (cpuptr->x - cpuptr->x_sav) +
1210 (cpuptr->y - cpuptr->y_sav) +
1211 (cpuptr->z - cpuptr->z_sav);
1212 if(cpuptr->total_ticks < MIN_TOTAL_TICK)
1214 cpuptr->cpu_usage = 0.0f;
1218 cpuptr->cpu_usage = (1.0f - ((float)cpuptr->idle_ticks /
1219 (float)cpuptr->total_ticks)) * 100.0f;
1221 // if(i != num_of_cpu)
1223 // idle_tick_sum += cpuptr->idle_ticks;
1224 // total_tick_sum += cpuptr->total_ticks;
1226 LOGI_th_samp("System cpu usage log : %d, %Ld, %Ld\n",
1227 i, cpuptr->idle_ticks, cpuptr->total_ticks);
1228 if(unlikely(cpuptr->cpu_usage < 0))
1230 cpuptr->cpu_usage = 0.0f;
1233 else // previous sampling is not just before 1 period
1235 // assume non idle ticks happen in 1 profiling period
1236 // because sampling is not available just before 1 profiling period
1237 cpuptr->idle_ticks = (cpuptr->u - cpuptr->u_sav) +
1238 (cpuptr->s - cpuptr->s_sav) +
1239 (cpuptr->n - cpuptr->n_sav) +
1240 (cpuptr->w - cpuptr->w_sav) +
1241 (cpuptr->x - cpuptr->x_sav) +
1242 (cpuptr->y - cpuptr->y_sav) +
1243 (cpuptr->z - cpuptr->z_sav);
1244 cpuptr->total_ticks = (long long)(Hertz * elapsed);
1245 if(unlikely(cpuptr->total_ticks < 1))
1246 cpuptr->total_ticks = 1;
1247 cpuptr->cpu_usage = ((float)cpuptr->idle_ticks /
1248 (float)cpuptr->total_ticks) * 100.0f;
1249 if(unlikely(cpuptr->cpu_usage > 100.0f))
1251 cpuptr->cpu_usage = 100.0f;
1256 cpuptr->u_sav = cpuptr->u;
1257 cpuptr->s_sav = cpuptr->s;
1258 cpuptr->n_sav = cpuptr->n;
1259 cpuptr->i_sav = cpuptr->i;
1260 cpuptr->w_sav = cpuptr->w;
1261 cpuptr->x_sav = cpuptr->x;
1262 cpuptr->y_sav = cpuptr->y;
1263 cpuptr->z_sav = cpuptr->z;
1264 cpuptr->sav_load_index = cpuptr->cur_load_index;
1268 cpuptr->cpu_usage = 0.0f;
1272 // calculate for cpu core load that failed to get tick information
1276 LOGI("ticks1 : %Ld, %Ld\n", idle_tick_sum, total_tick_sum);
1277 idle_tick_sum = cpus[num_of_cpu].idle_ticks - idle_tick_sum;
1278 total_tick_sum = cpus[num_of_cpu].total_ticks - total_tick_sum;
1279 LOGI("ticks2 : %Ld, %Ld\n", idle_tick_sum, total_tick_sum);
1280 if(total_tick_sum >= MIN_TICKS_FOR_LOAD)
1281 sys_usage = (1.0f - ((float)idle_tick_sum / (float)total_tick_sum)) * 100.0f;
1284 if(sys_usage < 0.0f) sys_usage = 0.0f;
1285 else if(sys_usage > 100.0f) sys_usage = 100.0f;
1287 for(i = 0; i < num_of_cpu; i++)
1289 if(failed_cpu & (1 << i))
1291 cpus[i].cpu_usage = sys_usage;
1299 static int fill_system_processes_info(float factor, struct system_info_t * sys_info)
1305 unsigned long virtual = 0;
1306 unsigned long resident = 0;
1307 unsigned long shared = 0;
1308 unsigned long pssmem = 0;
1310 float app_cpu_usage = 0.0;
1312 LOGI_th_samp("prochead = %X\n", (unsigned int)prochead);
1313 for(proc = prochead; proc != NULL; proc = proc->next)
1315 //increment process count
1316 sys_info->count_of_processes++; //maybe wrong
1318 sys_info->process_load = malloc (
1319 sys_info->count_of_processes *
1320 sizeof(*sys_info->process_load)
1323 for(proc = prochead; proc != NULL; proc = proc->next)
1325 LOGI_th_samp("proc#%d (%d %d),(%d %d) (%d) %f\n",
1327 (unsigned int)proc->proc_data.utime, (unsigned int)proc->proc_data.stime ,
1328 (unsigned int)proc->saved_utime, (unsigned int)proc->saved_stime,
1329 (int)(proc->proc_data.utime + proc->proc_data.stime - proc->saved_utime - proc->saved_stime),
1331 proc->saved_utime + proc->saved_stime -
1332 proc->proc_data.utime - proc->proc_data.stime
1334 thread_load = (float)(proc->proc_data.utime + proc->proc_data.stime -
1335 proc->saved_utime - proc->saved_stime) * factor;
1337 if(thread_load > 100.0f)
1338 thread_load = 100.0f;
1340 //num_thread += proc->proc_data.numofthread;
1341 virtual += proc->proc_data.vir_mem; // Byte
1342 resident += (proc->proc_data.res_memblock * 4); // KByte
1343 pssmem += (proc->proc_data.pss); // KByte
1344 shared += (proc->proc_data.sh_mem); // KByte
1345 ticks += (proc->proc_data.utime + proc->proc_data.stime -
1346 proc->saved_utime - proc->saved_stime);
1348 proc->saved_utime = proc->proc_data.utime;
1349 proc->saved_stime = proc->proc_data.stime;
1352 sys_info->process_load[i].id = proc->proc_data.pid;
1353 sys_info->process_load[i].load = thread_load;
1358 app_cpu_usage = (float)ticks * factor;
1359 if(app_cpu_usage > 100.0f)
1360 app_cpu_usage = 100.0f;
1361 resident = resident * 1024; // change to Byte
1362 pssmem = pssmem * 1024; // change to Byte
1363 shared = shared * 1024; // change to Byte
1365 sys_info->virtual_memory = virtual;
1366 sys_info->resident_memory = resident;
1367 sys_info->shared_memory = shared;
1368 sys_info->pss_memory = pssmem;
1370 sys_info->app_cpu_usage = app_cpu_usage;
1376 // fill threads information
1377 static int fill_system_threads_info(float factor, struct system_info_t * sys_info)
1382 for(proc = thread_prochead; proc != NULL; proc = proc->next)
1383 //increment thread count
1384 sys_info->count_of_threads++; //maybe wrong
1386 /* LOGI_th_samp("thread load\n"); */
1387 struct thread_info_t *pthread;
1388 if (sys_info->count_of_threads != 0)
1390 sys_info->thread_load = malloc( sys_info->count_of_threads * sizeof(*sys_info->thread_load) );
1391 pthread = sys_info->thread_load;
1394 for(proc = thread_prochead; proc != NULL; proc = proc->next)
1396 thread_load = (float)(proc->proc_data.utime + proc->proc_data.stime -
1397 proc->saved_utime - proc->saved_stime)
1399 if(thread_load > 100.0f)
1400 thread_load = 100.0f;
1402 pthread->pid = proc->proc_data.pid;
1403 pthread->load = thread_load;
1406 // sprintf(thread_loadtmpbuf, "%d,%.1f,", proc->proc_data.pid, thread_load);
1407 // strcat(thread_loadbuf, thread_loadtmpbuf);
1409 proc->saved_utime = proc->proc_data.utime;
1410 proc->saved_stime = proc->proc_data.stime;
1416 //fill system cpu information
1417 static int fill_system_cpu_info(struct system_info_t *sys_info)
1419 float sys_usage = 0.0f;
1422 // calculate for whole cpu load by average all core load
1423 LOGI_th_samp("calculate for whole cpu load num_of_cpu=%d\n", num_of_cpu);
1424 for(i = 0 ; i < num_of_cpu; i++)
1425 sys_usage += cpus[i].cpu_usage;
1429 if (num_of_cpu != 0)
1431 sys_info->cpu_load = malloc( num_of_cpu * sizeof(*sys_info->cpu_load) );
1432 pcpu_usage = sys_info->cpu_load;
1433 for(i = 0; i < num_of_cpu; i++)
1435 LOGI_th_samp("cpu#%d : %.1f\n" , i, cpus[i].cpu_usage);
1436 *pcpu_usage = cpus[i].cpu_usage;
1441 //fill CPU frequency
1442 sys_info->cpu_frequency = malloc(num_of_cpu * sizeof(float));
1443 if (!sys_info->cpu_frequency) {
1444 LOGE("Cannot alloc cpu freq\n");
1447 get_cpu_frequency(sys_info->cpu_frequency);
1452 static void skip_lines(FILE * fp, unsigned int count)
1454 char *buffer = NULL;
1457 for (index = 0; index != count; ++index)
1458 getline(&buffer, &buflen, fp);
1462 static void skip_tokens(FILE * fp, unsigned int count)
1466 for (index = 0; index != count; ++index)
1470 static void init_network_stat()
1472 manager.fd.networkstat = fopen("/proc/net/dev", "r");
1475 static void get_network_stat(uint32_t *recv, uint32_t *send)
1477 FILE *fp = manager.fd.networkstat;
1478 uintmax_t irecv, isend;
1487 skip_lines(fp, 2); /* strip header */
1489 while (fscanf(fp, "%s", ifname) != EOF)
1490 if (strcmp("lo:", ifname)) {
1491 fscanf(fp, "%" SCNuMAX, &irecv);
1494 fscanf(fp, "%" SCNuMAX, &isend);
1500 skip_tokens(fp, 16);
1503 static void peek_network_stat_diff(uint32_t *recv, uint32_t *send)
1505 static uint32_t irecv_old, isend_old;
1508 get_network_stat(recv, send);
1511 *recv = val_diff(tmp, irecv_old);
1515 *send = val_diff(tmp, isend_old);
1520 static void init_disk_stat(void)
1522 manager.fd.diskstats = fopen("/proc/diskstats", "r");
1525 static void get_disk_stat(uint32_t *reads, uint32_t *sec_reads,
1526 uint32_t *writes, uint32_t *sec_writes)
1528 enum { partition_name_maxlength = 128 };
1529 FILE *fp = manager.fd.diskstats;
1530 char master_partition[partition_name_maxlength] = { 0 };
1532 *reads = *writes = 0;
1533 *sec_reads = *sec_writes = 0;
1543 char partition[partition_name_maxlength];
1544 uintmax_t preads, pwrites;
1545 uintmax_t psec_read, psec_write;
1547 fscanf(fp, "%s", partition);
1548 if (*master_partition
1549 && !strncmp(master_partition, partition,
1550 strlen(master_partition))) {
1552 skip_tokens(fp, 11);
1555 fscanf(fp, "%" SCNuMAX, &preads);
1558 fscanf(fp, "%" SCNuMAX, &psec_read);
1561 fscanf(fp, "%" SCNuMAX, &pwrites);
1564 fscanf(fp, "%" SCNuMAX, &psec_write);
1567 memcpy(master_partition, partition,
1568 partition_name_maxlength);
1569 // FIXME rw size is in sectors
1570 // actualy different disks - different partition sector size (?)
1571 // maybe need convert to bytes like this:
1572 //*read += pread * sec_size;
1573 //*write += pwrite * sec_size;
1575 *reads += (uint32_t)preads;
1576 *writes += (uint32_t)pwrites;
1578 *sec_reads += (uint32_t)psec_read;
1579 *sec_writes += (uint32_t)psec_write;
1585 static void peek_disk_stat_diff(uint32_t *reads, uint32_t *sec_reads,
1586 uint32_t *writes, uint32_t *sec_writes)
1588 static uint32_t reads_old;
1589 static uint32_t sec_reads_old;
1590 static uint32_t writes_old;
1591 static uint32_t sec_writes_old;
1596 get_disk_stat(reads, sec_reads, writes, sec_writes);
1599 *reads = val_diff(tmp, reads_old);
1603 *writes = val_diff(tmp, writes_old);
1607 *sec_reads = val_diff(tmp, sec_reads_old);
1608 sec_reads_old = tmp;
1611 *sec_writes = val_diff(tmp, sec_writes_old);
1612 sec_writes_old = tmp;
1616 static float get_elapsed(void)
1618 static struct timeval old_time = {0, 0};
1619 struct timeval current_time;
1622 gettimeofday(¤t_time, NULL);
1623 elapsed = (current_time.tv_sec - old_time.tv_sec) +
1624 ((float)(current_time.tv_usec - old_time.tv_usec) / 1000000.0f);
1625 old_time.tv_sec = current_time.tv_sec;
1626 old_time.tv_usec = current_time.tv_usec;
1631 static float get_factor(float elapsed)
1633 return 100.0f / ((float)Hertz * elapsed * num_of_cpu);
1636 static uint64_t read_int64_from_file(const char *fname)
1638 FILE *fp = fopen(fname, "r");
1642 if (fscanf(fp, "%lld", &value) != 1)
1648 #define swap_sysfs_relpath(x) ("/sys/kernel/debug/swap/energy/" #x)
1649 #define swap_read_int64(x) (read_int64_from_file(swap_sysfs_relpath(x)))
1650 static uint64_t get_system_lcd_energy()
1652 static const char *PROC_LCD_ENERGY_FILES_GLOBPATTERN =
1653 "/sys/kernel/debug/swap/energy/lcd/*/system";
1654 uint64_t sum_energy = 0;
1657 const int err = glob(PROC_LCD_ENERGY_FILES_GLOBPATTERN, 0,
1661 LOG_ONCE_E("Globbing for LCD failed with error %d\n", err);
1665 for (i = 0; i < glob_buf.gl_pathc; ++i)
1666 sum_energy += read_int64_from_file(glob_buf.gl_pathv[i]);
1668 globfree(&glob_buf);
1672 * Calculates difference between current and previous sample (system).
1673 * Stores mutable state in static variables.
1675 static uint32_t pop_sys_energy_per_device(enum supported_device dev)
1677 static uint64_t cpu_old, flash_old, lcd_old;
1678 uint64_t cpu_new, flash_new, lcd_new;
1679 uint64_t cpu_diff, flash_diff, lcd_diff;
1683 cpu_new = swap_read_int64(cpu_idle/system) +
1684 swap_read_int64(cpu_running/system);
1685 cpu_diff = val_diff(cpu_new, cpu_old);
1687 return (uint32_t)cpu_diff;
1690 flash_new = swap_read_int64(flash_read/system) +
1691 swap_read_int64(flash_write/system);
1692 flash_diff = val_diff(flash_new, flash_old);
1693 flash_old = flash_new;
1694 return (uint32_t)flash_diff;
1696 lcd_new = get_system_lcd_energy();
1697 lcd_diff = val_diff(lcd_new, lcd_old);
1699 return (uint32_t)lcd_diff;
1701 assert(0 && "Unknown device. This should not happen");
1706 // Calculates difference between current and previous sample (app).
1707 // Stores mutable state in static variables.
1708 static uint32_t pop_app_energy_per_device(enum supported_device dev)
1710 static uint64_t cpu_old, flash_old;
1711 uint64_t cpu_new, flash_new;
1712 uint64_t cpu_diff, flash_diff;
1716 cpu_new = swap_read_int64(cpu_running/apps);
1717 cpu_diff = val_diff(cpu_new, cpu_old);
1719 return (uint32_t)cpu_diff;
1721 flash_new = swap_read_int64(flash_read/apps) +
1722 swap_read_int64(flash_write/apps);
1723 flash_diff = val_diff(flash_new, flash_old);
1724 flash_old = flash_new;
1725 return (uint32_t)flash_diff;
1728 * Per-application energy accounting
1729 * is not supported for LCD.
1733 assert(0 && "Unknown device. This should not happen");
1738 static int get_pid_array(int arr[], const int n)
1740 DIR *d = opendir("/proc");
1741 struct dirent *dirent;
1743 pid_t self_pid = getpid();
1746 LOGW("Cannot open /proc dir (%s)\n", strerror(errno));
1750 while ((dirent = readdir(d)) && (count < n)) {
1751 if (dirent->d_type == DT_DIR) {
1753 pid_t pid = strtol(dirent->d_name, &tmp, 10);
1754 if (*tmp == '\0' && pid != self_pid)
1764 static pid_t get_first_target_process(void)
1769 for (i = 0; i < MAX_TARGET_COUNT; i++) {
1770 if (manager.target[i].socket != -1 &&
1771 manager.target[i].pid != -1) {
1772 pid = manager.target[i].pid;
1780 // return log length (>0) for normal case
1781 // return negative value for error
1782 int get_system_info(struct system_info_t *sys_info)
1784 static int event_num = 0;
1785 uint64_t sysmemtotal = 0;
1786 uint64_t sysmemused = 0;
1791 LOGI_th_samp("start\n");
1793 memset(sys_info, 0, sizeof(*sys_info));
1795 // common (cpu, processes, memory)
1796 if (IS_OPT_SET(FL_CPU) ||
1797 IS_OPT_SET(FL_PROCESSES) ||
1798 IS_OPT_SET(FL_MEMORY)) {
1799 const int max_pid_num = 1024; /* ugly hardcode */
1800 int pidarray[max_pid_num];
1802 pid_t first_target_pid = -1;
1804 pidcount = get_pid_array(pidarray, max_pid_num);
1805 LOGI_th_samp("PID count : %d\n", pidcount);
1807 if (update_process_data(pidarray, pidcount, PROCDATA_STAT) < 0) {
1808 LOGE("Failed to update process stat data\n");
1812 * This position is optimized position of timestamp. Just
1813 * before get system cpu data and just after get process cpu
1814 * data because cpu data is changed so fast and variance is so
1817 elapsed = get_elapsed(); /* DO NOT MOVE THIS SENTENCE! */
1818 factor = get_factor(elapsed);
1820 if (update_system_cpu_data(event_num) < 0) {
1821 LOGE("Failed to update system cpu data\n");
1825 if (update_system_cpu_frequency(event_num) < 0) {
1826 LOGE("Failed to update system cpu freq data\n");
1831 * Memory data is changed slowly and variance is not
1832 * remarkable, so memory data is less related with timestamp
1835 if (update_process_data(pidarray, pidcount, PROCDATA_SMAPS) < 0) {
1836 LOGE("Failed to update process smaps data\n");
1840 first_target_pid = get_first_target_process();
1841 if (first_target_pid > 0)
1842 if (update_thread_data(first_target_pid) < 0) {
1843 LOGE("Failed to update thread stat data\n");
1847 if (update_system_memory_data(&sysmemtotal, &sysmemused) < 0) {
1848 LOGE("Failed to update system memory data\n");
1852 if (update_cpus_info(event_num, elapsed) < 0) {
1853 LOGE("Failed to update cpus info\n");
1857 /* calculate process load, memory, app_cpu_usage */
1858 if (fill_system_processes_info(factor, sys_info) < 0) {
1859 LOGE("Failed to fill processes info\n");
1863 /* calculate thread load */
1864 if (fill_system_threads_info(factor, sys_info) < 0) {
1865 LOGE("Failed to fill threads info\n");
1869 if (fill_system_cpu_info(sys_info) < 0) {
1870 LOGE("Failed to fill threads info\n");
1875 if (IS_OPT_SET(FL_MEMORY)) {
1876 sys_info->total_alloc_size = get_total_alloc_size();
1877 sys_info->system_memory_total = sysmemtotal;
1878 sys_info->system_memory_used = sysmemused;
1881 LOGI_th_samp("Fill result structure\n");
1883 if (IS_OPT_SET(FL_DISK)) {
1884 sys_info->total_used_drive = get_total_used_drive();
1885 peek_disk_stat_diff(&sys_info->disk_reads,
1886 &sys_info->disk_sectors_read,
1887 &sys_info->disk_writes,
1888 &sys_info->disk_sectors_write);
1891 if (IS_OPT_SET(FL_NETWORK))
1892 peek_network_stat_diff(&sys_info->network_send_size,
1893 &sys_info->network_receive_size);
1895 if (IS_OPT_SET(FL_DEVICE)) {
1896 sys_info->wifi_status = get_wifi_status();
1897 sys_info->bt_status = get_bt_status();
1898 sys_info->gps_status = get_gps_status();
1899 sys_info->brightness_status = get_brightness_status();
1900 sys_info->camera_status = get_camera_status();
1901 sys_info->sound_status = get_sound_status();
1902 sys_info->audio_status = get_audio_status();
1903 sys_info->vibration_status = get_vibration_status();
1904 sys_info->voltage_status = get_voltage_status();
1905 sys_info->rssi_status = get_rssi_status();
1906 sys_info->video_status = get_video_status();
1907 sys_info->call_status = get_call_status();
1908 sys_info->dnet_status = get_dnet_status();
1911 if (IS_OPT_SET(FL_ENERGY)) {
1913 sys_info->energy = 0; /* not implemented */
1914 for (i = 0; i != supported_devices_count; ++i) {
1915 sys_info->energy_per_device[i] =
1916 pop_sys_energy_per_device(i);
1917 sys_info->app_energy_per_device[i] = (i == DEVICE_LCD)
1918 ? sys_info->energy_per_device[i]
1919 : pop_app_energy_per_device(i);
1923 #ifdef THREAD_SAMPLING_DEBUG
1924 print_sys_info(sys_info);
1928 LOGI_th_samp("exit\n");
1932 /* Some data corrupted. Free allocated data. */
1933 reset_system_info(sys_info);
1934 LOGI_th_samp("fail exit\n");
1938 int initialize_system_info(void)
1942 num_of_cpu = sysconf(_SC_NPROCESSORS_CONF);
1945 Hertz = sysconf(_SC_CLK_TCK);
1946 LOGI("Hertz : %d\n", Hertz);
1950 cpus = (CPU_t*) calloc((num_of_cpu + 1), sizeof(CPU_t));
1953 for(i = 0; i <= num_of_cpu; i++)
1955 cpus[i].cur_load_index = cpus[i].sav_load_index = -1;
1956 cpus[i].cur_freq_index = cpus[i].sav_freq_index = -1;
1961 LOGE("Failed to alloc memory for cpu information\n");
1968 int finalize_system_info(void)
1974 for(i = 0; i < num_of_cpu; i++)
1976 if(cpus[i].pfreq != NULL)
1977 free(cpus[i].pfreq);
1987 static void test_and_close(int *fd)
1994 static void ftest_and_close(FILE **fd)
2002 #define str(x) strr(x)
2003 #define dtest_and_close(fd) do {LOGI("CLOSE " str(fd) "\n");test_and_close(fd);} while(0)
2004 #define dftest_and_close(fd) do {LOGI("CLOSE " str(fd) "\n");ftest_and_close(fd);} while(0)
2005 void close_system_file_descriptors(void)
2007 dtest_and_close(&manager.fd.brightness);
2008 dtest_and_close(&manager.fd.voltage);
2009 dtest_and_close(&manager.fd.procmeminfo);
2011 dftest_and_close(&manager.fd.video);
2012 dftest_and_close(&manager.fd.procstat);
2013 dftest_and_close(&manager.fd.networkstat);
2014 dftest_and_close(&manager.fd.diskstats);
2017 int init_system_file_descriptors(void)
2020 init_brightness_status();
2021 init_voltage_status();
2022 init_update_system_memory_data();
2024 init_video_status();
2025 init_system_cpu_data();
2026 init_network_stat();
2029 if (manager.fd.brightness < 0)
2030 LOGW("brightness file not found\n");
2031 if (manager.fd.voltage < 0)
2032 LOGW("voltage file not found\n");
2033 if (manager.fd.procmeminfo < 0)
2034 LOGW("procmeminfo file not found\n");
2036 if (manager.fd.video == NULL)
2037 LOGW("video file not found\n");
2038 if (manager.fd.procstat == NULL)
2039 LOGW("procstat file not found\n");
2040 if (manager.fd.networkstat == NULL)
2041 LOGW("networkstat file not found\n");
2042 if (manager.fd.diskstats == NULL)
2043 LOGW("diskstat file not found\n");
2047 //CMD SOCKET FUNCTIONS
2048 int fill_target_info(struct target_info_t *target_info)
2050 /* system_info_get_value_bool() changes only 1 byte
2051 so we need to be sure that the integer as a whole is correct */
2052 target_info->bluetooth_supp = 0;
2053 target_info->gps_supp = 0;
2054 target_info->wifi_supp = 0;
2055 target_info->camera_count = 0;
2056 target_info->network_type[0] = 0;
2058 target_info->sys_mem_size = get_system_total_memory();
2059 target_info->storage_size = stat_get_storageinfo(FSINFO_TYPE_TOTAL) *
2062 target_info->bluetooth_supp = is_bluetooth_available();
2063 target_info->gps_supp = is_gps_available();
2064 target_info->wifi_supp = is_wifi_available();
2066 target_info->camera_count = get_camera_count();
2068 get_device_network_type(target_info->network_type, NWTYPE_SIZE);
2071 target_info->max_brightness = get_max_brightness();
2072 target_info->cpu_core_count = sysconf(_SC_NPROCESSORS_CONF);
2076 int sys_stat_prepare(void)
2078 uint32_t reads, writes, sec_reads, sec_writes;
2079 uint32_t recv, send;
2081 peek_disk_stat_diff(&reads, &writes, &sec_reads, &sec_writes);
2082 peek_network_stat_diff(&recv, &send);
2087 static uint32_t msg_data_payload_length(const struct system_info_t *sys_info)
2089 uint32_t len = sizeof(*sys_info);
2091 /* num_of_cpu is unknown at compile time */
2092 len += 2 * num_of_cpu * sizeof(float);
2094 /* subtract pointers */
2095 len -= sizeof(sys_info->cpu_frequency) + sizeof(sys_info->cpu_load);
2096 len -= sizeof(sys_info->thread_load) + sizeof(sys_info->process_load);
2098 if (IS_OPT_SET(FL_CPU))
2099 len += sys_info->count_of_threads *
2100 sizeof(*sys_info->thread_load);
2102 if (IS_OPT_SET(FL_PROCESSES))
2103 len += sys_info->count_of_processes *
2104 sizeof(*sys_info->process_load);
2109 struct msg_data_t *pack_system_info(struct system_info_t *sys_info)
2111 const int len = msg_data_payload_length(sys_info);
2112 struct msg_data_t *msg = NULL;
2116 msg = malloc(MSG_DATA_HDR_LEN + len);
2118 LOGE("Cannot alloc message: %d bytes\n", len);
2122 fill_data_msg_head(msg, NMSG_SYSTEM, 0, len);
2126 if (IS_OPT_SET(FL_CPU)) {
2127 pack_float(p, sys_info->app_cpu_usage);
2129 for (i = 0; i < num_of_cpu; i++) {
2130 if (sys_info->cpu_frequency)
2131 pack_float(p, sys_info->cpu_frequency[i]);
2136 for (i = 0; i < num_of_cpu; i++) {
2137 if (sys_info->cpu_load)
2138 pack_float(p, sys_info->cpu_load[i]);
2143 pack_int32(p, sys_info->count_of_threads);
2144 for (i = 0; i < sys_info->count_of_threads; i++) {
2145 if (sys_info->thread_load) {
2146 pack_int32(p, sys_info->thread_load[i].pid);
2147 pack_float(p, sys_info->thread_load[i].load);
2154 pack_float(p, 0.0); /* pack app_cpu_usage */
2156 for (i = 0; i < num_of_cpu; i++) {
2157 pack_float(p, 0.0); /* pack cpu_frequency */
2158 pack_float(p, 0.0); /* pack cpu_load */
2161 pack_int32(p, 0); /* pack count_of_threads */
2165 if (IS_OPT_SET(FL_PROCESSES)) {
2166 pack_int32(p, sys_info->count_of_processes);
2167 for (i = 0; i < sys_info->count_of_processes; i++) {
2168 if (sys_info->process_load) {
2169 pack_int32(p, sys_info->process_load[i].id);
2170 pack_float(p, sys_info->process_load[i].load);
2177 pack_int32(p, 0); /* pack count_of_processes */
2181 if (IS_OPT_SET(FL_MEMORY)) {
2182 pack_int32(p, sys_info->virtual_memory);
2183 pack_int32(p, sys_info->resident_memory);
2184 pack_int32(p, sys_info->shared_memory);
2185 pack_int32(p, sys_info->pss_memory);
2186 pack_int64(p, sys_info->total_alloc_size);
2187 pack_int64(p, sys_info->system_memory_total);
2188 pack_int64(p, sys_info->system_memory_used);
2190 pack_int32(p, 0); /* pack virtual_memory */
2191 pack_int32(p, 0); /* pack resident_memory */
2192 pack_int32(p, 0); /* pack shared_memory */
2193 pack_int32(p, 0); /* pack pss_memory */
2194 pack_int64(p, (uint64_t) 0); /* pack total_alloc_size */
2195 pack_int64(p, (uint64_t) 0); /* pack system_memory_total */
2196 pack_int64(p, (uint64_t) 0); /* pack system_memory_used */
2199 pack_int32(p, sys_info->total_used_drive);
2200 pack_int32(p, sys_info->disk_reads);
2201 pack_int32(p, sys_info->disk_sectors_read);
2202 pack_int32(p, sys_info->disk_writes);
2203 pack_int32(p, sys_info->disk_sectors_write);
2205 pack_int32(p, sys_info->network_send_size);
2206 pack_int32(p, sys_info->network_receive_size);
2208 pack_int32(p, sys_info->wifi_status);
2209 pack_int32(p, sys_info->bt_status);
2210 pack_int32(p, sys_info->gps_status);
2211 pack_int32(p, sys_info->brightness_status);
2212 pack_int32(p, sys_info->camera_status);
2213 pack_int32(p, sys_info->sound_status);
2214 pack_int32(p, sys_info->audio_status);
2215 pack_int32(p, sys_info->vibration_status);
2216 pack_int32(p, sys_info->voltage_status);
2217 pack_int32(p, sys_info->rssi_status);
2218 pack_int32(p, sys_info->video_status);
2219 pack_int32(p, sys_info->call_status);
2220 pack_int32(p, sys_info->dnet_status);
2222 pack_int32(p, sys_info->energy);
2223 for (i = 0; i != supported_devices_count; ++i)
2224 pack_int32(p, sys_info->energy_per_device[i]);
2225 for (i = 0; i != supported_devices_count; ++i)
2226 pack_int32(p, sys_info->app_energy_per_device[i]);