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>
51 #include <system_info.h>
52 #include <runtime_info.h>
53 #include <telephony_network.h>
57 #include "da_protocol.h"
72 // defines for runtime environment
75 #define BUFFER_MAX 1024
76 #define LARGE_BUFFER 512
77 #define MIDDLE_BUFFER 256
78 #define SMALL_BUFFER 64
79 #define PROCPATH_MAX 32
80 #define STATUS_STRING_MAX 16
81 #define MAX_NUM_OF_FREQ 16
83 #define MEM_SLOT_TOTAL 0
84 #define MEM_SLOT_FREE 1
85 #define MEM_SLOT_BUFFER 2
86 #define MEM_SLOT_CACHED 3
87 #define MEM_SLOT_MAX 4
89 #define MIN_TICKS_FOR_LOAD 8
90 #define MIN_TOTAL_TICK 10
91 #define SYS_INFO_TICK 100 // TODO : change to (Hertz * profiling period)
93 #define CPUMHZ "cpu MHz"
94 #define DA_PROBE_TIZEN_SONAME "da_probe_tizen.so"
95 #define DA_PROBE_OSP_SONAME "da_probe_osp.so"
96 #define CAMCORDER_FILE "/usr/etc/mmfw_camcorder.ini"
97 #define CAMERA_COUNT_STR "DeviceCount"
105 // declared by greatim
106 static int Hertz = 0;
107 static int num_of_cpu = 0;
108 static int num_of_freq = 0;
109 static uint64_t mem_slot_array[MEM_SLOT_MAX];
110 static CPU_t* cpus = NULL;
111 static unsigned long probe_so_size = 0;
114 int get_file_status_no_open(int pfd, const char *filename)
119 char buf[STATUS_STRING_MAX];
121 if (unlikely(pfd < 0)) {
126 lseek(pfd, 0, SEEK_SET); // rewind to start of file
129 if (unlikely(read(pfd, buf, STATUS_STRING_MAX) == -1))
137 // daemon api : get status from file
138 // pfd must not be null
139 int get_file_status(int *pfd, const char *filename)
144 if (likely(pfd != NULL)) {
145 //open if is not open
146 if (unlikely(*pfd < 0)) {
148 *pfd = open(filename, O_RDONLY);
149 if (unlikely(*pfd == -1)) {
150 /* This file may absent in the system */
155 if (unlikely(*pfd < 0)) {
156 //file is open. lets read
157 status = get_file_status_no_open(*pfd, filename);
166 // =============================================================================
167 // device status information getter functions
168 // =============================================================================
169 static int get_wifi_status()
175 if (unlikely(vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_status) < 0))
177 wifi_status = VCONFKEY_WIFI_OFF;
180 if (unlikely(runtime_info_get_value_int(
181 RUNTIME_INFO_KEY_WIFI_STATUS, &wifi_status) < 0))
183 wifi_status = RUNTIME_INFO_WIFI_STATUS_DISABLED;
191 static int get_bt_status()
193 int bt_status = false;
197 if (unlikely(vconf_get_int(VCONFKEY_BT_STATUS, &bt_status) < 0))
199 bt_status = VCONFKEY_BT_STATUS_OFF;
202 if (unlikely(runtime_info_get_value_bool(
203 RUNTIME_INFO_KEY_BLUETOOTH_ENABLED, (bool*)&bt_status) < 0))
213 static int get_gps_status()
219 if(unlikely(vconf_get_bool(VCONFKEY_LOCATION_ENABLED, &gps_status) < 0))
221 gps_status = VCONFKEY_LOCATION_GPS_OFF;
223 else if(gps_status != 0)
225 if (unlikely(vconf_get_int(VCONFKEY_LOCATION_GPS_STATE, &gps_status) < 0))
227 gps_status = VCONFKEY_LOCATION_GPS_OFF;
231 if (unlikely(runtime_info_get_value_bool(
232 RUNTIME_INFO_KEY_LOCATION_SERVICE_ENABLED, (bool*)&gps_status) < 0))
236 else if(gps_status != 0)
238 if (unlikely(runtime_info_get_value_bool(
239 RUNTIME_INFO_KEY_LOCATION_ADVANCED_GPS_ENABLED, (bool*)&gps_status) < 0))
243 else if(gps_status != 0)
245 if(unlikely(runtime_info_get_value_int(
246 RUNTIME_INFO_KEY_GPS_STATUS, &gps_status) < 0))
252 // do nothing (gps_status is real gps status)
257 // do nothing (gps_status == 0)
262 // do nothing (gps_status == 0)
270 static void init_brightness_status()
275 struct dirent* dir_entry;
276 char fullpath[PATH_MAX];
278 dir_info = opendir(BRIGHTNESS_PARENT_DIR);
279 if (dir_info != NULL)
281 while((dir_entry = readdir(dir_info)) != NULL)
283 if (strcmp(dir_entry->d_name, ".") == 0 ||
284 strcmp(dir_entry->d_name, "..") == 0)
286 else // first directory
289 BRIGHTNESS_PARENT_DIR "/%s/" BRIGHTNESS_FILENAME,
291 get_file_status(&manager.fd.brightness, fullpath);
301 get_file_status(&manager.fd.brightness, EMUL_BRIGHTNESSFD);
306 static int get_brightness_status()
308 return get_file_status_no_open(manager.fd.brightness, EMUL_BRIGHTNESSFD);
311 static int get_max_brightness()
313 int maxbrightnessfd = -1;
314 static int max_brightness = -1;
317 if(__builtin_expect(max_brightness < 0, 0))
321 struct dirent* dir_entry;
322 char fullpath[PATH_MAX];
324 dir_info = opendir(BRIGHTNESS_PARENT_DIR);
327 while((dir_entry = readdir(dir_info)) != NULL)
329 if (strcmp(dir_entry->d_name, ".") == 0 ||
330 strcmp(dir_entry->d_name, "..") == 0)
332 else // first directory
335 BRIGHTNESS_PARENT_DIR "/%s/" MAX_BRIGHTNESS_FILENAME,
337 max_brightness = get_file_status(&maxbrightnessfd, fullpath);
347 max_brightness = get_file_status(&maxbrightnessfd, EMUL_MAX_BRIGHTNESSFD);
351 if(maxbrightnessfd != -1)
352 close(maxbrightnessfd);
355 return max_brightness;
358 static void init_video_status()
361 manager.fd.video = fopen(MFCFD, "r");
365 static int get_video_status()
367 int video_status = 0;
371 FILE *video_fp = manager.fd.video;
374 if (video_fp == NULL) // file is not open
380 ret = fscanf(video_fp, "%s", stat);
383 if(strncmp(stat,"active",6) == 0)
391 static int get_rssi_status()
394 int flightmode_status;
398 if(unlikely(vconf_get_bool(VCONFKEY_SETAPPL_FLIGHT_MODE_BOOL,
399 &flightmode_status) < 0))
401 flightmode_status = 0;
404 if(!flightmode_status)
406 if(unlikely(vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &rssi_status) < 0))
408 rssi_status = VCONFKEY_TELEPHONY_RSSI_0;
413 rssi_status = VCONFKEY_TELEPHONY_RSSI_0;
418 network_info_rssi_e rssi_status;
420 if(unlikely(runtime_info_get_value_bool(
421 RUNTIME_INFO_KEY_FLIGHT_MODE_ENABLED, (bool*)&flightmode_status) < 0))
423 flightmode_status = 0;
426 if(!flightmode_status)
428 if(unlikely(network_info_get_rssi(&rssi_status) < 0))
430 rssi_status = NETWORK_INFO_RSSI_0;
435 rssi_status = NETWORK_INFO_RSSI_0;
438 return (int)rssi_status;
445 static int get_call_status()
451 if(unlikely(vconf_get_int(VCONFKEY_CALL_STATE, &call_status) < 0))
453 call_status = VCONFKEY_CALL_OFF;
456 call_state_e call_state;
457 if(unlikely(call_get_voice_call_state(&call_state) < 0))
459 if(unlikely(call_get_video_call_state(&call_state) < 0))
461 call_status = 0; // call idle
465 // return video call state
466 if(call_state == CALL_STATE_CONNECTING)
468 else if(call_state == CALL_STATE_ACTIVE)
472 else if(call_state == CALL_STATE_IDLE) // voice call state is idle
474 if(unlikely(call_get_video_call_state(&call_state) < 0))
480 // return video call state
481 if(call_state == CALL_STATE_CONNECTING)
483 else if(call_state == CALL_STATE_ACTIVE)
489 // return voice call state
490 if(call_state == CALL_STATE_CONNECTING)
492 else if(call_state == CALL_STATE_ACTIVE)
502 static int get_dnet_status()
504 int dnet_status = false;
508 if(unlikely(vconf_get_int(VCONFKEY_DNET_STATE, &dnet_status) < 0))
510 dnet_status = VCONFKEY_DNET_OFF;
513 if(unlikely(runtime_info_get_value_bool(
514 RUNTIME_INFO_KEY_PACKET_DATA_ENABLED, (bool*)&dnet_status) < 0))
524 static int get_camera_status()
526 int camera_status = 0;
531 if(unlikely(vconf_get_int(VCONFKEY_CAMERA_STATE, &camera_status) < 0))
533 camera_status = VCONFKEY_CAMERA_OFF;
539 return camera_status;
542 // this means silent mode?
543 static int get_sound_status()
545 int sound_status = 0;
549 if(unlikely(vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL,
555 if(unlikely(runtime_info_get_value_bool(
556 RUNTIME_INFO_KEY_SILENT_MODE_ENABLED, (bool*)&sound_status) < 0))
562 sound_status = (sound_status == 1) ? 0 : 1; // slient mode
570 static void init_audio_status()
576 manager.fd.audio_status = fopen(AUDIOFD, "r");
583 static int get_audio_status()
593 FILE *audio_status_fp = manager.fd.audio_status;
594 if (audio_status_fp == NULL){
598 // fseek(audio_status_fp, 0, SEEK_SET);
599 rewind(audio_status_fp);
600 fflush(audio_status_fp);
605 ret = fscanf(audio_status_fp, "%[^:] %*c %[^\n] ", dev, state);
606 if(strncmp(dev,"SPKR",4) == 0 && strncmp(state, "On",2) == 0)
610 else if(ret == 2 && strncmp(dev,"Head",4) == 0 && strncmp(state, "On",2) == 0)
624 static int get_vibration_status()
626 int vibration_status = 0;
630 if(unlikely(vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL,
631 &vibration_status) < 0))
633 vibration_status = 0;
636 if(unlikely(runtime_info_get_value_bool(
637 RUNTIME_INFO_KEY_VIBRATION_ENABLED, (bool*)&vibration_status) < 0))
639 vibration_status = 0;
644 return vibration_status;
647 static void init_voltage_status()
649 get_file_status(&manager.fd.voltage, VOLTAGEFD);
652 static int get_voltage_status()
654 return get_file_status_no_open(manager.fd.voltage, VOLTAGEFD);
657 // =====================================================================
658 // cpu information getter functions
659 // =====================================================================
660 static void get_cpu_frequency(float *freqs)
662 char filename[MIDDLE_BUFFER];
663 char freq_str[SMALL_BUFFER];
668 for (cpu_n = 0; cpu_n < num_of_cpu; cpu_n++)
674 snprintf(filename, MIDDLE_BUFFER,
675 "/sys/devices/system/cpu/cpu%d/online", cpu_n);
677 f = fopen(filename, "r");
679 LOGI_th_samp("file not found <%s\n>", filename);
685 snprintf(filename, MIDDLE_BUFFER,
686 "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", cpu_n);
687 f = fopen(filename, "r");
691 LOGI_th_samp("core #%d diasabled\n", cpu_n);
694 //core enabled, get frequency
695 fscanf(f, "%s", freq_str);
696 freqs[cpu_n] = atof(freq_str);
697 LOGI_th_samp("core #%d freq = %.0f\n", cpu_n, freqs[cpu_n]);
707 // ========================================================================
708 // get cpu and memory info for each process and whole system
709 // ========================================================================
710 typedef struct _proc_node {
712 unsigned long long saved_utime;
713 unsigned long long saved_stime;
715 struct _proc_node *next;
718 static procNode *prochead = NULL;
719 static procNode *thread_prochead = NULL;
721 static procNode* find_node(procNode *head, pid_t pid)
726 if (t->proc_data.pid == pid)
736 static procNode* add_node(procNode **head, pid_t pid)
740 n = (procNode *) malloc(sizeof(procNode));
742 LOGE("Not enough memory, add cpu info node failied");
746 n->proc_data.pid = pid;
754 static int del_node(procNode **head, pid_t pid)
761 /* LOGI("dell t=%d\n",t); */
763 if (t->proc_data.pid == pid) {
765 prev->next = t->next;
767 *head = (*head)->next;
775 /* LOGI("ret 0\n"); */
779 static int del_notfound_node(procNode **head)
781 procNode *proc, *prev;
783 for(proc = *head; proc != NULL; )
789 prev->next = proc->next;
795 *head = (*head)->next;
809 static int reset_found_node(procNode *head)
812 for(proc = head; proc != NULL; proc = proc->next)
819 // return 0 for normal case
820 // return negative value for error case
821 static int parse_proc_stat_file_bypid(char *path, proc_t* P)
823 char filename[PROCPATH_MAX];
824 char buf[BUFFER_MAX];
828 // read from stat file
829 sprintf(filename, "%s/stat", path);
830 fd = open(filename, O_RDONLY, 0);
832 if(unlikely(fd == -1)){
836 num = read(fd, buf, BUFFER_MAX);
839 if(unlikely(num <= 0)){
840 LOGE("nothing read from '%s'\n", filename);
842 } else if(num == BUFFER_MAX)
850 abuf = strchr(buf, '(') + 1;
851 bbuf = strrchr(buf, ')');
853 if(unlikely(num >= sizeof(P->command)))
854 num = sizeof(P->command) - 1;
855 memcpy(P->command, abuf, num);
856 P->command[num] = '\0';
864 "%lu %lu %lu %lu %lu "
865 "%Lu %Lu %Lu %Lu " // utime stime cutime cstime
873 &P->ppid, &P->pgrp, &P->sid, &P->tty_nr, &P->tty_pgrp,
874 &P->flags, &P->minor_fault, &P->cminor_fault, &P->major_fault, &P->cmajor_fault,
875 &P->utime, &P->stime, &P->cutime, &P->cstime,
876 &P->priority, &P->nice,
884 if(P->numofthread == 0)
890 // return 0 for normal case
891 // return negative value for error case
892 static int parse_proc_smaps_file_bypid(char *path, proc_t* P)
894 #define MIN_SMAP_BLOCKLINE 50
896 char filename[PROCPATH_MAX];
897 char buf[MIDDLE_BUFFER];
898 char numbuf[SMALL_BUFFER];
901 // reset pss size of proc_t
905 // read from smaps file
906 sprintf(filename, "%s/smaps", path);
907 fp = fopen(filename, "r");
913 if(unlikely(probe_so_size == 0)) // probe so size is not abtained
916 while(fgets(buf, MIDDLE_BUFFER, fp) != NULL)
918 if(strncmp(buf, "Pss:", 4) == 0) // line is started with "Pss:"
920 sscanf(buf, "Pss:%s kB", numbuf);
921 P->pss += atoi(numbuf);
924 probe_so_size += atoi(numbuf);
925 is_probe_so = 0; // reset search flag
928 else if(strncmp(buf, "Shared", 6) == 0) // line is started with "Shared"
931 p = strstr(buf, ":");
934 sscanf(p, ":%s kB", numbuf);
935 P->sh_mem += atoi(numbuf);
941 if (is_probe_so == 0 && strlen(buf) > MIN_SMAP_BLOCKLINE)
943 // first we find probe so section
944 if(strstr(buf, DA_PROBE_TIZEN_SONAME) != NULL ||
945 strstr(buf, DA_PROBE_OSP_SONAME) != NULL)
962 else // we know about probe.so size already
964 while(fgets(buf, MIDDLE_BUFFER, fp) != NULL)
966 if(strncmp(buf, "Pss:", 4) == 0)
968 sscanf(buf, "Pss:%s kB", numbuf);
969 P->pss += atoi(numbuf);
971 else if(strncmp(buf, "Shared", 6) == 0) // line is started with "Shared"
974 p = strstr(buf, ":");
977 sscanf(p, ":%s kB", numbuf);
978 P->sh_mem += atoi(numbuf);
984 P->pss -= probe_so_size;
991 // return 0 for normal case
992 // return positive value for non critical case
993 // return negative value for critical case
994 static int update_process_data(int* pidarray, int pidcount, enum PROCESS_DATA datatype)
996 static struct stat sb;
998 char buf[PROCPATH_MAX];
1001 for(i = 0; i < pidcount; i++)
1003 /* LOGI("#%d\n", i); */
1004 if (pidarray[i] == 0) // pid is invalid
1010 sprintf(buf, "/proc/%d", pidarray[i]);
1011 /* LOGI("#->%s\n", buf); */
1012 if (unlikely(stat(buf, &sb) == -1)) // cannot access anymore
1014 /* LOGI("#del from prochead=%d\n", prochead); */
1015 del_node(&prochead, pidarray[i]);
1020 /* LOGI("find node = %d\n", procnode); */
1021 if ((procnode = find_node(prochead, pidarray[i])) == NULL) // new process
1023 /* LOGI("proc node1 = %d\n", procnode); */
1024 procnode = add_node(&prochead, pidarray[i]);
1025 if(datatype == PROCDATA_STAT)
1027 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
1029 LOGE("Failed to get proc stat file by pid(%d)\n", pidarray[i]);
1033 procnode->saved_utime = procnode->proc_data.utime;
1034 procnode->saved_stime = procnode->proc_data.stime;
1037 else if(datatype == PROCDATA_SMAPS)
1039 if (unlikely((ret = parse_proc_smaps_file_bypid(buf, &(procnode->proc_data))) < 0))
1041 LOGE("Failed to get proc smaps file by pid(%d)\n", pidarray[i]);
1053 /* LOGI("proc node2 = %d\n", procnode); */
1054 if(datatype == PROCDATA_STAT)
1056 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
1058 LOGE("Failed to get proc stat file by pid(%d)\n", pidarray[i]);
1064 else if(datatype == PROCDATA_SMAPS)
1066 if (unlikely((ret = parse_proc_smaps_file_bypid(buf, &(procnode->proc_data))) < 0))
1068 LOGE("Failed to get proc smaps file by pid(%d)\n", pidarray[i]);
1079 /* LOGI("del_notfound_node\n"); */
1080 del_notfound_node(&prochead);
1081 /* LOGI("reset_found_node\n"); */
1082 reset_found_node(prochead);
1084 /* LOGI("ret %d\n", ret); */
1088 static int update_system_cpu_frequency(int cur_index)
1090 char buf[SMALL_BUFFER];
1091 char filename[SMALL_BUFFER];
1095 // execute this block only once
1096 if(unlikely(num_of_freq <= 0))
1100 if((fp = fopen(CPUNUM_OF_FREQ, "r")) != NULL)
1102 while(fgets(buf, SMALL_BUFFER, fp) != NULL)
1110 /* This file may absent in the system */
1113 for(i = 0; i < num_of_cpu; i++)
1115 if(cpus[i].pfreq == NULL && num_of_freq)
1117 cpus[i].pfreq = (cpufreq_t*) calloc(num_of_freq, sizeof(cpufreq_t));
1122 sprintf(filename, CPUNUM_OF_FREQ);
1123 // update cpu frequency information
1124 for(i = 0; i < num_of_cpu; i++)
1126 filename[27] = (char)('0' + i);
1127 fp = fopen(filename, "r");
1130 for(j = 0; j < num_of_freq; j++)
1132 if(fgets(buf, SMALL_BUFFER, fp) != NULL)
1134 sscanf(buf, "%lu %Lu", &(cpus[i].pfreq[j].freq),
1135 &(cpus[i].pfreq[j].tick));
1137 else // cannot read anymore from frequency info file
1142 cpus[i].cur_freq_index = cur_index;
1144 else // cannot load cpu frequency information
1152 // return 0 for normal case
1153 // return negative value for error
1154 static void init_system_cpu_data()
1156 manager.fd.procstat = fopen(PROCSTAT, "r");
1159 static int update_system_cpu_data(int cur_index)
1163 FILE* fp = manager.fd.procstat;
1165 char buf[BUFFER_MAX];
1173 if(fgets(buf, sizeof(buf), fp) == NULL)
1175 LOGE("Failed to read first line of " PROCSTAT "\n");
1179 /* LOGI("scan; cpus = %d\n", cpus); */
1181 cpus[num_of_cpu].x = 0;
1182 cpus[num_of_cpu].y = 0;
1183 cpus[num_of_cpu].z = 0;
1184 num = sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
1185 &cpus[num_of_cpu].u,
1186 &cpus[num_of_cpu].n,
1187 &cpus[num_of_cpu].s,
1188 &cpus[num_of_cpu].i,
1189 &cpus[num_of_cpu].w,
1190 &cpus[num_of_cpu].x,
1191 &cpus[num_of_cpu].y,
1194 cpus[num_of_cpu].cur_load_index = cur_index;
1197 LOGE("Failed to read from " PROCSTAT "\n");
1203 /* LOGI("cpu num = %d\n", num_of_cpu); */
1204 // and just in case we're 2.2.xx compiled without SMP support...
1207 cpus[0].id = cpus[1].id = 0;
1208 memcpy(cpus, &cpus[1], sizeof(tic_t) * 8);
1209 cpus[0].cur_load_index = cur_index;
1211 else if(num_of_cpu > 1)
1214 // now value each separate cpu's tics
1215 for(i = 0; i < num_of_cpu; i++)
1217 if(fgets(buf, sizeof(buf), fp) != NULL)
1222 num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
1224 &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i,
1225 &cpus[i].w, &cpus[i].x, &cpus[i].y, &cpus[i].z);
1228 LOGI_th_samp("Readed %d stats of %dth cpu\n", num, i);
1229 cpus[i].cur_load_index = cur_index;
1231 else // buf is not cpu core tick information
1235 else // cannot read anymore from /proc/stat file
1249 // return 0 for normal case
1250 // return negative value for error
1251 static void init_update_system_memory_data()
1253 manager.fd.procmeminfo = open(PROCMEMINFO, O_RDONLY);
1256 static int update_system_memory_data(uint64_t *memtotal, uint64_t *memused)
1258 int meminfo_fd = manager.fd.procmeminfo;
1261 char buf[BUFFER_MAX];
1262 static const mem_t mem_table[] = {
1263 {"Buffers", (unsigned long *)&mem_slot_array[MEM_SLOT_BUFFER]},
1264 {"Cached", (unsigned long *)&mem_slot_array[MEM_SLOT_CACHED]},
1265 {"MemFree", (unsigned long *)&mem_slot_array[MEM_SLOT_FREE]},
1266 {"MemTotal", (unsigned long *)&mem_slot_array[MEM_SLOT_TOTAL]},
1268 const int mem_table_size = sizeof(mem_table) / sizeof(mem_t);
1270 if (meminfo_fd == -1)
1273 lseek(meminfo_fd, 0L, SEEK_SET);
1274 if((num = read(meminfo_fd, buf, BUFFER_MAX)) < 0)
1276 LOGE("Failed to read from " PROCMEMINFO "\n");
1280 if(num == BUFFER_MAX)
1284 // LOGI("buffer=<%s>\n", buf);
1286 num = 0; // number of found element
1288 for( ;num < mem_table_size ; )
1290 tail = strchr(head, ':');
1294 for(i = 0; i < mem_table_size; i++)
1296 if(strcmp(head, mem_table[i].name) == 0) // found
1299 *(mem_table[i].slot) = strtoul(head, &tail, 10);
1304 if(i == mem_table_size) // cannot find entry
1308 tail = strchr(head, '\n');
1313 /* LOGI("Buffers = %016LX\n", mem_slot_array[MEM_SLOT_BUFFER]); */
1314 /* LOGI("Cached = %016LX\n", mem_slot_array[MEM_SLOT_CACHED]); */
1315 /* LOGI("MemFree = %016LX\n", mem_slot_array[MEM_SLOT_FREE]); */
1316 /* LOGI("MemTotal= %016LX\n", mem_slot_array[MEM_SLOT_TOTAL]); */
1317 if(num == mem_table_size) // find all element
1319 *memtotal = mem_slot_array[MEM_SLOT_TOTAL];
1320 *memused = mem_slot_array[MEM_SLOT_TOTAL] - mem_slot_array[MEM_SLOT_FREE] -
1321 mem_slot_array[MEM_SLOT_BUFFER] - mem_slot_array[MEM_SLOT_CACHED];
1324 *memtotal *= 1024; // change to Byte
1325 *memused *= 1024; // change to Byte
1330 LOGE("Cannot find all neccessary element in meminfo\n");
1336 // return 0 for error case
1337 // return system total memory in MB
1339 unsigned long get_system_total_memory()
1341 int meminfo_fd = manager.fd.procmeminfo;
1344 char buf[BUFFER_MAX];
1345 static const char* memtotalstr = "MemTotal";
1346 unsigned long totalmem = 0;
1348 if (meminfo_fd == -1)
1351 lseek(meminfo_fd, 0L, SEEK_SET);
1353 if((num = read(meminfo_fd, buf, BUFFER_MAX)) < 0)
1355 LOGE("Failed to read from " PROCMEMINFO "\n");
1359 if(num == BUFFER_MAX)
1366 tail = strchr(head, ':');
1370 if(strcmp(head, memtotalstr) == 0) // found
1373 totalmem = strtoul(head, &tail, 10);
1378 tail = strchr(head, '\n');
1384 return (totalmem * 1024);
1387 // ===============================================================
1388 // disk information getter functions
1389 // ===============================================================
1390 static int get_fsinfo(const char* path, int type)
1396 if (statfs(path, &buf) < 0)
1401 total = (int)((long long)(buf.f_bsize / 1024LL * buf.f_blocks) / 1024LL);
1402 free = (int)((long long)(buf.f_bsize / 1024LL * buf.f_bavail) / 1024LL);
1404 /* LOGI("File storage total(%d), free(%d)\n", total, free); */
1405 if (type == FSINFO_TYPE_TOTAL)
1409 else if (type == FSINFO_TYPE_FREE)
1417 static int stat_get_storageinfo(int type)
1419 return get_fsinfo(UMSFD, type);
1422 static int stat_get_cardinfo(int type)
1424 if (access(MMCBLKFD, F_OK) < 0)
1429 return get_fsinfo(MMCFD, type);
1433 static int get_total_drive()
1436 int storage = stat_get_storageinfo(FSINFO_TYPE_TOTAL);
1437 int card = stat_get_cardinfo(FSINFO_TYPE_TOTAL);
1439 if (storage < 0 && card < 0)
1444 total = storage + card;
1449 static int get_total_used_drive()
1453 int storage = stat_get_storageinfo(FSINFO_TYPE_FREE);
1454 int card = stat_get_cardinfo(FSINFO_TYPE_FREE);
1456 if (storage < 0 && card < 0)
1458 LOGI_th_samp("total_used_drive = -1\n");
1462 free = storage + card;
1463 total = get_total_drive() - free;
1465 LOGI_th_samp("total_used_drive = %d\n", total);
1470 static int update_thread_data(int pid)
1472 static struct stat sb;
1474 char path[PROCPATH_MAX];
1475 char buf[PROCPATH_MAX];
1477 DIR *taskdir = NULL;
1478 struct dirent *entry = NULL;
1481 sprintf(path, "/proc/%d/task", pid);
1483 if(!(taskdir = opendir(path)))
1485 LOGE("task not found '%s'\n", path);
1489 while((entry = readdir(taskdir)) != NULL)
1491 if(*entry->d_name > '0' && *entry->d_name <= '9')
1493 tid = atoi(entry->d_name);
1494 sprintf(buf, "/proc/%d/task/%d", pid, tid);
1496 if(unlikely(stat(buf, &sb) == -1))
1498 del_node(&thread_prochead, tid);
1503 if((procnode = find_node(thread_prochead, tid)) == NULL)
1505 procnode = add_node(&thread_prochead, tid);
1506 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
1508 LOGE("Failed to get proc stat file by tid(%d). add node\n", tid);
1512 procnode->saved_utime = procnode->proc_data.utime;
1513 procnode->saved_stime = procnode->proc_data.stime;
1514 /* LOGI("data updated\n"); */
1519 if (unlikely((ret = parse_proc_stat_file_bypid(buf, &(procnode->proc_data))) < 0))
1521 LOGE("Failed to get proc stat file by tid(%d). node exist\n", tid);
1527 del_notfound_node(&thread_prochead);
1528 reset_found_node(thread_prochead);
1534 // ========================================================================
1535 // overall information getter functions
1536 // ========================================================================
1538 // this code is not necessary anymore
1540 static void get_app_info(const char* binary_path, char* width,
1541 char* height, char* theme, char* version,
1542 char* scale, char* removable,
1549 char pkg_info_path [PATH_MAX];
1550 char buffer [BUFFER_MAX];
1552 sprintf(pkg_info_path, "/opt/share/applications/%s.desktop", pkg_name);
1554 fd = open(pkg_info_path, O_RDONLY);
1557 LOGE("Cannot open %s", pkg_info_path);
1561 fcntl( fd, F_SETFD, FD_CLOEXEC );
1563 LOGI("get_app_info - After open pkg_info_path\n");
1567 res = read(fd, buffer, BUFFER_MAX);
1580 LOGI("read buffer ===%s===\n", buffer);
1581 for (i = 0; i < res; i++)
1583 if (i < res - 22 && strncmp(&buffer[i], "X-SLP-BaseLayoutWidth=", 22) == 0)
1585 for (j = 0; j < res; j ++)
1587 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1589 LOGI("width :::: ");
1590 strncpy(width, &(buffer[i+22]), j-22);
1591 LOGI("%s\n", width);
1597 else if (i < res - 23 && strncmp(&buffer[i], "X-SLP-BaseLayoutHeight=", 23) == 0)
1599 for (j = 0; j < res; j ++)
1601 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1603 LOGI("height :::: ");
1604 strncpy(height, &(buffer[i+23]), j-23);
1605 LOGI("%s\n", height);
1611 else if (i < res - 6 && (strncmp(&buffer[i], "theme=", 6) == 0 || strncmp(&buffer[i], "Theme=", 6) == 0))
1613 for (j = 0; j < res; j ++)
1615 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1617 LOGI("theme :::: ");
1618 strncpy(theme, &(buffer[i+6]), j-6);
1619 LOGI("%s\n", theme);
1625 else if (i < res - 8 && (strncmp(&buffer[i], "Version=", 8) == 0 || strncmp(&buffer[i], "version=", 8) == 0))
1627 for (j = 0; j < res; j ++)
1629 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1631 LOGI("version :::: ");
1632 strncpy(version, &(buffer[i+8]), j-8);
1633 LOGI("%s\n", version);
1639 else if (i < res - 24 && strncmp(&buffer[i], "X-SLP-IsHorizontalScale=", 24) == 0)
1641 for (j = 0; j < res; j ++)
1643 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1645 LOGI("scale :::: ");
1646 strncpy(scale, &(buffer[i+24]), j-24);
1647 LOGI("%s\n", scale);
1653 else if (i < res - 16 && strncmp(&buffer[i], "X-SLP-Removable=", 16) == 0)
1655 for (j = 0; j < res; j ++)
1657 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1659 LOGI("removable :::: ");
1660 strncpy(removable, &(buffer[i+16]), j-16);
1661 LOGI("%s\n", removable);
1667 else if (i < res - 8 && (strncmp(&buffer[i], "Comment=", 8) == 0 || strncmp(&buffer[i], "comment=", 8) == 0))
1669 for (j = 0; j < res; j ++)
1671 if (buffer[i+j] == '\n' || buffer[i+j] == '\t')
1673 LOGI("comments :::: ");
1674 strncpy(comment, &(buffer[i+8]), j-8);
1675 LOGI("%s\n", comment);
1687 int get_camera_count()
1692 char buf[BUFFER_MAX];
1694 fp = fopen(CAMCORDER_FILE, "r");
1697 size = strlen(CAMERA_COUNT_STR);
1699 while(fgets(buf, BUFFER_MAX, fp) != NULL)
1701 if(strncmp(buf, CAMERA_COUNT_STR, size) == 0) {
1702 sscanf(buf, CAMERA_COUNT_STR " = %d", &count);
1715 static int get_device_network_type(char* buf, int buflen)
1721 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.cdma", &bool_var);
1722 if(bool_var) len += sprintf(buf + len, "CDMA,");
1723 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.edge", &bool_var);
1724 if(bool_var) len += sprintf(buf + len, "EDGE,");
1725 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.gprs", &bool_var);
1726 if(bool_var) len += sprintf(buf + len, "GPRS,");
1727 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.gsm", &bool_var);
1728 if(bool_var) len += sprintf(buf + len, "GSM,");
1729 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.hsdpa", &bool_var);
1730 if(bool_var) len += sprintf(buf + len, "HSDPA,");
1731 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.hspa", &bool_var);
1732 if(bool_var) len += sprintf(buf + len, "HSPA,");
1733 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.hsupa", &bool_var);
1734 if(bool_var) len += sprintf(buf + len, "HSUPA,");
1735 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.umts", &bool_var);
1736 if(bool_var) len += sprintf(buf + len, "UMTS,");
1737 system_info_get_platform_bool("tizen.org/feature/network.telephony.service.lte", &bool_var);
1738 if(bool_var) len += sprintf(buf + len, "LTE,");
1747 static int get_device_availability_info(char* buf, int buflen)
1749 int camera_count = 0;
1750 bool blue_support = false;
1751 bool gps_support = false;
1752 bool wifi_support = false;
1753 char* networktype = NULL;
1755 char network_type[128];
1759 system_info_get_platform_bool("tizen.org/feature/network.bluetooth", &blue_support);
1760 camera_count = get_camera_count();
1761 system_info_get_platform_bool("tizen.org/feature/location.gps", &gps_support);
1762 network_len = get_device_network_type(networktype, 128);
1763 system_info_get_platform_bool("tizen.org/feature/network.wifi", &wifi_support);
1766 loglen += sprintf(buf, "%d`,%d`,%d`,%d`,",
1772 if(network_type != NULL && network_len > 0) {
1773 loglen += sprintf(buf + loglen, "%s", networktype);
1780 int get_device_info(char* buffer, int buffer_len)
1784 char width[BUFFER_MAX];
1785 char height[BUFFER_MAX];
1786 char theme[BUFFER_MAX];
1787 char version[BUFFER_MAX];
1788 char scale[BUFFER_MAX];
1789 char removable[BUFFER_MAX];
1790 char comment[BUFFER_MAX * 2];
1792 memset(width, 0, sizeof(width));
1793 memset(height, 0, sizeof(height));
1794 memset(theme, 0, sizeof(theme));
1795 memset(version, 0, sizeof(version));
1796 memset(scale, 0, sizeof(scale));
1797 memset(removable, 0, sizeof(removable));
1798 memset(comment, 0, sizeof(comment));
1800 res += sprintf(buffer, "%lu`,%d`,", get_system_total_memory(), get_total_drive());
1801 res += get_device_availability_info(buffer + res, buffer_len - res);
1802 res += sprintf(buffer + res, "`,%d", get_max_brightness());
1804 res += sprintf(buffer + res, "`,`,`,`,`,`,`,");
1805 // res += sprintf(buffer + res, "`,%s`,%s`,%s`,%s`,%s`,%s`,%s", width, height, theme, version, scale, removable, comment);
1810 int update_cpus_info(int event_num, float elapsed)
1814 // calculate for system cpu load
1816 for(i = 0; i < num_of_cpu; i++)
1818 for(i = num_of_cpu; i <= num_of_cpu; i++)
1821 LOGI_th_samp("CPU #%d\n", i);
1822 cpuptr = &(cpus[i]);
1824 if(cpuptr->cur_load_index == event_num)
1826 if(cpuptr->sav_load_index == event_num - 1) // previous sampling is just before 1 period
1828 cpuptr->idle_ticks = cpuptr->i - cpuptr->i_sav;
1829 if(unlikely(cpuptr->idle_ticks < 0))
1831 cpuptr->idle_ticks = 0;
1833 cpuptr->total_ticks = (cpuptr->u - cpuptr->u_sav) +
1834 (cpuptr->s - cpuptr->s_sav) +
1835 (cpuptr->n - cpuptr->n_sav) +
1836 cpuptr->idle_ticks +
1837 (cpuptr->w - cpuptr->w_sav) +
1838 (cpuptr->x - cpuptr->x_sav) +
1839 (cpuptr->y - cpuptr->y_sav) +
1840 (cpuptr->z - cpuptr->z_sav);
1841 if(cpuptr->total_ticks < MIN_TOTAL_TICK)
1843 cpuptr->cpu_usage = 0.0f;
1847 cpuptr->cpu_usage = (1.0f - ((float)cpuptr->idle_ticks /
1848 (float)cpuptr->total_ticks)) * 100.0f;
1850 // if(i != num_of_cpu)
1852 // idle_tick_sum += cpuptr->idle_ticks;
1853 // total_tick_sum += cpuptr->total_ticks;
1855 LOGI_th_samp("System cpu usage log : %d, %Ld, %Ld\n",
1856 i, cpuptr->idle_ticks, cpuptr->total_ticks);
1857 if(unlikely(cpuptr->cpu_usage < 0))
1859 cpuptr->cpu_usage = 0.0f;
1862 else // previous sampling is not just before 1 period
1864 // assume non idle ticks happen in 1 profiling period
1865 // because sampling is not available just before 1 profiling period
1866 cpuptr->idle_ticks = (cpuptr->u - cpuptr->u_sav) +
1867 (cpuptr->s - cpuptr->s_sav) +
1868 (cpuptr->n - cpuptr->n_sav) +
1869 (cpuptr->w - cpuptr->w_sav) +
1870 (cpuptr->x - cpuptr->x_sav) +
1871 (cpuptr->y - cpuptr->y_sav) +
1872 (cpuptr->z - cpuptr->z_sav);
1873 cpuptr->total_ticks = (long long)(Hertz * elapsed);
1874 if(unlikely(cpuptr->total_ticks < 1))
1875 cpuptr->total_ticks = 1;
1876 cpuptr->cpu_usage = ((float)cpuptr->idle_ticks /
1877 (float)cpuptr->total_ticks) * 100.0f;
1878 if(unlikely(cpuptr->cpu_usage > 100.0f))
1880 cpuptr->cpu_usage = 100.0f;
1885 cpuptr->u_sav = cpuptr->u;
1886 cpuptr->s_sav = cpuptr->s;
1887 cpuptr->n_sav = cpuptr->n;
1888 cpuptr->i_sav = cpuptr->i;
1889 cpuptr->w_sav = cpuptr->w;
1890 cpuptr->x_sav = cpuptr->x;
1891 cpuptr->y_sav = cpuptr->y;
1892 cpuptr->z_sav = cpuptr->z;
1893 cpuptr->sav_load_index = cpuptr->cur_load_index;
1897 cpuptr->cpu_usage = 0.0f;
1901 // calculate for cpu core load that failed to get tick information
1905 LOGI("ticks1 : %Ld, %Ld\n", idle_tick_sum, total_tick_sum);
1906 idle_tick_sum = cpus[num_of_cpu].idle_ticks - idle_tick_sum;
1907 total_tick_sum = cpus[num_of_cpu].total_ticks - total_tick_sum;
1908 LOGI("ticks2 : %Ld, %Ld\n", idle_tick_sum, total_tick_sum);
1909 if(total_tick_sum >= MIN_TICKS_FOR_LOAD)
1910 sys_usage = (1.0f - ((float)idle_tick_sum / (float)total_tick_sum)) * 100.0f;
1913 if(sys_usage < 0.0f) sys_usage = 0.0f;
1914 else if(sys_usage > 100.0f) sys_usage = 100.0f;
1916 for(i = 0; i < num_of_cpu; i++)
1918 if(failed_cpu & (1 << i))
1920 cpus[i].cpu_usage = sys_usage;
1928 int fill_system_processes_info(float factor, struct system_info_t * sys_info)
1934 unsigned long virtual = 0;
1935 unsigned long resident = 0;
1936 unsigned long shared = 0;
1937 unsigned long pssmem = 0;
1939 float app_cpu_usage = 0.0;
1941 LOGI_th_samp("prochead = %X\n", (unsigned int)prochead);
1942 for(proc = prochead; proc != NULL; proc = proc->next)
1944 //increment process count
1945 sys_info->count_of_processes++; //maybe wrong
1947 sys_info->process_load = malloc (
1948 sys_info->count_of_processes *
1949 sizeof(*sys_info->process_load)
1952 for(proc = prochead; proc != NULL; proc = proc->next)
1954 LOGI_th_samp("proc#%d (%d %d),(%d %d) (%d) %f\n",
1956 (unsigned int)proc->proc_data.utime, (unsigned int)proc->proc_data.stime ,
1957 (unsigned int)proc->saved_utime, (unsigned int)proc->saved_stime,
1958 (int)(proc->proc_data.utime + proc->proc_data.stime - proc->saved_utime - proc->saved_stime),
1960 proc->saved_utime + proc->saved_stime -
1961 proc->proc_data.utime - proc->proc_data.stime
1963 thread_load = (float)(proc->proc_data.utime + proc->proc_data.stime -
1964 proc->saved_utime - proc->saved_stime) * factor;
1966 if(thread_load > 100.0f)
1967 thread_load = 100.0f;
1969 //num_thread += proc->proc_data.numofthread;
1970 virtual += proc->proc_data.vir_mem; // Byte
1971 resident += (proc->proc_data.res_memblock * 4); // KByte
1972 pssmem += (proc->proc_data.pss); // KByte
1973 shared += (proc->proc_data.sh_mem); // KByte
1974 ticks += (proc->proc_data.utime + proc->proc_data.stime -
1975 proc->saved_utime - proc->saved_stime);
1977 proc->saved_utime = proc->proc_data.utime;
1978 proc->saved_stime = proc->proc_data.stime;
1981 sys_info->process_load[i].id = proc->proc_data.pid;
1982 sys_info->process_load[i].load = thread_load;
1987 app_cpu_usage = (float)ticks * factor;
1988 if(app_cpu_usage > 100.0f)
1989 app_cpu_usage = 100.0f;
1990 resident = resident * 1024; // change to Byte
1991 pssmem = pssmem * 1024; // change to Byte
1992 shared = shared * 1024; // change to Byte
1994 sys_info->virtual_memory = virtual;
1995 sys_info->resident_memory = resident;
1996 sys_info->shared_memory = shared;
1997 sys_info->pss_memory = pssmem;
1999 sys_info->app_cpu_usage = app_cpu_usage;
2005 // fill threads information
2006 int fill_system_threads_info(float factor, struct system_info_t * sys_info)
2011 for(proc = thread_prochead; proc != NULL; proc = proc->next)
2012 //increment thread count
2013 sys_info->count_of_threads++; //maybe wrong
2015 /* LOGI_th_samp("thread load\n"); */
2016 struct thread_info_t *pthread;
2017 if (sys_info->count_of_threads != 0)
2019 sys_info->thread_load = malloc( sys_info->count_of_threads * sizeof(*sys_info->thread_load) );
2020 pthread = sys_info->thread_load;
2023 for(proc = thread_prochead; proc != NULL; proc = proc->next)
2025 thread_load = (float)(proc->proc_data.utime + proc->proc_data.stime -
2026 proc->saved_utime - proc->saved_stime)
2028 if(thread_load > 100.0f)
2029 thread_load = 100.0f;
2031 pthread->pid = proc->proc_data.pid;
2032 pthread->load = thread_load;
2035 // sprintf(thread_loadtmpbuf, "%d,%.1f,", proc->proc_data.pid, thread_load);
2036 // strcat(thread_loadbuf, thread_loadtmpbuf);
2038 proc->saved_utime = proc->proc_data.utime;
2039 proc->saved_stime = proc->proc_data.stime;
2045 //fill system cpu information
2046 int fill_system_cpu_info(struct system_info_t *sys_info)
2048 float sys_usage = 0.0f;
2051 // calculate for whole cpu load by average all core load
2052 LOGI_th_samp("calculate for whole cpu load num_of_cpu=%d\n", num_of_cpu);
2053 for(i = 0 ; i < num_of_cpu; i++)
2054 sys_usage += cpus[i].cpu_usage;
2058 if (num_of_cpu != 0)
2060 sys_info->cpu_load = malloc( num_of_cpu * sizeof(*sys_info->cpu_load) );
2061 pcpu_usage = sys_info->cpu_load;
2062 for(i = 0; i < num_of_cpu; i++)
2064 LOGI_th_samp("cpu#%d : %.1f\n" , i, cpus[i].cpu_usage);
2065 *pcpu_usage = cpus[i].cpu_usage;
2070 //fill CPU frequency
2071 sys_info->cpu_frequency = malloc(num_of_cpu * sizeof(float));
2072 if (!sys_info->cpu_frequency) {
2073 LOGE("Cannot alloc cpu freq\n");
2076 get_cpu_frequency(sys_info->cpu_frequency);
2082 //fill cpu frequency based on cpu tick count in different cpu frequence states
2083 int fill_cpu_frequecy(int event_num)
2085 // calculate for system cpu frequency
2086 float sys_usage = 0.0f;
2087 uint64_t ticks = 0, freqsum = 0;
2091 for(i = 0; i < num_of_cpu; i++)
2093 cpuptr = &(cpus[i]);
2095 if(cpuptr->cur_freq_index == event_num)
2097 if(cpuptr->sav_freq_index == event_num - 1)
2099 for(j = 0; j < num_of_freq; j++)
2101 freqsum += (cpuptr->pfreq[j].freq *
2102 (cpuptr->pfreq[j].tick - cpuptr->pfreq[j].tick_sav));
2103 ticks += (cpuptr->pfreq[j].tick - cpuptr->pfreq[j].tick_sav);
2110 for(j = 0; j < num_of_freq; j++)
2112 cpuptr->pfreq[j].tick_sav = cpuptr->pfreq[j].tick; // restore last tick value
2114 cpuptr->sav_freq_index = cpuptr->cur_freq_index;
2120 if(sys_usage == 0.0f)
2121 sys_usage = (float)freqsum / (float)ticks;
2122 // TODO use sys_usage as cpu #i core freq
2126 //freqbufpos += sprintf(freqbuf + freqbufpos, "%.0f,", sys_usage);
2136 static void skip_lines(FILE * fp, unsigned int count)
2138 char *buffer = NULL;
2141 for (index = 0; index != count; ++index)
2142 getline(&buffer, &buflen, fp);
2146 static void skip_tokens(FILE * fp, unsigned int count)
2150 for (index = 0; index != count; ++index)
2154 static void init_network_stat()
2156 manager.fd.networkstat = fopen("/proc/net/dev", "r");
2159 static void get_network_stat(uint32_t * recv, uint32_t * send)
2161 FILE *fp = manager.fd.networkstat;
2162 uintmax_t irecv, isend;
2171 skip_lines(fp, 2); /* strip header */
2173 while (fscanf(fp, "%s", ifname) != EOF)
2174 if (strcmp("lo:", ifname)) {
2175 fscanf(fp, "%" SCNuMAX, &irecv);
2178 fscanf(fp, "%" SCNuMAX, &isend);
2184 skip_tokens(fp, 16);
2187 static void init_disk_stat(void)
2189 manager.fd.diskstats = fopen("/proc/diskstats", "r");
2192 //function return partition sector size
2195 // <size> if no errors
2196 static int get_partition_sector_size(const char * partition_name)
2200 char sec_size_buff[LARGE_BUFFER];
2202 sprintf(sec_size_buff, "/sys/block/%s/queue/hw_sector_size", partition_name);
2203 sfp = fopen(sec_size_buff, "r");
2205 LOGE("cannot detect sector size for <%s> (%s)\n",
2206 partition_name, sec_size_buff);
2209 fscanf(sfp, "%d", &sec_size);
2212 LOGE("cannot detect sector size for <%s> (%s)\n",
2213 partition_name, sec_size_buff);
2220 static void get_disk_stat(uint32_t *reads, uint32_t *sec_reads,
2221 uint32_t * writes, uint32_t *sec_writes)
2224 enum { partition_name_maxlength = 128 };
2225 FILE *fp = manager.fd.diskstats;
2226 char master_partition[partition_name_maxlength] = { 0 };
2228 *reads = *writes = 0;
2229 *sec_reads = *sec_writes = 0;
2239 char partition[partition_name_maxlength];
2240 uintmax_t preads, pwrites;
2241 uintmax_t psec_read, psec_write;
2243 fscanf(fp, "%s", partition);
2244 if (*master_partition
2245 && !strncmp(master_partition, partition,
2246 strlen(master_partition))) {
2248 skip_tokens(fp, 11);
2250 // FIXME it is not good way call this func
2251 // each time to get partition sector size
2252 /*sec_size = get_partition_sector_size(partition);
2256 LOGE("get RW error\n");
2262 fscanf(fp, "%" SCNuMAX, &preads);
2265 fscanf(fp, "%" SCNuMAX, &psec_read);
2268 fscanf(fp, "%" SCNuMAX, &pwrites);
2271 fscanf(fp, "%" SCNuMAX, &psec_write);
2274 memcpy(master_partition, partition,
2275 partition_name_maxlength);
2276 // FIXME rw size is in sectors
2277 // actualy different disks - different partition sector size (?)
2278 // maybe need convert to bytes like this:
2279 //*read += pread * sec_size;
2280 //*write += pwrite * sec_size;
2285 *sec_reads += psec_read;
2286 *sec_writes += psec_write;
2293 static float get_elapsed(void)
2295 static struct timeval old_time = {0, 0};
2296 struct timeval current_time;
2299 gettimeofday(¤t_time, NULL);
2300 elapsed = (current_time.tv_sec - old_time.tv_sec) +
2301 ((float)(current_time.tv_usec - old_time.tv_usec) / 1000000.0f);
2302 old_time.tv_sec = current_time.tv_sec;
2303 old_time.tv_usec = current_time.tv_usec;
2308 static float get_factor(float elapsed)
2310 return 100.0f / ((float)Hertz * elapsed * num_of_cpu);
2313 static uint64_t read_int64_from_file(const char *fname)
2315 FILE *fp = fopen(fname, "r");
2319 if (fscanf(fp, "%lld", &value) != 1)
2325 #define swap_sysfs_relpath(x) ("/sys/kernel/debug/swap/energy/" #x)
2326 #define swap_read_int64(x) (read_int64_from_file(swap_sysfs_relpath(x)))
2328 // Calculates difference between current and previous sample (system).
2329 // Stores mutable state in static variables.
2330 static uint32_t pop_sys_energy_per_device(enum supported_device dev)
2332 static uint64_t cpu_old, flash_old;
2333 uint64_t cpu_new, flash_new;
2334 uint64_t cpu_diff, flash_diff;
2338 cpu_new = swap_read_int64(cpu_idle/system) +
2339 swap_read_int64(cpu_running/system);
2340 cpu_diff = cpu_new - cpu_old;
2342 return (uint32_t)cpu_diff;
2345 flash_new = swap_read_int64(flash_read/system) +
2346 swap_read_int64(flash_write/system);
2347 flash_diff = flash_new - flash_old;
2348 flash_old = flash_new;
2349 return (uint32_t)flash_diff;
2351 assert(0 && "Unknown device. This should not happen");
2356 // Calculates difference between current and previous sample (app).
2357 // Stores mutable state in static variables.
2358 static uint32_t pop_app_energy_per_device(enum supported_device dev)
2360 static uint64_t cpu_old, flash_old;
2361 uint64_t cpu_new, flash_new;
2362 uint64_t cpu_diff, flash_diff;
2366 cpu_new = swap_read_int64(cpu_running/apps);
2367 cpu_diff = cpu_new - cpu_old;
2369 return (uint32_t)cpu_diff;
2371 flash_new = swap_read_int64(flash_read/apps) +
2372 swap_read_int64(flash_write/apps);
2373 flash_diff = flash_new - flash_old;
2374 flash_old = flash_new;
2375 return (uint32_t)flash_diff;
2377 assert(0 && "Unknown device. This should not happen");
2382 // return log length (>0) for normal case
2383 // return negative value for error
2384 int get_system_info(struct system_info_t *sys_info, int* pidarray, int pidcount)
2386 static int event_num = 0;
2387 uint64_t sysmemtotal = 0;
2388 uint64_t sysmemused = 0;
2393 LOGI_th_samp("start\n");
2394 LOGI_th_samp("PID count : %d\n", pidcount);
2396 // clean output structure
2397 memset(sys_info, 0, sizeof(*sys_info));
2399 // common (cpu, processes, memory)
2400 if (IS_OPT_SET(FL_CPU) ||
2401 IS_OPT_SET(FL_PROCESSES) ||
2402 IS_OPT_SET(FL_MEMORY)) {
2403 if (update_process_data(pidarray, pidcount, PROCDATA_STAT) < 0) {
2404 LOGE("Failed to update process stat data\n");
2408 // this position is optimized position of timestamp.
2409 // just before get system cpu data and just after get process cpu data
2410 // because cpu data is changed so fast and variance is so remarkable
2411 elapsed = get_elapsed(); // DO NOT MOVE THIS SENTENCE!
2412 factor = get_factor(elapsed);
2414 if (update_system_cpu_data(event_num) < 0) {
2415 LOGE("Failed to update system cpu data\n");
2420 if (update_system_cpu_frequency(event_num) < 0) {
2421 LOGE("Failed to update system cpu freq data\n");
2425 // memory data is changed slowly and variance is not remarkable
2426 // so memory data is less related with timestamp then cpu data
2427 if (update_process_data(pidarray, pidcount, PROCDATA_SMAPS) < 0) {
2428 LOGE("Failed to update process smaps data\n");
2433 if (update_thread_data(pidarray[0]) < 0) {
2434 LOGE("Failed to update thread stat data\n");
2438 if (update_system_memory_data(&sysmemtotal, &sysmemused) < 0) {
2439 LOGE("Failed to update system memory data\n");
2443 // update cpus information
2444 if (update_cpus_info(event_num, elapsed) < 0) {
2445 LOGE("Failed to update cpus info\n");
2449 // calculate process load, memory, app_cpu_usage
2450 if (fill_system_processes_info(factor, sys_info) < 0) {
2451 LOGE("Failed to fill processes info\n");
2455 // calculate thread load
2456 if (fill_system_threads_info(factor, sys_info) < 0) {
2457 LOGE("Failed to fill threads info\n");
2461 if (fill_system_cpu_info(sys_info) < 0) {
2462 LOGE("Failed to fill threads info\n");
2467 // memory (not full)
2468 if (IS_OPT_SET(FL_MEMORY)) {
2469 sys_info->total_alloc_size = get_total_alloc_size();
2470 sys_info->system_memory_total = sysmemtotal;
2471 sys_info->system_memory_used = sysmemused;
2474 // Fill result strutcture
2475 LOGI_th_samp("fill result structure\n");
2478 if (IS_OPT_SET(FL_DISK)) {
2479 sys_info->total_used_drive = get_total_used_drive();
2480 get_disk_stat(&sys_info->disk_reads,
2481 &sys_info->disk_sectors_read,
2482 &sys_info->disk_writes,
2483 &sys_info->disk_sectors_write);
2487 if (IS_OPT_SET(FL_NETWORK))
2488 get_network_stat(&sys_info->network_send_size,
2489 &sys_info->network_receive_size);
2492 if (IS_OPT_SET(FL_DEVICE)) {
2493 sys_info->wifi_status = get_wifi_status();
2494 sys_info->bt_status = get_bt_status();
2495 sys_info->gps_status = get_gps_status();
2496 sys_info->brightness_status = get_brightness_status();
2497 sys_info->camera_status = get_camera_status();
2498 sys_info->sound_status = get_sound_status();
2499 sys_info->audio_status = get_audio_status();
2500 sys_info->vibration_status = get_vibration_status();
2501 sys_info->voltage_status = get_voltage_status();
2502 sys_info->rssi_status = get_rssi_status();
2503 sys_info->video_status = get_video_status();
2504 sys_info->call_status = get_call_status();
2505 sys_info->dnet_status = get_dnet_status();
2507 #else /* LOCALTEST */
2509 if (IS_OPT_SET(FL_DISK)) {
2510 sys_info->disk_read_size = 0x20;
2511 sys_info->disk_write_size = 0x21;
2515 if (IS_OPT_SET(FL_NETWORK)) {
2516 sys_info->network_send_size = 0x22;
2517 sys_info->network_receive_size = 0x23;
2521 if (IS_OPT_SET(FL_DEVICE)) {
2522 sys_info->wifi_status = 2;
2523 sys_info->bt_status = 3;
2524 sys_info->gps_status = 4;
2525 sys_info->brightness_status = 5;
2526 sys_info->camera_status = 6;
2527 sys_info->sound_status = 7;
2528 sys_info->audio_status = 8;
2529 sys_info->vibration_status = 9;
2530 sys_info->voltage_status = 0xa;
2531 sys_info->rssi_status = 0xb;
2532 sys_info->video_status = 0xc;
2533 sys_info->call_status = 0xd;
2534 sys_info->dnet_status = 0xe;
2536 #endif /* LOCALTEST */
2538 if (IS_OPT_SET(FL_ENERGY)) {
2540 sys_info->energy = 0; // not implemented
2541 for (i = 0; i != supported_devices_count; ++i) {
2542 sys_info->energy_per_device[i] =
2543 pop_sys_energy_per_device(i);
2544 sys_info->app_energy_per_device[i] =
2545 pop_app_energy_per_device(i);
2549 #ifdef THREAD_SAMPLING_DEBUG
2550 print_sys_info(sys_info);
2554 LOGI_th_samp("exit\n");
2558 //some data corrupted
2559 //free allocated data
2560 reset_system_info(sys_info);
2561 LOGI_th_samp("fail exit\n");
2565 int initialize_system_info()
2569 num_of_cpu = sysconf(_SC_NPROCESSORS_CONF);
2572 Hertz = sysconf(_SC_CLK_TCK);
2573 LOGI("Hertz : %d\n", Hertz);
2577 cpus = (CPU_t*) calloc((num_of_cpu + 1), sizeof(CPU_t));
2580 for(i = 0; i <= num_of_cpu; i++)
2582 cpus[i].cur_load_index = cpus[i].sav_load_index = -1;
2583 cpus[i].cur_freq_index = cpus[i].sav_freq_index = -1;
2588 LOGE("Failed to alloc memory for cpu information\n");
2595 int finalize_system_info()
2601 for(i = 0; i < num_of_cpu; i++)
2603 if(cpus[i].pfreq != NULL)
2604 free(cpus[i].pfreq);
2614 static void test_and_close(int *fd)
2621 static void ftest_and_close(FILE **fd)
2629 #define str(x) strr(x)
2630 #define dtest_and_close(fd) do {LOGI("CLOSE " str(fd) "\n");test_and_close(fd);} while(0)
2631 #define dftest_and_close(fd) do {LOGI("CLOSE " str(fd) "\n");ftest_and_close(fd);} while(0)
2632 void close_system_file_descriptors()
2634 dtest_and_close(&manager.fd.brightness);
2635 dtest_and_close(&manager.fd.voltage);
2636 dtest_and_close(&manager.fd.procmeminfo);
2638 dftest_and_close(&manager.fd.video);
2639 dftest_and_close(&manager.fd.audio_status);
2640 dftest_and_close(&manager.fd.procstat);
2641 dftest_and_close(&manager.fd.networkstat);
2642 dftest_and_close(&manager.fd.diskstats);
2645 int init_system_file_descriptors()
2648 init_brightness_status();
2649 init_voltage_status();
2650 init_update_system_memory_data();
2652 init_video_status();
2653 init_audio_status();
2654 init_system_cpu_data();
2655 init_network_stat();
2658 if (manager.fd.brightness < 0)
2659 LOGW("brightness file not found\n");
2660 if (manager.fd.voltage < 0)
2661 LOGW("voltage file not found\n");
2662 if (manager.fd.procmeminfo < 0)
2663 LOGW("procmeminfo file not found\n");
2665 if (manager.fd.video == NULL)
2666 LOGW("video file not found\n");
2667 if (manager.fd.audio_status == NULL)
2668 LOGW("audio file not found\n");
2669 if (manager.fd.procstat == NULL)
2670 LOGW("procstat file not found\n");
2671 if (manager.fd.networkstat == NULL)
2672 LOGW("networkstat file not found\n");
2673 if (manager.fd.diskstats == NULL)
2674 LOGW("diskstat file not found\n");
2678 //CMD SOCKET FUNCTIONS
2679 int fill_target_info(struct target_info_t *target_info)
2681 /* system_info_get_value_bool() changes only 1 byte
2682 so we need to be sure that the integer as a whole is correct */
2683 target_info->bluetooth_supp = 0;
2684 target_info->gps_supp = 0;
2685 target_info->wifi_supp = 0;
2686 target_info->camera_count = 0;
2687 target_info->network_type[0] = 0;
2689 target_info->sys_mem_size = get_system_total_memory();
2690 target_info->storage_size = stat_get_storageinfo(FSINFO_TYPE_TOTAL) *
2694 system_info_get_platform_bool("tizen.org/feature/network.bluetooth",
2695 (_Bool *)&target_info->bluetooth_supp);
2698 system_info_get_platform_bool("tizen.org/feature/location.gps",
2699 (_Bool *)&target_info->gps_supp);
2701 system_info_get_platform_bool("tizen.org/feature/network.wifi",
2702 (_Bool *)&target_info->wifi_supp);
2704 target_info->camera_count = get_camera_count();
2706 get_device_network_type(target_info->network_type, NWTYPE_SIZE);
2709 #endif /* LOCALTEST */
2710 target_info->max_brightness = get_max_brightness();
2711 target_info->cpu_core_count = sysconf(_SC_NPROCESSORS_CONF);
2715 struct msg_data_t *pack_system_info(struct system_info_t *sys_info)
2717 struct msg_data_t *msg = NULL;
2720 uint32_t len = sizeof(*sys_info) -
2721 (sizeof(sys_info->thread_load) +
2722 sizeof(sys_info->process_load)) +
2723 2 * num_of_cpu * sizeof(float) +
2724 sys_info->count_of_threads * sizeof(*sys_info->thread_load) +
2725 sys_info->count_of_processes * sizeof(*sys_info->process_load);
2727 msg = malloc(MSG_DATA_HDR_LEN + len);
2729 LOGE("Cannot alloc message: %d bytes\n", len);
2733 fill_data_msg_head(msg, NMSG_SYSTEM, 0, len);
2737 if (IS_OPT_SET(FL_CPU)) {
2738 pack_float(p, sys_info->app_cpu_usage);
2740 for (i = 0; i < num_of_cpu; i++) {
2741 if (sys_info->cpu_frequency)
2742 pack_float(p, sys_info->cpu_frequency[i]);
2747 for (i = 0; i < num_of_cpu; i++) {
2748 if (sys_info->cpu_load)
2749 pack_float(p, sys_info->cpu_load[i]);
2754 pack_int(p, sys_info->count_of_threads);
2755 for (i = 0; i < sys_info->count_of_threads; i++) {
2756 if (sys_info->thread_load) {
2757 pack_int(p, sys_info->thread_load[i].pid);
2758 pack_float(p, sys_info->thread_load[i].load);
2765 pack_float(p, 0.0); // pack app_cpu_usage
2767 for (i = 0; i < num_of_cpu; i++) {
2768 pack_float(p, 0.0); // pack cpu_frequency
2769 pack_float(p, 0.0); // pack cpu_load
2772 pack_int(p, 0); // pack count_of_threads
2776 if (IS_OPT_SET(FL_PROCESSES)) {
2777 pack_int(p, sys_info->count_of_processes);
2778 for (i = 0; i < sys_info->count_of_processes; i++) {
2779 if (sys_info->process_load) {
2780 pack_int(p, sys_info->process_load[i].id);
2781 pack_float(p, sys_info->process_load[i].load);
2788 pack_int(p, 0); // pack count_of_processes
2792 if (IS_OPT_SET(FL_MEMORY)) {
2793 pack_int(p, sys_info->virtual_memory);
2794 pack_int(p, sys_info->resident_memory);
2795 pack_int(p, sys_info->shared_memory);
2796 pack_int(p, sys_info->pss_memory);
2797 pack_int(p, sys_info->total_alloc_size);
2798 pack_int(p, sys_info->system_memory_total);
2799 pack_int(p, sys_info->system_memory_used);
2801 pack_int(p, 0); // pack virtual_memory
2802 pack_int(p, 0); // pack resident_memory
2803 pack_int(p, 0); // pack shared_memory
2804 pack_int(p, 0); // pack pss_memory
2805 pack_int(p, 0); // pack total_alloc_size
2806 pack_int(p, 0); // pack system_memory_total
2807 pack_int(p, 0); // pack system_memory_used
2810 pack_int(p, sys_info->disk_reads);
2811 pack_int(p, sys_info->disk_sectors_read);
2812 pack_int(p, sys_info->disk_writes);
2813 pack_int(p, sys_info->disk_sectors_write);
2815 pack_int(p, sys_info->network_send_size);
2816 pack_int(p, sys_info->network_receive_size);
2818 pack_int(p, sys_info->wifi_status);
2819 pack_int(p, sys_info->bt_status);
2820 pack_int(p, sys_info->gps_status);
2821 pack_int(p, sys_info->brightness_status);
2822 pack_int(p, sys_info->camera_status);
2823 pack_int(p, sys_info->sound_status);
2824 pack_int(p, sys_info->audio_status);
2825 pack_int(p, sys_info->vibration_status);
2826 pack_int(p, sys_info->voltage_status);
2827 pack_int(p, sys_info->rssi_status);
2828 pack_int(p, sys_info->video_status);
2829 pack_int(p, sys_info->call_status);
2830 pack_int(p, sys_info->dnet_status);
2831 pack_int(p, sys_info->energy);
2832 for (i = 0; i != supported_devices_count; ++i)
2833 pack_int(p, sys_info->energy_per_device[i]);
2834 for (i = 0; i != supported_devices_count; ++i)
2835 pack_int(p, sys_info->app_energy_per_device[i]);
2837 // pack_int(p, sys_info->total_used_drive);