2 * Copyright (C) 2013 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <cutils/log.h>
24 #include <hardware/memtrack.h>
26 #include "memtrack_exynos.h"
28 /* Following includes added for directory parsing. */
29 #include <sys/types.h>
32 /* Some general defines. */
33 #define MALI_DEBUG_FS_PATH "/d/mali/mem/"
34 #define MALI_DEBUG_MEM_FILE "/mem_profile"
36 #define MAX_FILES_PER_PID 8
37 #define MAX_FILES_PER_NAME 32
38 static int libmemtrack_gbl_input_filename_counter
= 0;
39 static char libmemtrack_gbl_input_filename
[MAX_FILES_PER_PID
][MAX_FILES_PER_NAME
];
41 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
42 #define min(x, y) ((x) < (y) ? (x) : (y))
44 struct memtrack_record record_templates
[] = {
46 .flags
= MEMTRACK_FLAG_SMAPS_ACCOUNTED
|
47 MEMTRACK_FLAG_PRIVATE
|
48 MEMTRACK_FLAG_NONSECURE
,
51 .flags
= MEMTRACK_FLAG_SMAPS_UNACCOUNTED
|
52 MEMTRACK_FLAG_PRIVATE
|
53 MEMTRACK_FLAG_NONSECURE
,
57 static void scan_directory_for_filenames(pid_t pid
)
59 /* As per ARM, there can be multiple files */
61 struct dirent
*entries
;
62 char pid_string
[8] = {0};
66 directory
= opendir(MALI_DEBUG_FS_PATH
);
68 sprintf(pid_string
, "%d", pid
);
69 for (pid_index
= 0; pid_index
< 8; pid_index
++) {
70 if (pid_string
[pid_index
] == 0) {
71 pid_string
[pid_index
] = '_';
76 libmemtrack_gbl_input_filename_counter
= 0;
78 if (directory
!= NULL
) {
79 /* Keep reading the directory. */
80 while ((entries
= readdir(directory
))) {
81 /* Check if the PID is present in the direcotry entry.
82 * If it is present, then keep the filename for reading
83 * contents. Also concatenate the directory path, so that
86 if (!strncmp(entries
->d_name
, pid_string
, strlen(pid_string
))) {
87 snprintf(&libmemtrack_gbl_input_filename
[libmemtrack_gbl_input_filename_counter
][0], MAX_FILES_PER_NAME
, "%s%s%s", MALI_DEBUG_FS_PATH
, entries
->d_name
, MALI_DEBUG_MEM_FILE
);
88 libmemtrack_gbl_input_filename_counter
++;
91 /* Close directory before leaving. */
92 (void) closedir(directory
);
94 ALOGE("libmemtrack-hw -- Couldn't open the directory - %s \r\n", MALI_DEBUG_FS_PATH
);
100 int mali_memtrack_get_memory(pid_t pid
, enum memtrack_type __unused type
,
101 struct memtrack_record
*records
,
104 size_t allocated_records
= min(*num_records
, ARRAY_SIZE(record_templates
));
107 unsigned int temp_val
= 0, total_memory_size
= 0, native_buf_mem_size
= 0;
108 bool native_buffer_read
= false;
109 char line
[1024] = {0};
111 *num_records
= ARRAY_SIZE(record_templates
);
113 /* fastpath to return the necessary number of records */
114 if (allocated_records
== 0) {
118 memcpy(records
, record_templates
,
119 sizeof(struct memtrack_record
) * allocated_records
);
121 /* First, scan the directoy. */
122 scan_directory_for_filenames(pid
);
125 total_memory_size
= 0;
126 native_buf_mem_size
= 0;
128 while (local_count
< libmemtrack_gbl_input_filename_counter
) {
129 fp
= fopen(&libmemtrack_gbl_input_filename
[local_count
][0], "r");
132 /* Unable to open the file. Either move to next file, or
133 * return to caller. */
139 char memory_type
[16] = {0};
140 char memory_type_2
[16] = {0};
143 if (native_buffer_read
== false) {
144 if (fgets(line
, sizeof(line
), fp
) == NULL
) {
145 if (native_buffer_read
== false) {
146 /* Unable to read Native buffer.
147 * Probably DDK doesn't support Native Buffer.
148 * Reset to start of file and look for Total
150 fseek(fp
, 0, SEEK_SET
);
152 /* Also, set Native buffer flag and memory sizes. */
153 native_buffer_read
= true;
158 /* Search for Total memory. */
161 * Channel: Native Buffer (Total memory: 44285952)
164 ret
= sscanf(line
, "%*s %15s %15s %*s %*s %d \n", memory_type
, memory_type_2
, &temp_val
);
169 if ((strcmp(memory_type
, "Native") == 0) &&
170 (strcmp(memory_type_2
, "Buffer") == 0)) {
171 /* Set native buffer memory read flag to true. */
172 native_buffer_read
= true;
173 native_buf_mem_size
+= temp_val
;
175 /* Ignore case. Nothing to do here. */
176 /* Continue reading file until NativeBuffer is found. */
179 if (fgets(line
, sizeof(line
), fp
) == NULL
) {
180 /* Unable to find, so break the loop here.*/
184 /* Search for Total memory. */
187 * Total allocated memory: 36146960
190 ret
= sscanf(line
, "%15s %*s %*s %d \n", memory_type
, &temp_val
);
195 if (strcmp(memory_type
, "Total") == 0) {
196 /* Store total memory. */
197 total_memory_size
+= temp_val
;
199 /* Ignore case. Nothing to do here. */
201 } /* end if (native_buffer_read == false) */
206 /* Close the opened file. */
209 /* Reset some of the local variables here. */
211 native_buffer_read
= false;
214 /* Manage local variables and counters. */
217 } /* while (local_count <= libmemtrack_gbl_input_filename_counter) */
219 /* Arrange and return memory size details. */
220 if (allocated_records
> 0)
221 records
[0].size_in_bytes
= 0;
223 if (allocated_records
> 1)
224 records
[1].size_in_bytes
= total_memory_size
- native_buf_mem_size
;