Update memps functionality 87/94587/6 accepted/tizen/3.0/common/20161114.082855 accepted/tizen/3.0/ivi/20161110.022705 accepted/tizen/3.0/mobile/20161110.022610 accepted/tizen/3.0/tv/20161110.022638 accepted/tizen/3.0/wearable/20161110.022650 accepted/tizen/common/20161110.153633 accepted/tizen/ivi/20161110.002046 accepted/tizen/mobile/20161110.001953 accepted/tizen/tv/20161110.002009 accepted/tizen/wearable/20161110.002026 submit/tizen/20161109.144928 submit/tizen_3.0/20161109.145028 submit/tizen_3.0_common/20161110.084657
authorVitaliy Cherepanov <v.cherepanov@samsung.com>
Mon, 31 Oct 2016 14:34:01 +0000 (17:34 +0300)
committerVitaliy Cherepanov <v.cherepanov@samsung.com>
Wed, 9 Nov 2016 14:19:16 +0000 (06:19 -0800)
Change-Id: Ifdf5b265f85ecc4c7a05bd9d4650c777ba5c020f
Signed-off-by: Vitaliy Cherepanov <v.cherepanov@samsung.com>
daemon/sys_stat.c

index dd111cd..4ce7c0f 100644 (file)
@@ -741,9 +741,72 @@ static uint64_t total_gem_memory(void)
        return total_gem_mem;
 }
 
-static int ignore_smaps_field = 0;
+static int smaps_field_lcnt = 0;
 
