upload android base code part6
This commit is contained in:
parent
421e214c7d
commit
4e516ec6ed
35396 changed files with 9188716 additions and 0 deletions
169
android/system/extras/pagecache/dumpcache.c
Normal file
169
android/system/extras/pagecache/dumpcache.c
Normal file
|
@ -0,0 +1,169 @@
|
|||
#include <ftw.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stddef.h>
|
||||
#include <mntent.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
// Initial size of the array holding struct file_info
|
||||
#define INITIAL_NUM_FILES 512
|
||||
|
||||
// Max number of file descriptors to use for ntfw
|
||||
#define MAX_NUM_FD 1
|
||||
|
||||
struct file_info {
|
||||
char *name;
|
||||
size_t file_size;
|
||||
size_t num_cached_pages;
|
||||
};
|
||||
|
||||
// Size of pages on this system
|
||||
static int g_page_size;
|
||||
|
||||
// Total number of cached pages found so far
|
||||
static size_t g_total_cached = 0;
|
||||
|
||||
// Total number of files scanned so far
|
||||
static size_t g_num_files = 0;
|
||||
|
||||
// Scanned files and their associated cached page counts
|
||||
static struct file_info **g_files;
|
||||
|
||||
// Current size of files array
|
||||
size_t g_files_size;
|
||||
|
||||
static struct file_info *get_file_info(const char* fpath, size_t file_size) {
|
||||
struct file_info *info;
|
||||
if (g_num_files >= g_files_size) {
|
||||
g_files = realloc(g_files, 2 * g_files_size * sizeof(struct file_info*));
|
||||
if (!g_files) {
|
||||
fprintf(stderr, "Couldn't allocate space for files array: %s\n", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
g_files_size = 2 * g_files_size;
|
||||
}
|
||||
|
||||
info = calloc(1, sizeof(*info));
|
||||
if (!info) {
|
||||
fprintf(stderr, "Couldn't allocate space for file struct: %s\n", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
info->name = malloc(strlen(fpath) + 1);
|
||||
if (!info->name) {
|
||||
fprintf(stderr, "Couldn't allocate space for file struct: %s\n", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
strcpy(info->name, fpath);
|
||||
|
||||
info->num_cached_pages = 0;
|
||||
info->file_size = file_size;
|
||||
|
||||
g_files[g_num_files++] = info;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static int store_num_cached(const char* fpath, const struct stat *sb) {
|
||||
int fd, ret = -1;
|
||||
fd = open (fpath, O_RDONLY);
|
||||
|
||||
if (fd == -1) {
|
||||
fprintf(stderr, "Could not open file: %s\n", fpath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* mapped_addr = mmap(NULL, sb->st_size, PROT_NONE, MAP_SHARED, fd, 0);
|
||||
|
||||
if (mapped_addr != MAP_FAILED) {
|
||||
// Calculate bit-vector size
|
||||
size_t num_file_pages = (sb->st_size + g_page_size - 1) / g_page_size;
|
||||
unsigned char* mincore_data = calloc(1, num_file_pages);
|
||||
ret = mincore(mapped_addr, sb->st_size, mincore_data);
|
||||
if (!ret) {
|
||||
int num_cached = 0;
|
||||
unsigned int page = 0;
|
||||
for (page = 0; page < num_file_pages; page++) {
|
||||
if (mincore_data[page]) num_cached++;
|
||||
}
|
||||
if (num_cached > 0) {
|
||||
struct file_info *info = get_file_info(fpath, sb->st_size);
|
||||
info->num_cached_pages += num_cached;
|
||||
g_total_cached += num_cached;
|
||||
}
|
||||
}
|
||||
munmap(mapped_addr, sb->st_size);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scan_entry(const char *fpath, const struct stat *sb, int typeflag,
|
||||
struct FTW * __attribute__((unused))ftwbuf) {
|
||||
if (typeflag == FTW_F) {
|
||||
store_num_cached(fpath, sb);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmpsize(size_t a, size_t b) {
|
||||
if (a < b) return -1;
|
||||
if (a > b) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmpfiles(const void *a, const void *b) {
|
||||
return cmpsize((*((struct file_info**)a))->num_cached_pages,
|
||||
(*((struct file_info**)b))->num_cached_pages);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
size_t i;
|
||||
g_page_size = getpagesize();
|
||||
|
||||
g_files = malloc(INITIAL_NUM_FILES * sizeof(struct file_info*));
|
||||
g_files_size = INITIAL_NUM_FILES;
|
||||
|
||||
// Walk filesystem trees through procfs except rootfs/devfs/sysfs/procfs
|
||||
FILE* fp = setmntent("/proc/mounts", "r");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "Error opening /proc/mounts\n");
|
||||
return -errno;
|
||||
}
|
||||
struct mntent* mentry;
|
||||
while ((mentry = getmntent(fp)) != NULL) {
|
||||
if (strcmp(mentry->mnt_type, "rootfs") != 0 &&
|
||||
strncmp("/dev", mentry->mnt_dir, strlen("/dev")) != 0 &&
|
||||
strncmp("/sys", mentry->mnt_dir, strlen("/sys")) != 0 &&
|
||||
strncmp("/proc", mentry->mnt_dir, strlen("/proc")) != 0) {
|
||||
nftw(mentry->mnt_dir, &scan_entry, MAX_NUM_FD, FTW_MOUNT | FTW_PHYS | FTW_DEPTH);
|
||||
}
|
||||
}
|
||||
endmntent(fp);
|
||||
|
||||
// Sort entries
|
||||
qsort(g_files, g_num_files, sizeof(g_files[0]), &cmpfiles);
|
||||
|
||||
// Dump entries
|
||||
for (i = 0; i < g_num_files; i++) {
|
||||
struct file_info *info = g_files[i];
|
||||
fprintf(stdout, "%s: %zu cached pages (%.2f MB, %zu%% of total file size.)\n", info->name,
|
||||
info->num_cached_pages,
|
||||
(float) (info->num_cached_pages * g_page_size) / 1024 / 1024,
|
||||
(100 * info->num_cached_pages * g_page_size) / info->file_size);
|
||||
}
|
||||
|
||||
fprintf(stdout, "TOTAL CACHED: %zu pages (%f MB)\n", g_total_cached,
|
||||
(float) (g_total_cached * 4096) / 1024 / 1024);
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue