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 <system_info.h>
51 #include <runtime_info.h>
52 #include <telephony_network.h>
55 #include "da_protocol.h"
64 // defines for runtime environment
67 #define BUFFER_MAX 1024
68 #define LARGE_BUFFER 512
69 #define MIDDLE_BUFFER 256
70 #define SMALL_BUFFER 64
71 #define PROCPATH_MAX 32
72 #define STATUS_STRING_MAX 16
73 #define MAX_NUM_OF_FREQ 16
75 #define MEM_SLOT_TOTAL 0
76 #define MEM_SLOT_FREE 1
77 #define MEM_SLOT_BUFFER 2
78 #define MEM_SLOT_CACHED 3
79 #define MEM_SLOT_MAX 4
81 #define MIN_TICKS_FOR_LOAD 8
82 #define MIN_TOTAL_TICK 10
83 #define SYS_INFO_TICK 100 // TODO : change to (Hertz * profiling period)
85 #define CPUMHZ "cpu MHz"
86 #define DA_PROBE_TIZEN_SONAME "da_probe_tizen.so"
87 #define DA_PROBE_OSP_SONAME "da_probe_osp.so"
88 #define CAMCORDER_FILE "/usr/etc/mmfw_camcorder.ini"
89 #define CAMERA_COUNT_STR "DeviceCount"
97 // declared by greatim
99 static int num_of_cpu = 0;
100 static int num_of_freq = 0;
101 static uint64_t mem_slot_array[MEM_SLOT_MAX];
102 static CPU_t* cpus = NULL;
103 static unsigned long probe_so_size = 0;
106 int get_file_status_no_open(int pfd, const char *filename)
109 char buf[STATUS_STRING_MAX];
111 if (unlikely(pfd < 0)) {
116 lseek(pfd, 0, SEEK_SET); // rewind to start of file
119 if (unlikely(read(pfd, buf, STATUS_STRING_MAX) == -1))
126 // daemon api : get status from file
127 // pfd must not be null
128 int get_file_status(int *pfd, const char *filename)
132 if (likely(pfd != NULL)) {
133 //open if is not open
134 if (unlikely(*pfd < 0)) {
136 *pfd = open(filename, O_RDONLY);
137 if (unlikely(*pfd == -1)) {
138 /* This file may absent in the system */
143 if (unlikely(*pfd < 0)) {
144 //file is open. lets read
145 status = get_file_status_no_open(*pfd, filename);
153 // =============================================================================
154 // device status information getter functions
155 // =============================================================================
156 static int get_wifi_status()
161 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_status);
162 if (unlikely(res < 0)) {
163 LOG_ONCE_W("get error #%d\n", res);
164 wifi_status = VCONFKEY_WIFI_OFF;
170 static int get_bt_status()
172 int bt_status = false;
175 res = vconf_get_int(VCONFKEY_BT_STATUS, &bt_status);
176 if (unlikely(res < 0)) {
177 LOG_ONCE_W("get error #%d\n", res);
178 bt_status = VCONFKEY_BT_STATUS_OFF;
184 static int get_gps_status()
189 res = vconf_get_int(VCONFKEY_LOCATION_ENABLED, &gps_status);
190 if(unlikely(res < 0)) {
191 LOG_ONCE_W("get error #%d\n", res);
192 gps_status = VCONFKEY_LOCATION_GPS_OFF;
193 } else if(gps_status != 0) {
194 res = vconf_get_int(VCONFKEY_LOCATION_GPS_STATE, &gps_status);
195 if (unlikely(res < 0)) {
196 LOG_ONCE_W("get error #%d\n", res);
197 gps_status = VCONFKEY_LOCATION_GPS_OFF;
204 static void init_brightness_status()
208 struct dirent *dir_entry;
209 char fullpath[PATH_MAX];
211 dir_info = opendir(BRIGHTNESS_PARENT_DIR);
212 if (dir_info != NULL) {
213 while ((dir_entry = readdir(dir_info)) != NULL) {
214 if (strcmp(dir_entry->d_name, ".") == 0 ||
215 strcmp(dir_entry->d_name, "..") == 0)
217 else { /* first directory */
219 BRIGHTNESS_PARENT_DIR "/%s/"
222 get_file_status(&manager.fd.brightness,
231 get_file_status(&manager.fd.brightness, EMUL_BRIGHTNESSFD);
235 static int get_brightness_status()
237 return get_file_status_no_open(manager.fd.brightness, EMUL_BRIGHTNESSFD);
240 static int get_max_brightness()
242 int maxbrightnessfd = -1;
243 static int max_brightness = -1;
245 if (__builtin_expect(max_brightness < 0, 0)) {
248 struct dirent* dir_entry;
249 char fullpath[PATH_MAX];
251 dir_info = opendir(BRIGHTNESS_PARENT_DIR);
252 if (dir_info != NULL) {
253 while((dir_entry = readdir(dir_info)) != NULL) {
254 if (strcmp(dir_entry->d_name, ".") == 0 ||
255 strcmp(dir_entry->d_name, "..") == 0)
259 BRIGHTNESS_PARENT_DIR "/%s/" MAX_BRIGHTNESS_FILENAME,
261 max_brightness = get_file_status(&maxbrightnessfd, fullpath);
268 #else /* DEVICE_ONLY */
269 max_brightness = get_file_status(&maxbrightnessfd, EMUL_MAX_BRIGHTNESSFD);
270 #endif /* DEVICE_ONLY */
273 if (maxbrightnessfd != -1)
274 close(maxbrightnessfd);
276 return max_brightness;
279 static void init_video_status()
281 manager.fd.video = fopen(MFCFD, "r");
284 static int get_video_status()
286 int video_status = 0;
288 FILE *video_fp = manager.fd.video;
291 if (video_fp == NULL) // file is not open
297 ret = fscanf(video_fp, "%s", stat);
300 if(strncmp(stat,"active",6) == 0)
306 static int get_rssi_status()
309 int flightmode_status;
313 res = vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE,
315 if(unlikely(res < 0)) {
316 LOG_ONCE_W("get err #%d <%s>\n", res,
317 VCONFKEY_TELEPHONY_FLIGHT_MODE);
318 flightmode_status = 0;
321 if(!flightmode_status) {
322 res = vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &rssi_status);
323 if(unlikely(res < 0)) {
324 LOG_ONCE_W("rssi get err #%d\n", res);
325 rssi_status = VCONFKEY_TELEPHONY_RSSI_0;
328 rssi_status = VCONFKEY_TELEPHONY_RSSI_0;
336 static int get_call_status()
341 res = vconf_get_int(VCONFKEY_CALL_STATE, &call_status);
342 if(unlikely(res < 0)) {
343 LOG_ONCE_W("get err #%d\n", res);
344 call_status = VCONFKEY_CALL_OFF;
351 static int get_dnet_status()
353 int dnet_status = false;
356 res = vconf_get_int(VCONFKEY_DNET_STATE, &dnet_status);
357 if(unlikely(res < 0)) {
358 LOG_ONCE_W("get err #%d <%s>\n", res, VCONFKEY_DNET_STATE);
359 dnet_status = VCONFKEY_DNET_OFF;
365 static int get_camera_status()
367 int camera_status = 0;
369 if (unlikely(vconf_get_int(VCONFKEY_CAMERA_STATE, &camera_status) < 0)) {
370 camera_status = VCONFKEY_CAMERA_STATE_NULL;
373 return camera_status;
376 // this means silent mode?
377 static int get_sound_status()
379 int sound_status = 0;
382 res = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL,
384 if (unlikely(res < 0)) {
385 LOG_ONCE_W("get err #%d\n", res);
392 static int get_audio_status()
397 res = vconf_get_int(VCONFKEY_SOUND_STATUS,
399 if (unlikely(res < 0)) {
400 LOG_ONCE_W("get err #%d\n", res);
407 static int get_vibration_status()
409 int vibration_status = 0;
412 res = vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL,
414 if(unlikely(res < 0)) {
415 LOG_ONCE_W("get err #%d\n", res);
416 vibration_status = 0;
419 return vibration_status;
422 static void init_voltage_status()
424 get_file_status(&manager.fd.voltage, VOLTAGEFD);
427 static int get_voltage_status()
429 return get_file_status_no_open(manager.fd.voltage, VOLTAGEFD);
432 // =====================================================================
433 // cpu information getter functions
434 // =====================================================================
435 static void get_cpu_frequency(float *freqs)
437 char filename[MIDDLE_BUFFER];
438 char freq_str[SMALL_BUFFER];
443 for (cpu_n = 0; cpu_n < num_of_cpu; cpu_n++)
449 snprintf(filename, MIDDLE_BUFFER,
450 "/sys/devices/system/cpu/cpu%d/online", cpu_n);
452 f = fopen(filename, "r");
454 LOGI_th_samp("file not found <%s\n>", filename);
460 snprintf(filename, MIDDLE_BUFFER,
461 "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", cpu_n);
462 f = fopen(filename, "r");
466 LOGI_th_samp("core #%d diasabled\n", cpu_n);
469 //core enabled, get frequency
470 fscanf(f, "%s", freq_str);
471 freqs[cpu_n] = atof(freq_str);
472 LOGI_th_samp("core #%d freq = %.0f\n", cpu_n, freqs[cpu_n]);
482 // ========================================================================
483 // get cpu and memory info for each process and whole system
484 // ========================================================================
485 typedef struct _proc_node {
487 unsigned long long saved_utime;
488 unsigned long long saved_stime;
490 struct _proc_node *next;
493 static procNode *prochead = NULL;
494 static procNode *thread_prochead = NULL;
496 static procNode* find_node(procNode *head, pid_t pid)
501 if (t->proc_data.pid == pid)
511 static procNode* add_node(procNode **head, pid_t pid)
515 n = (procNode *) malloc(sizeof(procNode));
517 LOGE("Not enough memory, add cpu info node failied");
521 n->proc_data.pid = pid;
529 static int del_node(procNode **head, pid_t pid)
536 /* LOGI("dell t=%d\n",t); */
538 if (t->proc_data.pid == pid) {
540 prev->next = t->next;
542 *head = (*head)->next;
550 /* LOGI("ret 0\n"); */
554 static int del_notfound_node(procNode **head)
556 procNode *proc, *prev;
558 for(proc = *head; proc != NULL; )
564 prev->next = proc->next;
570 *head = (*head)->next;
584 static int reset_found_node(procNode *head)
587 for(proc = head; proc != NULL; proc = proc->next)
594 // return 0 for normal case
595 // return negative value for error case
596 static int parse_proc_stat_file_bypid(char *path, proc_t* P)
598 char filename[PROCPATH_MAX];
599 char buf[BUFFER_MAX];
603 // read from stat file
604 sprintf(filename, "%s/stat", path);
605 fd = open(filename, O_RDONLY, 0);
607 if(unlikely(fd == -1)){
611 num = read(fd, buf, BUFFER_MAX);
614 if(unlikely(num <= 0)){
615 LOGE("nothing read from '%s'\n", filename);
617 } else if(num == BUFFER_MAX)
625 abuf = strchr(buf, '(') + 1;
626 bbuf = strrchr(buf, ')');
628 if(unlikely(num >= sizeof(P->command)))
629 num = sizeof(P->command) - 1;
630 memcpy(P->command, abuf, num);
631 P->command[num] = '\0';
639 "%lu %lu %lu %lu %lu "
640 "%Lu %Lu %Lu %Lu " // utime stime cutime cstime
648 &P->ppid, &P->pgrp, &P->sid, &P->tty_nr, &P->tty_pgrp,
649 &P->flags, &P->minor_fault, &P->cminor_fault, &P->major_fault, &P->cmajor_fault,
650 &P->utime, &P->stime, &P->cutime, &P->cstime,
651 &P->priority, &P->nice,
659 if(P->numofthread == 0)
665 // return 0 for normal case
666 // return negative value for error case
667 static int parse_proc_smaps_file_bypid(char *path, proc_t* P)
669 #define MIN_SMAP_BLOCKLINE 50
671 char filename[PROCPATH_MAX];
672 char buf[MIDDLE_BUFFER];
673 char numbuf[SMALL_BUFFER];
676 // reset pss size of proc_t
680 // read from smaps file
681 sprintf(filename, "%s/smaps", path);
682 fp = fopen(filename, "r");
688 if(unlikely(probe_so_size == 0)) // probe so size is not abtained
691 while(fgets(buf, MIDDLE_BUFFER, fp) != NULL)
693 if(strncmp(buf, "Pss:", 4) == 0) // line is started with "Pss:"
695 sscanf(buf, "Pss:%s kB", numbuf);
696 P->pss += atoi(numbuf);
699 probe_so_size += atoi(numbuf);
700 is_probe_so = 0; // reset search flag
703 else if(strncmp(buf, "Shared", 6) == 0) // line is started with "Shared"
706 p = strstr(buf, ":");
708 sscanf(p, ":%s kB", numbuf);
709 P->sh_mem += atoi(numbuf);
715 if (is_probe_so == 0 && strlen(buf) > MIN_SMAP_BLOCKLINE)
717 // first we find probe so section
718 if(strstr(buf, DA_PROBE_TIZEN_SONAME) != NULL ||
719 strstr(buf, DA_PROBE_OSP_SONAME) != NULL)
736 else // we know about probe.so size already
738 while(fgets(buf, MIDDLE_BUFFER, fp) != NULL)
740 if(strncmp(buf, "Pss:", 4) == 0)
742 sscanf(buf, "Pss:%s kB", numbuf);
743 P->pss += atoi(numbuf);
745 else if(strncmp(buf, "Shared", 6) == 0) // line is started with "Shared"
748 p = strstr(buf, ":");
750 sscanf(p, ":%s kB", numbuf);
751 P->sh_mem += atoi(numbuf);
757 P->pss -= probe_so_size;
764 // return 0 for normal case
765 // return positive value for non critical case
766 // return negative value for critical case
767 static int update_process_data(int* pidarray, int pidcount, enum PROCESS_DATA datatype)
769 static struct stat sb;
771 char buf[PROCPATH_MAX];
774 for(i = 0; i < pidcount; i++)
776 /* LOGI("#%d\n", i); */
777 if (pidarray[i] == 0) // pid is invalid
783 sprintf(buf, "/proc/%d", pidarray[i]);
784 /* LOGI("#->%s\n", buf); */
785 if (unlikely(stat(buf, &sb) == -1)) // cannot access anymore
787 /* LOGI("#del from prochead=%d\n", prochead); */
788 del_node(&prochead, pidarray[i]);
793 /* LOGI("find node = %d\n", procnode); */
794 if ((procnode = find_node(prochead, pidarray[i])) == NULL) // new process
796 /* LOGI("proc node1 = %d\n", procnode); */
797 procnode = add_node(&prochead, pidarray[i]);
798 if(datatype == PROCDATA_STAT)
800 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
802 LOGE("Failed to get proc stat file by pid(%d)\n", pidarray[i]);
806 procnode->saved_utime = procnode->proc_data.utime;
807 procnode->saved_stime = procnode->proc_data.stime;
810 else if(datatype == PROCDATA_SMAPS)
812 if (unlikely((ret = parse_proc_smaps_file_bypid(buf, &(procnode->proc_data))) < 0))
814 LOGE("Failed to get proc smaps file by pid(%d)\n", pidarray[i]);
826 /* LOGI("proc node2 = %d\n", procnode); */
827 if(datatype == PROCDATA_STAT)
829 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
831 LOGE("Failed to get proc stat file by pid(%d)\n", pidarray[i]);
837 else if(datatype == PROCDATA_SMAPS)
839 if (unlikely((ret = parse_proc_smaps_file_bypid(buf, &(procnode->proc_data))) < 0))
841 LOGE("Failed to get proc smaps file by pid(%d)\n", pidarray[i]);
852 /* LOGI("del_notfound_node\n"); */
853 del_notfound_node(&prochead);
854 /* LOGI("reset_found_node\n"); */
855 reset_found_node(prochead);
857 /* LOGI("ret %d\n", ret); */
861 static int update_system_cpu_frequency(int cur_index)
863 char buf[SMALL_BUFFER];
864 char filename[SMALL_BUFFER];
868 // execute this block only once
869 if(unlikely(num_of_freq <= 0))
873 if((fp = fopen(CPUNUM_OF_FREQ, "r")) != NULL)
875 while(fgets(buf, SMALL_BUFFER, fp) != NULL)
883 /* This file may absent in the system */
886 for(i = 0; i < num_of_cpu; i++)
888 if(cpus[i].pfreq == NULL && num_of_freq)
890 cpus[i].pfreq = (cpufreq_t*) calloc(num_of_freq, sizeof(cpufreq_t));
895 sprintf(filename, CPUNUM_OF_FREQ);
896 // update cpu frequency information
897 for(i = 0; i < num_of_cpu; i++)
899 filename[27] = (char)('0' + i);
900 fp = fopen(filename, "r");
903 for(j = 0; j < num_of_freq; j++)
905 if(fgets(buf, SMALL_BUFFER, fp) != NULL)
907 sscanf(buf, "%lu %Lu", &(cpus[i].pfreq[j].freq),
908 &(cpus[i].pfreq[j].tick));
910 else // cannot read anymore from frequency info file
915 cpus[i].cur_freq_index = cur_index;
917 else // cannot load cpu frequency information
925 // return 0 for normal case
926 // return negative value for error
927 static void init_system_cpu_data()
929 manager.fd.procstat = fopen(PROCSTAT, "r");
932 static int update_system_cpu_data(int cur_index)
936 FILE* fp = manager.fd.procstat;
938 char buf[BUFFER_MAX];
946 if(fgets(buf, sizeof(buf), fp) == NULL)
948 LOGE("Failed to read first line of " PROCSTAT "\n");
952 /* LOGI("scan; cpus = %d\n", cpus); */
954 cpus[num_of_cpu].x = 0;
955 cpus[num_of_cpu].y = 0;
956 cpus[num_of_cpu].z = 0;
957 num = sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
967 cpus[num_of_cpu].cur_load_index = cur_index;
970 LOGE("Failed to read from " PROCSTAT "\n");
976 /* LOGI("cpu num = %d\n", num_of_cpu); */
977 // and just in case we're 2.2.xx compiled without SMP support...
980 cpus[0].id = cpus[1].id = 0;
981 memcpy(cpus, &cpus[1], sizeof(tic_t) * 8);
982 cpus[0].cur_load_index = cur_index;
984 else if(num_of_cpu > 1)
987 // now value each separate cpu's tics
988 for(i = 0; i < num_of_cpu; i++)
990 if(fgets(buf, sizeof(buf), fp) != NULL)
995 num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
997 &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i,
998 &cpus[i].w, &cpus[i].x, &cpus[i].y, &cpus[i].z);
1001 LOGI_th_samp("Readed %d stats of %dth cpu\n", num, i);
1002 cpus[i].cur_load_index = cur_index;
1004 else // buf is not cpu core tick information
1008 else // cannot read anymore from /proc/stat file
1022 // return 0 for normal case
1023 // return negative value for error
1024 static void init_update_system_memory_data()
1026 manager.fd.procmeminfo = open(PROCMEMINFO, O_RDONLY);
1029 static int update_system_memory_data(uint64_t *memtotal, uint64_t *memused)
1031 int meminfo_fd = manager.fd.procmeminfo;
1034 char buf[BUFFER_MAX];
1035 static const mem_t mem_table[] = {
1036 {"Buffers", (unsigned long *)&mem_slot_array[MEM_SLOT_BUFFER]},
1037 {"Cached", (unsigned long *)&mem_slot_array[MEM_SLOT_CACHED]},
1038 {"MemFree", (unsigned long *)&mem_slot_array[MEM_SLOT_FREE]},
1039 {"MemTotal", (unsigned long *)&mem_slot_array[MEM_SLOT_TOTAL]},
1041 const int mem_table_size = sizeof(mem_table) / sizeof(mem_t);
1043 if (meminfo_fd == -1)
1046 lseek(meminfo_fd, 0L, SEEK_SET);
1047 if((num = read(meminfo_fd, buf, BUFFER_MAX)) < 0)
1049 LOGE("Failed to read from " PROCMEMINFO "\n");
1053 if(num == BUFFER_MAX)
1057 // LOGI("buffer=<%s>\n", buf);
1059 num = 0; // number of found element
1061 for( ;num < mem_table_size ; )
1063 tail = strchr(head, ':');
1067 for(i = 0; i < mem_table_size; i++)
1069 if(strcmp(head, mem_table[i].name) == 0) // found
1072 *(mem_table[i].slot) = strtoul(head, &tail, 10);
1077 if(i == mem_table_size) // cannot find entry
1081 tail = strchr(head, '\n');
1086 /* LOGI("Buffers = %016LX\n", mem_slot_array[MEM_SLOT_BUFFER]); */
1087 /* LOGI("Cached = %016LX\n", mem_slot_array[MEM_SLOT_CACHED]); */
1088 /* LOGI("MemFree = %016LX\n", mem_slot_array[MEM_SLOT_FREE]); */
1089 /* LOGI("MemTotal= %016LX\n", mem_slot_array[MEM_SLOT_TOTAL]); */
1090 if(num == mem_table_size) // find all element
1092 *memtotal = mem_slot_array[MEM_SLOT_TOTAL];
1093 *memused = mem_slot_array[MEM_SLOT_TOTAL] - mem_slot_array[MEM_SLOT_FREE] -
1094 mem_slot_array[MEM_SLOT_BUFFER] - mem_slot_array[MEM_SLOT_CACHED];
1097 *memtotal *= 1024; // change to Byte
1098 *memused *= 1024; // change to Byte
1103 LOGE("Cannot find all neccessary element in meminfo\n");
1109 // return 0 for error case
1110 // return system total memory in MB
1112 unsigned long get_system_total_memory()
1114 int meminfo_fd = manager.fd.procmeminfo;
1117 char buf[BUFFER_MAX];
1118 static const char* memtotalstr = "MemTotal";
1119 unsigned long totalmem = 0;
1121 if (meminfo_fd == -1)
1124 lseek(meminfo_fd, 0L, SEEK_SET);
1126 if((num = read(meminfo_fd, buf, BUFFER_MAX)) < 0)
1128 LOGE("Failed to read from " PROCMEMINFO "\n");
1132 if(num == BUFFER_MAX)
1139 tail = strchr(head, ':');
1143 if(strcmp(head, memtotalstr) == 0) // found
1146 totalmem = strtoul(head, &tail, 10);
1151 tail = strchr(head, '\n');
1157 return (totalmem * 1024);
1160 // ===============================================================
1161 // disk information getter functions
1162 // ===============================================================
1163 static int get_fsinfo(const char* path, int type)
1169 if (statfs(path, &buf) < 0)
1174 total = (int)((long long)(buf.f_bsize / 1024LL * buf.f_blocks) / 1024LL);
1175 free = (int)((long long)(buf.f_bsize / 1024LL * buf.f_bavail) / 1024LL);
1177 /* LOGI("File storage total(%d), free(%d)\n", total, free); */
1178 if (type == FSINFO_TYPE_TOTAL)
1182 else if (type == FSINFO_TYPE_FREE)
1190 static int stat_get_storageinfo(int type)
1192 return get_fsinfo(UMSFD, type);
1195 static int stat_get_cardinfo(int type)
1197 if (access(MMCBLKFD, F_OK) < 0)
1202 return get_fsinfo(MMCFD, type);
1206 static int get_total_drive()
1209 int storage = stat_get_storageinfo(FSINFO_TYPE_TOTAL);
1210 int card = stat_get_cardinfo(FSINFO_TYPE_TOTAL);
1212 if (storage < 0 && card < 0)
1217 total = storage + card;
1222 static int get_total_used_drive()
1226 int storage = stat_get_storageinfo(FSINFO_TYPE_FREE);
1227 int card = stat_get_cardinfo(FSINFO_TYPE_FREE);
1229 if (storage < 0 && card < 0)
1231 LOGI_th_samp("total_used_drive = -1\n");
1235 free = storage + card;
1236 total = get_total_drive() - free;
1238 LOGI_th_samp("total_used_drive = %d\n", total);
1243 static int update_thread_data(int pid)
1245 static struct stat sb;
1247 char path[PROCPATH_MAX];
1248 char buf[PROCPATH_MAX];
1250 DIR *taskdir = NULL;
1251 struct dirent *entry = NULL;
1254 sprintf(path, "/proc/%d/task", pid);
1256 if(!(taskdir = opendir(path)))
1258 LOGE("task not found '%s'\n", path);
1262 while((entry = readdir(taskdir)) != NULL)
1264 if(*entry->d_name > '0' && *entry->d_name <= '9')
1266 tid = atoi(entry->d_name);
1267 sprintf(buf, "/proc/%d/task/%d", pid, tid);
1269 if(unlikely(stat(buf, &sb) == -1))
1271 del_node(&thread_prochead, tid);
1276 if((procnode = find_node(thread_prochead, tid)) == NULL)
1278 procnode = add_node(&thread_prochead, tid);
1279 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
1281 LOGE("Failed to get proc stat file by tid(%d). add node\n", tid);
1285 procnode->saved_utime = procnode->proc_data.utime;
1286 procnode->saved_stime = procnode->proc_data.stime;
1287 /* LOGI("data updated\n"); */
1292 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
1294 LOGE("Failed to get proc stat file by tid(%d). node exist\n", tid);
1300 del_notfound_node(&thread_prochead);
1301 reset_found_node(thread_prochead);
1307 // ========================================================================
1308 // overall information getter functions
1309 // ========================================================================
1311 // this code is not necessary anymore
1313 static void get_app_info(const char* binary_path, char* width,
1314 char* height, char* theme, char* version,
1315 char* scale, char* removable,
1322 char pkg_info_path [PATH_MAX];
1323 char buffer [BUFFER_MAX];
1325 sprintf(pkg_info_path, "/opt/share/applications/%s.desktop", pkg_name);
1327 fd = open(pkg_info_path, O_RDONLY);
1330 LOGE("Cannot open %s", pkg_info_path);
1334 fcntl( fd, F_SETFD, FD_CLOEXEC );
1336 LOGI("get_app_info - After open pkg_info_path\n");
1340 res = read(fd, buffer, BUFFER_MAX);
1353 LOGI("read buffer ===%s===\n", buffer);
1354 for (i = 0; i < res; i++)
1356 if (i < res - 22 && strncmp(&buffer[i], "X-SLP-BaseLayoutWidth=", 22) == 0)
1358 for (j = 0; j < res; j ++)
1360 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1362 LOGI("width :::: ");
1363 strncpy(width, &(buffer[i+22]), j-22);
1364 LOGI("%s\n", width);
1370 else if (i < res - 23 && strncmp(&buffer[i], "X-SLP-BaseLayoutHeight=", 23) == 0)
1372 for (j = 0; j < res; j ++)
1374 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1376 LOGI("height :::: ");
1377 strncpy(height, &(buffer[i+23]), j-23);
1378 LOGI("%s\n", height);
1384 else if (i < res - 6 && (strncmp(&buffer[i], "theme=", 6) == 0 || strncmp(&buffer[i], "Theme=", 6) == 0))
1386 for (j = 0; j < res; j ++)
1388 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1390 LOGI("theme :::: ");
1391 strncpy(theme, &(buffer[i+6]), j-6);
1392 LOGI("%s\n", theme);
1398 else if (i < res - 8 && (strncmp(&buffer[i], "Version=", 8) == 0 || strncmp(&buffer[i], "version=", 8) == 0))
1400 for (j = 0; j < res; j ++)
1402 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1404 LOGI("version :::: ");
1405 strncpy(version, &(buffer[i+8]), j-8);
1406 LOGI("%s\n", version);
1412 else if (i < res - 24 && strncmp(&buffer[i], "X-SLP-IsHorizontalScale=", 24) == 0)
1414 for (j = 0; j < res; j ++)
1416 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1418 LOGI("scale :::: ");
1419 strncpy(scale, &(buffer[i+24]), j-24);
1420 LOGI("%s\n", scale);
1426 else if (i < res - 16 && strncmp(&buffer[i], "X-SLP-Removable=", 16) == 0)
1428 for (j = 0; j < res; j ++)
1430 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1432 LOGI("removable :::: ");
1433 strncpy(removable, &(buffer[i+16]), j-16);
1434 LOGI("%s\n", removable);
1440 else if (i < res - 8 && (strncmp(&buffer[i], "Comment=", 8) == 0 || strncmp(&buffer[i], "comment=", 8) == 0))
1442 for (j = 0; j < res; j ++)
1444 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1446 LOGI("comments :::: ");
1447 strncpy(comment, &(buffer[i+8]), j-8);
1448 LOGI("%s\n", comment);
1460 int get_camera_count()
1465 char buf[BUFFER_MAX];
1467 fp = fopen(CAMCORDER_FILE, "r");
1470 size = strlen(CAMERA_COUNT_STR);
1472 while(fgets(buf, BUFFER_MAX, fp) != NULL)
1474 if(strncmp(buf, CAMERA_COUNT_STR, size) == 0) {
1475 sscanf(buf, CAMERA_COUNT_STR " = %d", &count);
1488 static int get_device_network_type(char* buf, int buflen)
1493 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.cdma", &bool_var);
1494 if(bool_var) len += sprintf(buf + len, "CDMA,");
1495 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.edge", &bool_var);
1496 if(bool_var) len += sprintf(buf + len, "EDGE,");
1497 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.gprs", &bool_var);
1498 if(bool_var) len += sprintf(buf + len, "GPRS,");
1499 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.gsm", &bool_var);
1500 if(bool_var) len += sprintf(buf + len, "GSM,");
1501 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.hsdpa", &bool_var);
1502 if(bool_var) len += sprintf(buf + len, "HSDPA,");
1503 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.hspa", &bool_var);
1504 if(bool_var) len += sprintf(buf + len, "HSPA,");
1505 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.hsupa", &bool_var);
1506 if(bool_var) len += sprintf(buf + len, "HSUPA,");
1507 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.umts", &bool_var);
1508 if(bool_var) len += sprintf(buf + len, "UMTS,");
1509 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.lte", &bool_var);
1510 if(bool_var) len += sprintf(buf + len, "LTE,");
1519 static int get_device_availability_info(char* buf, int buflen)
1521 int camera_count = 0;
1522 bool blue_support = false;
1523 bool gps_support = false;
1524 bool wifi_support = false;
1525 char* networktype = NULL;
1527 char network_type[128];
1530 system_info_get_platform_bool("tizen.org/feature/network.bluetooth", &blue_support);
1531 camera_count = get_camera_count();
1532 system_info_get_platform_bool("tizen.org/feature/location.gps", &gps_support);
1533 network_len = get_device_network_type(networktype, 128);
1534 system_info_get_platform_bool("tizen.org/feature/network.wifi", &wifi_support);
1536 loglen += sprintf(buf, "%d`,%d`,%d`,%d`,",
1542 if(network_type != NULL && network_len > 0) {
1543 loglen += sprintf(buf + loglen, "%s", networktype);
1550 int get_device_info(char* buffer, int buffer_len)
1554 char width[BUFFER_MAX];
1555 char height[BUFFER_MAX];
1556 char theme[BUFFER_MAX];
1557 char version[BUFFER_MAX];
1558 char scale[BUFFER_MAX];
1559 char removable[BUFFER_MAX];
1560 char comment[BUFFER_MAX * 2];
1562 memset(width, 0, sizeof(width));
1563 memset(height, 0, sizeof(height));
1564 memset(theme, 0, sizeof(theme));
1565 memset(version, 0, sizeof(version));
1566 memset(scale, 0, sizeof(scale));
1567 memset(removable, 0, sizeof(removable));
1568 memset(comment, 0, sizeof(comment));
1570 res += sprintf(buffer, "%lu`,%d`,", get_system_total_memory(), get_total_drive());
1571 res += get_device_availability_info(buffer + res, buffer_len - res);
1572 res += sprintf(buffer + res, "`,%d", get_max_brightness());
1574 res += sprintf(buffer + res, "`,`,`,`,`,`,`,");
1575 // res += sprintf(buffer + res, "`,%s`,%s`,%s`,%s`,%s`,%s`,%s", width, height, theme, version, scale, removable, comment);
1580 int update_cpus_info(int event_num, float elapsed)
1584 // calculate for system cpu load
1586 for(i = 0; i < num_of_cpu; i++)
1588 for(i = num_of_cpu; i <= num_of_cpu; i++)
1591 LOGI_th_samp("CPU #%d\n", i);
1592 cpuptr = &(cpus[i]);
1594 if(cpuptr->cur_load_index == event_num)
1596 if(cpuptr->sav_load_index == event_num - 1) // previous sampling is just before 1 period
1598 cpuptr->idle_ticks = cpuptr->i - cpuptr->i_sav;
1599 if(unlikely(cpuptr->idle_ticks < 0))
1601 cpuptr->idle_ticks = 0;
1603 cpuptr->total_ticks = (cpuptr->u - cpuptr->u_sav) +
1604 (cpuptr->s - cpuptr->s_sav) +
1605 (cpuptr->n - cpuptr->n_sav) +
1606 cpuptr->idle_ticks +
1607 (cpuptr->w - cpuptr->w_sav) +
1608 (cpuptr->x - cpuptr->x_sav) +
1609 (cpuptr->y - cpuptr->y_sav) +
1610 (cpuptr->z - cpuptr->z_sav);
1611 if(cpuptr->total_ticks < MIN_TOTAL_TICK)
1613 cpuptr->cpu_usage = 0.0f;
1617 cpuptr->cpu_usage = (1.0f - ((float)cpuptr->idle_ticks /
1618 (float)cpuptr->total_ticks)) * 100.0f;
1620 // if(i != num_of_cpu)
1622 // idle_tick_sum += cpuptr->idle_ticks;
1623 // total_tick_sum += cpuptr->total_ticks;
1625 LOGI_th_samp("System cpu usage log : %d, %Ld, %Ld\n",
1626 i, cpuptr->idle_ticks, cpuptr->total_ticks);
1627 if(unlikely(cpuptr->cpu_usage < 0))
1629 cpuptr->cpu_usage = 0.0f;
1632 else // previous sampling is not just before 1 period
1634 // assume non idle ticks happen in 1 profiling period
1635 // because sampling is not available just before 1 profiling period
1636 cpuptr->idle_ticks = (cpuptr->u - cpuptr->u_sav) +
1637 (cpuptr->s - cpuptr->s_sav) +
1638 (cpuptr->n - cpuptr->n_sav) +
1639 (cpuptr->w - cpuptr->w_sav) +
1640 (cpuptr->x - cpuptr->x_sav) +
1641 (cpuptr->y - cpuptr->y_sav) +
1642 (cpuptr->z - cpuptr->z_sav);
1643 cpuptr->total_ticks = (long long)(Hertz * elapsed);
1644 if(unlikely(cpuptr->total_ticks < 1))
1645 cpuptr->total_ticks = 1;
1646 cpuptr->cpu_usage = ((float)cpuptr->idle_ticks /
1647 (float)cpuptr->total_ticks) * 100.0f;
1648 if(unlikely(cpuptr->cpu_usage > 100.0f))
1650 cpuptr->cpu_usage = 100.0f;
1655 cpuptr->u_sav = cpuptr->u;
1656 cpuptr->s_sav = cpuptr->s;
1657 cpuptr->n_sav = cpuptr->n;
1658 cpuptr->i_sav = cpuptr->i;
1659 cpuptr->w_sav = cpuptr->w;
1660 cpuptr->x_sav = cpuptr->x;
1661 cpuptr->y_sav = cpuptr->y;
1662 cpuptr->z_sav = cpuptr->z;
1663 cpuptr->sav_load_index = cpuptr->cur_load_index;
1667 cpuptr->cpu_usage = 0.0f;
1671 // calculate for cpu core load that failed to get tick information
1675 LOGI("ticks1 : %Ld, %Ld\n", idle_tick_sum, total_tick_sum);
1676 idle_tick_sum = cpus[num_of_cpu].idle_ticks - idle_tick_sum;
1677 total_tick_sum = cpus[num_of_cpu].total_ticks - total_tick_sum;
1678 LOGI("ticks2 : %Ld, %Ld\n", idle_tick_sum, total_tick_sum);
1679 if(total_tick_sum >= MIN_TICKS_FOR_LOAD)
1680 sys_usage = (1.0f - ((float)idle_tick_sum / (float)total_tick_sum)) * 100.0f;
1683 if(sys_usage < 0.0f) sys_usage = 0.0f;
1684 else if(sys_usage > 100.0f) sys_usage = 100.0f;
1686 for(i = 0; i < num_of_cpu; i++)
1688 if(failed_cpu & (1 << i))
1690 cpus[i].cpu_usage = sys_usage;
1698 int fill_system_processes_info(float factor, struct system_info_t * sys_info)
1704 unsigned long virtual = 0;
1705 unsigned long resident = 0;
1706 unsigned long shared = 0;
1707 unsigned long pssmem = 0;
1709 float app_cpu_usage = 0.0;
1711 LOGI_th_samp("prochead = %X\n", (unsigned int)prochead);
1712 for(proc = prochead; proc != NULL; proc = proc->next)
1714 //increment process count
1715 sys_info->count_of_processes++; //maybe wrong
1717 sys_info->process_load = malloc (
1718 sys_info->count_of_processes *
1719 sizeof(*sys_info->process_load)
1722 for(proc = prochead; proc != NULL; proc = proc->next)
1724 LOGI_th_samp("proc#%d (%d %d),(%d %d) (%d) %f\n",
1726 (unsigned int)proc->proc_data.utime, (unsigned int)proc->proc_data.stime ,
1727 (unsigned int)proc->saved_utime, (unsigned int)proc->saved_stime,
1728 (int)(proc->proc_data.utime + proc->proc_data.stime - proc->saved_utime - proc->saved_stime),
1730 proc->saved_utime + proc->saved_stime -
1731 proc->proc_data.utime - proc->proc_data.stime
1733 thread_load = (float)(proc->proc_data.utime + proc->proc_data.stime -
1734 proc->saved_utime - proc->saved_stime) * factor;
1736 if(thread_load > 100.0f)
1737 thread_load = 100.0f;
1739 //num_thread += proc->proc_data.numofthread;
1740 virtual += proc->proc_data.vir_mem; // Byte
1741 resident += (proc->proc_data.res_memblock * 4); // KByte
1742 pssmem += (proc->proc_data.pss); // KByte
1743 shared += (proc->proc_data.sh_mem); // KByte
1744 ticks += (proc->proc_data.utime + proc->proc_data.stime -
1745 proc->saved_utime - proc->saved_stime);
1747 proc->saved_utime = proc->proc_data.utime;
1748 proc->saved_stime = proc->proc_data.stime;
1751 sys_info->process_load[i].id = proc->proc_data.pid;
1752 sys_info->process_load[i].load = thread_load;
1757 app_cpu_usage = (float)ticks * factor;
1758 if(app_cpu_usage > 100.0f)
1759 app_cpu_usage = 100.0f;
1760 resident = resident * 1024; // change to Byte
1761 pssmem = pssmem * 1024; // change to Byte
1762 shared = shared * 1024; // change to Byte
1764 sys_info->virtual_memory = virtual;
1765 sys_info->resident_memory = resident;
1766 sys_info->shared_memory = shared;
1767 sys_info->pss_memory = pssmem;
1769 sys_info->app_cpu_usage = app_cpu_usage;
1775 // fill threads information
1776 int fill_system_threads_info(float factor, struct system_info_t * sys_info)
1781 for(proc = thread_prochead; proc != NULL; proc = proc->next)
1782 //increment thread count
1783 sys_info->count_of_threads++; //maybe wrong
1785 /* LOGI_th_samp("thread load\n"); */
1786 struct thread_info_t *pthread;
1787 if (sys_info->count_of_threads != 0)
1789 sys_info->thread_load = malloc( sys_info->count_of_threads * sizeof(*sys_info->thread_load) );
1790 pthread = sys_info->thread_load;
1793 for(proc = thread_prochead; proc != NULL; proc = proc->next)
1795 thread_load = (float)(proc->proc_data.utime + proc->proc_data.stime -
1796 proc->saved_utime - proc->saved_stime)
1798 if(thread_load > 100.0f)
1799 thread_load = 100.0f;
1801 pthread->pid = proc->proc_data.pid;
1802 pthread->load = thread_load;
1805 // sprintf(thread_loadtmpbuf, "%d,%.1f,", proc->proc_data.pid, thread_load);
1806 // strcat(thread_loadbuf, thread_loadtmpbuf);
1808 proc->saved_utime = proc->proc_data.utime;
1809 proc->saved_stime = proc->proc_data.stime;
1815 //fill system cpu information
1816 int fill_system_cpu_info(struct system_info_t *sys_info)
1818 float sys_usage = 0.0f;
1821 // calculate for whole cpu load by average all core load
1822 LOGI_th_samp("calculate for whole cpu load num_of_cpu=%d\n", num_of_cpu);
1823 for(i = 0 ; i < num_of_cpu; i++)
1824 sys_usage += cpus[i].cpu_usage;
1828 if (num_of_cpu != 0)
1830 sys_info->cpu_load = malloc( num_of_cpu * sizeof(*sys_info->cpu_load) );
1831 pcpu_usage = sys_info->cpu_load;
1832 for(i = 0; i < num_of_cpu; i++)
1834 LOGI_th_samp("cpu#%d : %.1f\n" , i, cpus[i].cpu_usage);
1835 *pcpu_usage = cpus[i].cpu_usage;
1840 //fill CPU frequency
1841 sys_info->cpu_frequency = malloc(num_of_cpu * sizeof(float));
1842 if (!sys_info->cpu_frequency) {
1843 LOGE("Cannot alloc cpu freq\n");
1846 get_cpu_frequency(sys_info->cpu_frequency);
1852 //fill cpu frequency based on cpu tick count in different cpu frequence states
1853 int fill_cpu_frequecy(int event_num)
1855 // calculate for system cpu frequency
1856 float sys_usage = 0.0f;
1857 uint64_t ticks = 0, freqsum = 0;
1861 for(i = 0; i < num_of_cpu; i++)
1863 cpuptr = &(cpus[i]);
1865 if(cpuptr->cur_freq_index == event_num)
1867 if(cpuptr->sav_freq_index == event_num - 1)
1869 for(j = 0; j < num_of_freq; j++)
1871 freqsum += (cpuptr->pfreq[j].freq *
1872 (cpuptr->pfreq[j].tick - cpuptr->pfreq[j].tick_sav));
1873 ticks += (cpuptr->pfreq[j].tick - cpuptr->pfreq[j].tick_sav);
1880 for(j = 0; j < num_of_freq; j++)
1882 cpuptr->pfreq[j].tick_sav = cpuptr->pfreq[j].tick; // restore last tick value
1884 cpuptr->sav_freq_index = cpuptr->cur_freq_index;
1890 if(sys_usage == 0.0f)
1891 sys_usage = (float)freqsum / (float)ticks;
1892 // TODO use sys_usage as cpu #i core freq
1896 //freqbufpos += sprintf(freqbuf + freqbufpos, "%.0f,", sys_usage);
1906 static void skip_lines(FILE * fp, unsigned int count)
1908 char *buffer = NULL;
1911 for (index = 0; index != count; ++index)
1912 getline(&buffer, &buflen, fp);
1916 static void skip_tokens(FILE * fp, unsigned int count)
1920 for (index = 0; index != count; ++index)
1924 static void init_network_stat()
1926 manager.fd.networkstat = fopen("/proc/net/dev", "r");
1929 static void get_network_stat(uint32_t *recv, uint32_t *send)
1931 FILE *fp = manager.fd.networkstat;
1932 uintmax_t irecv, isend;
1941 skip_lines(fp, 2); /* strip header */
1943 while (fscanf(fp, "%s", ifname) != EOF)
1944 if (strcmp("lo:", ifname)) {
1945 fscanf(fp, "%" SCNuMAX, &irecv);
1948 fscanf(fp, "%" SCNuMAX, &isend);
1954 skip_tokens(fp, 16);
1957 static void peek_network_stat_diff(uint32_t *recv, uint32_t *send)
1959 static uint32_t irecv_old, isend_old;
1962 get_network_stat(recv, send);
1965 *recv = tmp - irecv_old;
1969 *send = tmp - isend_old;
1974 static void init_disk_stat(void)
1976 manager.fd.diskstats = fopen("/proc/diskstats", "r");
1979 //function return partition sector size
1982 // <size> if no errors
1983 static int get_partition_sector_size(const char * partition_name)
1987 char sec_size_buff[LARGE_BUFFER];
1989 sprintf(sec_size_buff, "/sys/block/%s/queue/hw_sector_size", partition_name);
1990 sfp = fopen(sec_size_buff, "r");
1992 LOGE("cannot detect sector size for <%s> (%s)\n",
1993 partition_name, sec_size_buff);
1996 fscanf(sfp, "%d", &sec_size);
1999 LOGE("cannot detect sector size for <%s> (%s)\n",
2000 partition_name, sec_size_buff);
2007 static void get_disk_stat(uint32_t *reads, uint32_t *sec_reads,
2008 uint32_t *writes, uint32_t *sec_writes)
2010 enum { partition_name_maxlength = 128 };
2011 FILE *fp = manager.fd.diskstats;
2012 char master_partition[partition_name_maxlength] = { 0 };
2014 *reads = *writes = 0;
2015 *sec_reads = *sec_writes = 0;
2025 char partition[partition_name_maxlength];
2026 uintmax_t preads, pwrites;
2027 uintmax_t psec_read, psec_write;
2029 fscanf(fp, "%s", partition);
2030 if (*master_partition
2031 && !strncmp(master_partition, partition,
2032 strlen(master_partition))) {
2034 skip_tokens(fp, 11);
2036 // FIXME it is not good way call this func
2037 // each time to get partition sector size
2038 /*sec_size = get_partition_sector_size(partition);
2042 LOGE("get RW error\n");
2048 fscanf(fp, "%" SCNuMAX, &preads);
2051 fscanf(fp, "%" SCNuMAX, &psec_read);
2054 fscanf(fp, "%" SCNuMAX, &pwrites);
2057 fscanf(fp, "%" SCNuMAX, &psec_write);
2060 memcpy(master_partition, partition,
2061 partition_name_maxlength);
2062 // FIXME rw size is in sectors
2063 // actualy different disks - different partition sector size (?)
2064 // maybe need convert to bytes like this:
2065 //*read += pread * sec_size;
2066 //*write += pwrite * sec_size;
2068 *reads += (uint32_t)preads;
2069 *writes += (uint32_t)pwrites;
2071 *sec_reads += (uint32_t)psec_read;
2072 *sec_writes += (uint32_t)psec_write;
2078 static void peek_disk_stat_diff(uint32_t *reads, uint32_t *sec_reads,
2079 uint32_t *writes, uint32_t *sec_writes)
2081 static uint32_t reads_old;
2082 static uint32_t sec_reads_old;
2083 static uint32_t writes_old;
2084 static uint32_t sec_writes_old;
2089 get_disk_stat(reads, sec_reads, writes, sec_writes);
2092 *reads = tmp - reads_old;
2096 *writes = tmp - writes_old;
2100 *sec_reads = tmp - sec_reads_old;
2101 sec_reads_old = tmp;
2104 *sec_writes = tmp - sec_writes_old;
2105 sec_writes_old = tmp;
2109 static float get_elapsed(void)
2111 static struct timeval old_time = {0, 0};
2112 struct timeval current_time;
2115 gettimeofday(¤t_time, NULL);
2116 elapsed = (current_time.tv_sec - old_time.tv_sec) +
2117 ((float)(current_time.tv_usec - old_time.tv_usec) / 1000000.0f);
2118 old_time.tv_sec = current_time.tv_sec;
2119 old_time.tv_usec = current_time.tv_usec;
2124 static float get_factor(float elapsed)
2126 return 100.0f / ((float)Hertz * elapsed * num_of_cpu);
2129 static uint64_t read_int64_from_file(const char *fname)
2131 FILE *fp = fopen(fname, "r");
2135 if (fscanf(fp, "%lld", &value) != 1)
2141 #define swap_sysfs_relpath(x) ("/sys/kernel/debug/swap/energy/" #x)
2142 #define swap_read_int64(x) (read_int64_from_file(swap_sysfs_relpath(x)))
2143 static uint64_t get_system_lcd_energy()
2145 static const char *PROC_LCD_ENERGY_FILES_GLOBPATTERN =
2146 "/sys/kernel/debug/swap/energy/lcd/*/system";
2147 uint64_t sum_energy = 0;
2150 const int err = glob(PROC_LCD_ENERGY_FILES_GLOBPATTERN, 0,
2154 LOG_ONCE_E("Globbing for LCD failed with error %d\n", err);
2158 for (i = 0; i < glob_buf.gl_pathc; ++i)
2159 sum_energy += read_int64_from_file(glob_buf.gl_pathv[i]);
2161 globfree(&glob_buf);
2165 * Calculates difference between current and previous sample (system).
2166 * Stores mutable state in static variables.
2168 static uint32_t pop_sys_energy_per_device(enum supported_device dev)
2170 static uint64_t cpu_old, flash_old, lcd_old;
2171 uint64_t cpu_new, flash_new, lcd_new;
2172 uint64_t cpu_diff, flash_diff, lcd_diff;
2176 cpu_new = swap_read_int64(cpu_idle/system) +
2177 swap_read_int64(cpu_running/system);
2178 cpu_diff = cpu_new - cpu_old;
2180 return (uint32_t)cpu_diff;
2183 flash_new = swap_read_int64(flash_read/system) +
2184 swap_read_int64(flash_write/system);
2185 flash_diff = flash_new - flash_old;
2186 flash_old = flash_new;
2187 return (uint32_t)flash_diff;
2189 lcd_new = get_system_lcd_energy();
2190 lcd_diff = lcd_new - lcd_old;
2192 return (uint32_t)lcd_diff;
2194 assert(0 && "Unknown device. This should not happen");
2199 // Calculates difference between current and previous sample (app).
2200 // Stores mutable state in static variables.
2201 static uint32_t pop_app_energy_per_device(enum supported_device dev)
2203 static uint64_t cpu_old, flash_old;
2204 uint64_t cpu_new, flash_new;
2205 uint64_t cpu_diff, flash_diff;
2209 cpu_new = swap_read_int64(cpu_running/apps);
2210 cpu_diff = cpu_new - cpu_old;
2212 return (uint32_t)cpu_diff;
2214 flash_new = swap_read_int64(flash_read/apps) +
2215 swap_read_int64(flash_write/apps);
2216 flash_diff = flash_new - flash_old;
2217 flash_old = flash_new;
2218 return (uint32_t)flash_diff;
2221 * Per-application energy accounting
2222 * is not supported for LCD.
2226 assert(0 && "Unknown device. This should not happen");
2231 // return log length (>0) for normal case
2232 // return negative value for error
2233 int get_system_info(struct system_info_t *sys_info, int* pidarray, int pidcount)
2235 static int event_num = 0;
2236 uint64_t sysmemtotal = 0;
2237 uint64_t sysmemused = 0;
2242 LOGI_th_samp("start\n");
2243 LOGI_th_samp("PID count : %d\n", pidcount);
2245 memset(sys_info, 0, sizeof(*sys_info));
2247 // common (cpu, processes, memory)
2248 if (IS_OPT_SET(FL_CPU) ||
2249 IS_OPT_SET(FL_PROCESSES) ||
2250 IS_OPT_SET(FL_MEMORY)) {
2251 if (update_process_data(pidarray, pidcount, PROCDATA_STAT) < 0) {
2252 LOGE("Failed to update process stat data\n");
2256 * This position is optimized position of timestamp. Just
2257 * before get system cpu data and just after get process cpu
2258 * data because cpu data is changed so fast and variance is so
2261 elapsed = get_elapsed(); /* DO NOT MOVE THIS SENTENCE! */
2262 factor = get_factor(elapsed);
2264 if (update_system_cpu_data(event_num) < 0) {
2265 LOGE("Failed to update system cpu data\n");
2269 if (update_system_cpu_frequency(event_num) < 0) {
2270 LOGE("Failed to update system cpu freq data\n");
2275 * Memory data is changed slowly and variance is not
2276 * remarkable, so memory data is less related with timestamp
2279 if (update_process_data(pidarray, pidcount, PROCDATA_SMAPS) < 0) {
2280 LOGE("Failed to update process smaps data\n");
2285 if (update_thread_data(pidarray[0]) < 0) {
2286 LOGE("Failed to update thread stat data\n");
2290 if (update_system_memory_data(&sysmemtotal, &sysmemused) < 0) {
2291 LOGE("Failed to update system memory data\n");
2295 if (update_cpus_info(event_num, elapsed) < 0) {
2296 LOGE("Failed to update cpus info\n");
2300 /* calculate process load, memory, app_cpu_usage */
2301 if (fill_system_processes_info(factor, sys_info) < 0) {
2302 LOGE("Failed to fill processes info\n");
2306 /* calculate thread load */
2307 if (fill_system_threads_info(factor, sys_info) < 0) {
2308 LOGE("Failed to fill threads info\n");
2312 if (fill_system_cpu_info(sys_info) < 0) {
2313 LOGE("Failed to fill threads info\n");
2318 if (IS_OPT_SET(FL_MEMORY)) {
2319 sys_info->total_alloc_size = get_total_alloc_size();
2320 sys_info->system_memory_total = sysmemtotal;
2321 sys_info->system_memory_used = sysmemused;
2324 LOGI_th_samp("Fill result structure\n");
2326 if (IS_OPT_SET(FL_DISK)) {
2327 sys_info->total_used_drive = get_total_used_drive();
2328 peek_disk_stat_diff(&sys_info->disk_reads,
2329 &sys_info->disk_sectors_read,
2330 &sys_info->disk_writes,
2331 &sys_info->disk_sectors_write);
2334 if (IS_OPT_SET(FL_NETWORK))
2335 peek_network_stat_diff(&sys_info->network_send_size,
2336 &sys_info->network_receive_size);
2338 if (IS_OPT_SET(FL_DEVICE)) {
2339 sys_info->wifi_status = get_wifi_status();
2340 sys_info->bt_status = get_bt_status();
2341 sys_info->gps_status = get_gps_status();
2342 sys_info->brightness_status = get_brightness_status();
2343 sys_info->camera_status = get_camera_status();
2344 sys_info->sound_status = get_sound_status();
2345 sys_info->audio_status = get_audio_status();
2346 sys_info->vibration_status = get_vibration_status();
2347 sys_info->voltage_status = get_voltage_status();
2348 sys_info->rssi_status = get_rssi_status();
2349 sys_info->video_status = get_video_status();
2350 sys_info->call_status = get_call_status();
2351 sys_info->dnet_status = get_dnet_status();
2354 if (IS_OPT_SET(FL_ENERGY)) {
2356 sys_info->energy = 0; /* not implemented */
2357 for (i = 0; i != supported_devices_count; ++i) {
2358 sys_info->energy_per_device[i] =
2359 pop_sys_energy_per_device(i);
2360 sys_info->app_energy_per_device[i] =
2361 pop_app_energy_per_device(i);
2365 #ifdef THREAD_SAMPLING_DEBUG
2366 print_sys_info(sys_info);
2370 LOGI_th_samp("exit\n");
2374 /* Some data corrupted. Free allocated data. */
2375 reset_system_info(sys_info);
2376 LOGI_th_samp("fail exit\n");
2380 int initialize_system_info()
2384 num_of_cpu = sysconf(_SC_NPROCESSORS_CONF);
2387 Hertz = sysconf(_SC_CLK_TCK);
2388 LOGI("Hertz : %d\n", Hertz);
2392 cpus = (CPU_t*) calloc((num_of_cpu + 1), sizeof(CPU_t));
2395 for(i = 0; i <= num_of_cpu; i++)
2397 cpus[i].cur_load_index = cpus[i].sav_load_index = -1;
2398 cpus[i].cur_freq_index = cpus[i].sav_freq_index = -1;
2403 LOGE("Failed to alloc memory for cpu information\n");
2410 int finalize_system_info()
2416 for(i = 0; i < num_of_cpu; i++)
2418 if(cpus[i].pfreq != NULL)
2419 free(cpus[i].pfreq);
2429 static void test_and_close(int *fd)
2436 static void ftest_and_close(FILE **fd)
2444 #define str(x) strr(x)
2445 #define dtest_and_close(fd) do {LOGI("CLOSE " str(fd) "\n");test_and_close(fd);} while(0)
2446 #define dftest_and_close(fd) do {LOGI("CLOSE " str(fd) "\n");ftest_and_close(fd);} while(0)
2447 void close_system_file_descriptors()
2449 dtest_and_close(&manager.fd.brightness);
2450 dtest_and_close(&manager.fd.voltage);
2451 dtest_and_close(&manager.fd.procmeminfo);
2453 dftest_and_close(&manager.fd.video);
2454 dftest_and_close(&manager.fd.procstat);
2455 dftest_and_close(&manager.fd.networkstat);
2456 dftest_and_close(&manager.fd.diskstats);
2459 int init_system_file_descriptors()
2462 init_brightness_status();
2463 init_voltage_status();
2464 init_update_system_memory_data();
2466 init_video_status();
2467 init_system_cpu_data();
2468 init_network_stat();
2471 if (manager.fd.brightness < 0)
2472 LOGW("brightness file not found\n");
2473 if (manager.fd.voltage < 0)
2474 LOGW("voltage file not found\n");
2475 if (manager.fd.procmeminfo < 0)
2476 LOGW("procmeminfo file not found\n");
2478 if (manager.fd.video == NULL)
2479 LOGW("video file not found\n");
2480 if (manager.fd.procstat == NULL)
2481 LOGW("procstat file not found\n");
2482 if (manager.fd.networkstat == NULL)
2483 LOGW("networkstat file not found\n");
2484 if (manager.fd.diskstats == NULL)
2485 LOGW("diskstat file not found\n");
2489 //CMD SOCKET FUNCTIONS
2490 int fill_target_info(struct target_info_t *target_info)
2492 /* system_info_get_value_bool() changes only 1 byte
2493 so we need to be sure that the integer as a whole is correct */
2494 target_info->bluetooth_supp = 0;
2495 target_info->gps_supp = 0;
2496 target_info->wifi_supp = 0;
2497 target_info->camera_count = 0;
2498 target_info->network_type[0] = 0;
2500 target_info->sys_mem_size = get_system_total_memory();
2501 target_info->storage_size = stat_get_storageinfo(FSINFO_TYPE_TOTAL) *
2504 system_info_get_platform_bool("tizen.org/feature/network.bluetooth",
2505 (_Bool *)&target_info->bluetooth_supp);
2508 system_info_get_platform_bool("tizen.org/feature/location.gps",
2509 (_Bool *)&target_info->gps_supp);
2511 system_info_get_platform_bool("tizen.org/feature/network.wifi",
2512 (_Bool *)&target_info->wifi_supp);
2514 target_info->camera_count = get_camera_count();
2516 get_device_network_type(target_info->network_type, NWTYPE_SIZE);
2519 target_info->max_brightness = get_max_brightness();
2520 target_info->cpu_core_count = sysconf(_SC_NPROCESSORS_CONF);
2524 int sys_stat_prepare(void)
2526 uint32_t reads, writes, sec_reads, sec_writes;
2527 uint32_t recv, send;
2529 peek_disk_stat_diff(&reads, &writes, &sec_reads, &sec_writes);
2530 peek_network_stat_diff(&recv, &send);
2535 static uint32_t msg_data_payload_length(const struct system_info_t *sys_info)
2537 uint32_t len = sizeof(*sys_info);
2539 /* num_of_cpu is unknown at compile time */
2540 len += 2 * num_of_cpu * sizeof(float);
2542 /* subtract pointers */
2543 len -= sizeof(sys_info->cpu_frequency) + sizeof(sys_info->cpu_load);
2544 len -= sizeof(sys_info->thread_load) + sizeof(sys_info->process_load);
2546 if (IS_OPT_SET(FL_CPU))
2547 len += sys_info->count_of_threads *
2548 sizeof(*sys_info->thread_load);
2550 if (IS_OPT_SET(FL_PROCESSES))
2551 len += sys_info->count_of_processes *
2552 sizeof(*sys_info->process_load);
2557 struct msg_data_t *pack_system_info(struct system_info_t *sys_info)
2559 const int len = msg_data_payload_length(sys_info);
2560 struct msg_data_t *msg = NULL;
2564 msg = malloc(MSG_DATA_HDR_LEN + len);
2566 LOGE("Cannot alloc message: %d bytes\n", len);
2570 fill_data_msg_head(msg, NMSG_SYSTEM, 0, len);
2574 if (IS_OPT_SET(FL_CPU)) {
2575 pack_float(p, sys_info->app_cpu_usage);
2577 for (i = 0; i < num_of_cpu; i++) {
2578 if (sys_info->cpu_frequency)
2579 pack_float(p, sys_info->cpu_frequency[i]);
2584 for (i = 0; i < num_of_cpu; i++) {
2585 if (sys_info->cpu_load)
2586 pack_float(p, sys_info->cpu_load[i]);
2591 pack_int32(p, sys_info->count_of_threads);
2592 for (i = 0; i < sys_info->count_of_threads; i++) {
2593 if (sys_info->thread_load) {
2594 pack_int32(p, sys_info->thread_load[i].pid);
2595 pack_float(p, sys_info->thread_load[i].load);
2602 pack_float(p, 0.0); /* pack app_cpu_usage */
2604 for (i = 0; i < num_of_cpu; i++) {
2605 pack_float(p, 0.0); /* pack cpu_frequency */
2606 pack_float(p, 0.0); /* pack cpu_load */
2609 pack_int32(p, 0); /* pack count_of_threads */
2613 if (IS_OPT_SET(FL_PROCESSES)) {
2614 pack_int32(p, sys_info->count_of_processes);
2615 for (i = 0; i < sys_info->count_of_processes; i++) {
2616 if (sys_info->process_load) {
2617 pack_int32(p, sys_info->process_load[i].id);
2618 pack_float(p, sys_info->process_load[i].load);
2625 pack_int32(p, 0); /* pack count_of_processes */
2629 if (IS_OPT_SET(FL_MEMORY)) {
2630 pack_int32(p, sys_info->virtual_memory);
2631 pack_int32(p, sys_info->resident_memory);
2632 pack_int32(p, sys_info->shared_memory);
2633 pack_int32(p, sys_info->pss_memory);
2634 pack_int32(p, sys_info->total_alloc_size);
2635 pack_int64(p, sys_info->system_memory_total);
2636 pack_int64(p, sys_info->system_memory_used);
2638 pack_int32(p, 0); /* pack virtual_memory */
2639 pack_int32(p, 0); /* pack resident_memory */
2640 pack_int32(p, 0); /* pack shared_memory */
2641 pack_int32(p, 0); /* pack pss_memory */
2642 pack_int32(p, 0); /* pack total_alloc_size */
2643 pack_int64(p, (uint64_t) 0); /* pack system_memory_total */
2644 pack_int64(p, (uint64_t) 0); /* pack system_memory_used */
2647 pack_int32(p, sys_info->total_used_drive);
2648 pack_int32(p, sys_info->disk_reads);
2649 pack_int32(p, sys_info->disk_sectors_read);
2650 pack_int32(p, sys_info->disk_writes);
2651 pack_int32(p, sys_info->disk_sectors_write);
2653 pack_int32(p, sys_info->network_send_size);
2654 pack_int32(p, sys_info->network_receive_size);
2656 pack_int32(p, sys_info->wifi_status);
2657 pack_int32(p, sys_info->bt_status);
2658 pack_int32(p, sys_info->gps_status);
2659 pack_int32(p, sys_info->brightness_status);
2660 pack_int32(p, sys_info->camera_status);
2661 pack_int32(p, sys_info->sound_status);
2662 pack_int32(p, sys_info->audio_status);
2663 pack_int32(p, sys_info->vibration_status);
2664 pack_int32(p, sys_info->voltage_status);
2665 pack_int32(p, sys_info->rssi_status);
2666 pack_int32(p, sys_info->video_status);
2667 pack_int32(p, sys_info->call_status);
2668 pack_int32(p, sys_info->dnet_status);
2670 pack_int32(p, sys_info->energy);
2671 for (i = 0; i != supported_devices_count; ++i)
2672 pack_int32(p, sys_info->energy_per_device[i]);
2673 for (i = 0; i != supported_devices_count; ++i)
2674 pack_int32(p, sys_info->app_energy_per_device[i]);