-void init_read_mapinfo(void)
+#define BUF_INC_SIZE    (512 * 1024)        /* maximal SMAPS I saw 2 MB     */
+/* reads file contents into memory */
+static char* cread(const char* path)
+{
+       /* once allocated area for reads */
+       static char*    text = NULL;
+       static size_t   size = 0;
+
+       ssize_t ret;
+       char*   ptr = text;
+       size_t  cap = size;
+       int     fd  = open(path, O_RDONLY);
+
+       if (fd < 0) {
+               return NULL;
+       }
+
+       do {
+               /* ensure we have enough space */
+               if (cap == 0) {
+                       ptr = (char*)realloc(text, size + BUF_INC_SIZE);
+                       if (ptr == NULL) {
+                               ret = -1;
+                               break;
+                       }
+
+                       text  = ptr;
+                       ptr   = text + size;
+                       cap   = BUF_INC_SIZE;
+                       size += BUF_INC_SIZE;
+               }
+               ret = read(fd, ptr, cap);
+               if (ret == 0) {
+                       *ptr = 0;
+               } else if (ret > 0) {
+                       cap -= ret;
+                       ptr += ret;
+               }
+       } while (ret > 0);
+       close(fd);
+
+       return (ret < 0 ? NULL : text);
+} /* cread */
+
+/* like fgets/gets but adjusting contents pointer */
+static inline char* cgets(char** contents)
+{
+       if (contents && *contents && **contents) {
+               char* bos = *contents;          /* begin of string */
+               char* eos = strchr(bos, '\n');  /* end of string   */
+
+               if (eos) {
+                       *contents = eos + 1;
+                       *eos      = 0;
+               } else {
+                       *contents = NULL;
+               }
+               return bos;
+       }
+
+       return NULL;
+} /* cgets */
+
+int get_fixed_smaps_lcnt(void)
 {
        struct utsname buf;
        int ret;
@@ -751,48 +814,116 @@ void init_read_mapinfo(void)
        ret = uname(&buf);
 
        if (!ret) {
-               if (buf.release[0] == '3') {
-                       char *pch;
-                       char str[3];
-                       int sub_version;
-                       pch = strstr(buf.release, ".");
-                       strncpy(str, pch+1, 2);
-                       sub_version = atoi(str);
-
-                       if (sub_version >= 10) {
-                               /* Referenced, Anonymous, AnonHugePages,
-                                * Swap, KernelPageSize, MMUPageSize,
-                                * Locked, VmFlags
-                                */
-                               ignore_smaps_field = 8;
-                       } else {
-                               /* Referenced, Anonymous, AnonHugePages,
-                                * Swap, KernelPageSize, MMUPageSize,
-                                * Locked
-                                */
-                               ignore_smaps_field = 7;
-                       }
-               } else {
-                       /* Referenced, Swap, KernelPageSize, MMUPageSize */
-                       ignore_smaps_field = 4;
-               }
+       char *pch;
+       char str[3];
+       int sub_version;
+       pch = strstr(buf.release, ".");
+       strncpy(str, pch+1, 2);
+       sub_version = atoi(str);
+
+       if (buf.release[0] >= '4') {
+               if (sub_version >= 4)
+               ret = 18;
+               /* Size, Rss, Pss, Shared_Clean, Shard_Dirty,
+                * Private_Clean, Private_Drity,
+                * Referenced, Anonymous, AnonHugePages, Shared_Hugetlb,
+                * Private_Hugetlb, Swap, SwapPss, KernelPageSize,
+                * MMUPageSize, Locked, VmFlags */
+               else if (sub_version == 3)
+               ret = 16;
+               /* Size, Rss, Pss, Shared_Clean, Shard_Dirty,
+                * Private_Clean, Private_Drity,
+                * Referenced, Anonymous, AnonHugePages, Swap, SwapPss,
+                * KernelPageSize, MMUPageSize, Locked, VmFlags */
+               else
+               ret = 15;
+               /* Size, Rss, Pss, Shared_Clean, Shard_Dirty,
+                * Private_Clean, Private_Drity,
+                * Referenced, Anonymous, AnonHugePages, Swap,
+                * KernelPageSize, MMUPageSize, Locked, VmFlags */
+       } else if (buf.release[0] == '3') {
+               if (sub_version >= 10)
+               ret = 15;
+               /* Size, Rss, Pss, Shared_Clean, Shard_Dirty,
+                * Private_Clean, Private_Drity,
+                * Referenced, Anonymous, AnonHugePages, Swap,
+                * KernelPageSize, MMUPageSize, Locked, VmFlags */
+               else
+               ret = 14;
+               /* Size, Rss, Pss, Shared_Clean, Shard_Dirty,
+                * Private_Clean, Private_Drity,
+                * Referenced, Anonymous, AnonHugePages, Swap,
+                * KernelPageSize, MMUPageSize, Locked */
+       } else {
+               ret = 11;
+               /* Size, Rss, Pss, Shared_Clean, Shard_Dirty,
+                * Private_Clean, Private_Drity,
+                * Referenced, Swap, KernelPageSize, MMUPageSize */
+       }
+       }
+       return ret;
+}
+
+int get_smaps_lcnt(void)
+{
+       char *buf, *buf_start, *line;
+       char cmd[64] = "/proc/self/smaps";
+       int line_count = 0;
+       long start_addr, end_addr;
+       unsigned long pg_off;
+       int major, minor;
+       char flags[4];
+
+       buf_start = cread(cmd);
+       if (buf_start == NULL)
+               goto error;
+
+       buf = buf_start;
+       line = cgets(&buf);
+       if (!line)
+               goto error;
+
+       if (sscanf(line, "%lx-%lx %s %lx %x:%x", &start_addr, &end_addr,
+                  flags, &pg_off, &major, &minor) != 6)
+               goto error;
+
+       while ((line = cgets(&buf)) != NULL) {
+               line_count++;
+               if (sscanf(line, "%lx-%lx %s %lx %x:%x", &start_addr,
+                          &end_addr, flags, &pg_off, &major, &minor) == 6)
+                       break;
        }
+
+       free(buf_start);
+       return line_count;
+
+error:
+       free(buf_start); /*TODO redesign it*/
+       return get_fixed_smaps_lcnt();
 }
-/* 6f000000-6f01e000 rwxp 00000000 00:0c 16389419   /android/lib/libcomposer.so
- * 012345678901234567890123456789012345678901234567890123456789
- * 0         1         2         3         4         5
- */
 
+void init_read_mapinfo()
+{
+       smaps_field_lcnt = get_smaps_lcnt();
+}
+
+/* b6e82000-b6e83000 rw-p 00020000 b3:19 714        /usr/lib/ld-2.20-2014.11.so  : TM1
+ * 7fae2e4b2000-7fae2e4b3000 r--p 00021000 fe:01 603                        /usr/lib64/ld-2.20-2014.11.so  : x86-64 Emulator
+ * 7f9389d000-7f9389e000 rw-p 0001f000 b3:12 618                            /usr/lib64/ld-2.20-2014.11.so  : Note4
+ * 01234567890123456789012345678901234567890123456789012345678901234567890123456789
+ * 0         1         2         3         4         5         6         7
+ */
 #define NAME_OFFSET    49
 int read_mapinfo_section(FILE* fp, proc_t *proc)
 {
        char* line;
        int len;
        int tmp;
-       int rest_line;
+       int line_cnt;
        char buf[LARGE_BUFFER];
 
-       if ((line = fgets(buf, sizeof(buf), fp)) == 0)
+       line_cnt = smaps_field_lcnt;
+       if ((--line_cnt <= 0) || (line = fgets(buf, sizeof(buf), fp)) == 0)
                return -EOF;
 
        len = strlen(buf);
@@ -806,70 +937,20 @@ int read_mapinfo_section(FILE* fp, proc_t *proc)
                strncpy(proc->command, buf + NAME_OFFSET, len + 1);
        }
 
-       if ((line = fgets(buf, sizeof(buf), fp)) == 0) {
-               LOGE("Get section error\n");
-               goto oops;
-       }
-       if (sscanf(buf, "Size: %lu kB", &proc->size) != 1) {
-               LOGE("Get section error\n");
-               goto oops;
-       }
-       if ((line = fgets(buf, sizeof(buf), fp)) == 0) {
-               LOGE("Get section error\n");
-               goto oops;
-       }
-       if (sscanf(buf, "Rss: %d kB", &tmp) != 1) {
-               LOGE("Get section error\n");
-               goto oops;
-       }
-       if ((line = fgets(buf, sizeof(buf), fp)) == 0) {
-               LOGE("Get section error\n");
-               goto oops;
-       }
-       if (sscanf(buf, "Pss: %lu kB", &proc->pss) == 1)
-               if ((line = fgets(buf, sizeof(buf), fp)) == 0) {
-                       LOGE("Get section error\n");
-                       goto oops;
-       }
-       if (sscanf(buf, "Shared_Clean: %lu kB", &proc->sh_mem_clean) != 1) {
-               LOGE("Get section error\n");
-               goto oops;
-       }
-       if ((line = fgets(buf, sizeof(buf), fp)) == 0) {
-               LOGE("Get section error\n");
-               goto oops;
-       }
-       if (sscanf(buf, "Shared_Dirty: %lu kB", &proc->sh_mem_dirty) != 1) {
-               LOGE("Get section error\n");
-               goto oops;
-       }
-       if ((line = fgets(buf, sizeof(buf), fp)) == 0) {
-               LOGE("Get section error\n");
-               goto oops;
-       }
-       if (sscanf(buf, "Private_Clean: %d kB", &tmp) != 1) {
-               LOGE("Get section error\n");
-               goto oops;
-       }
-       if ((line = fgets(buf, sizeof(buf), fp)) == 0) {
-               LOGE("Get section error\n");
-               goto oops;
-       }
-       if (sscanf(buf, "Private_Dirty: %d kB", &tmp) != 1) {
-               LOGE("Get section error\n");
-               goto oops;
-       }
 
-       rest_line = ignore_smaps_field;
-       while (rest_line-- && (line = fgets(buf, sizeof(buf), fp))) {
-               if (sscanf(buf, "PSwap: %d kB", &tmp) == 1)
-                       rest_line++;
+       while (line_cnt-- && (line = fgets(buf, sizeof(buf), fp))) {
+               if (sscanf(line, "Size: %lu kB", &proc->size) == 1) {}
+               else if (sscanf(line, "Rss: %d kB", &tmp) == 1) {}
+               else if (sscanf(line, "Pss: %lu kB", &proc->pss) == 1) {}
+               else if (sscanf(line, "Shared_Clean: %lu kB",
+                               &proc->sh_mem_clean) == 1) {}
+               else if (sscanf(line, "Shared_Dirty: %lu kB",
+                               &proc->sh_mem_dirty) == 1) {}
+               else if (sscanf(line, "Private_Clean: %d kB", &tmp) == 1) {}
+               else if (sscanf(line, "Private_Dirty: %d kB", &tmp) == 1) {}
+               else if (sscanf(line, "Swap: %d kB", &tmp) == 1) {}
        }
-
        return 0;
-oops:
-       LOGE("Get section error\n");
-       return -1;
 }