From 1f6d5009021c7351c4a55d1308cfc7f4702b9a56 Mon Sep 17 00:00:00 2001 From: Wenchao Hao Date: Fri, 22 Nov 2024 19:06:49 +0800 Subject: [PATCH] Add case to test zram data correct Signed-off-by: Wenchao Hao --- madvise.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 madvise.c diff --git a/madvise.c b/madvise.c new file mode 100644 index 0000000..0f52fa0 --- /dev/null +++ b/madvise.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SIZE 19*1024*1024 +#define PAGE_SIZE 4096 // 4KB +#define CHUNK_SIZE 8 * 1024 // 8KB + +void compute_md5(const unsigned char *data, size_t length, unsigned char *md5_hash) { + MD5_CTX md5_ctx; + + MD5_Init(&md5_ctx); + + MD5_Update(&md5_ctx, data, length); + + MD5_Final(md5_hash, &md5_ctx); +} + +void print_md5(unsigned char *md5_hash) { + for (int i = 0; i < MD5_DIGEST_LENGTH; i++) { + printf("%02x", md5_hash[i]); + } + printf("\n"); +} + +unsigned long long tv_to_ms(struct timeval tv) +{ + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +int main() +{ + char c; + pid_t pid; + int i; + int j = 0; + struct timeval tv_b, tv_e;; + unsigned char md5_hash[MD5_DIGEST_LENGTH]; + + unsigned long *p = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (!p) { + perror("fail to get memory"); + exit(-1); + } + + printf("0x%lx\n", p); + + madvise(p, SIZE, MADV_HUGEPAGE); + + for (j = 0; j < SIZE / 8; j += 8) + *(p + j) = j; + + for (size_t offset = PAGE_SIZE; offset < SIZE; offset += CHUNK_SIZE) { + char *str = (char *)p + offset; + + sprintf(str, "child"); + } + + for (size_t offset = PAGE_SIZE; offset < SIZE; offset += CHUNK_SIZE) { + compute_md5((unsigned char *)p + offset, PAGE_SIZE, md5_hash); + printf("MD5 of the buffer: "); + print_md5(md5_hash); + } + + gettimeofday(&tv_b, NULL); + madvise(p, SIZE, MADV_PAGEOUT); + gettimeofday(&tv_e, NULL); + + printf("swp out bandwidth: %ld bytes/ms\n", + SIZE/(tv_to_ms(tv_e) - tv_to_ms(tv_b))); + + pid = fork(); + + if (pid == 0) { + printf("child: freeing some swap\n"); + for (size_t offset = 0; offset < SIZE; offset += CHUNK_SIZE) { + if (madvise((void *)((char *)p + offset), PAGE_SIZE, MADV_DONTNEED) == -1) { + perror("madvise failed"); + return -1; + } + } + + printf("child: sleep\n"); + sleep(5); + + printf("child: reading swaped data\n"); + + for (size_t offset = PAGE_SIZE; offset < SIZE; offset += CHUNK_SIZE) { + char *str = (char *)p + offset; + + if (strcmp(str, "child")) + printf("%s\n", str); + + } + printf("child: read done\n"); + + for (size_t offset = PAGE_SIZE; offset < SIZE; offset += CHUNK_SIZE) { + compute_md5((unsigned char *)p + offset, PAGE_SIZE, md5_hash); + printf("MD5 of the buffer: "); + print_md5(md5_hash); + } +#if 2 + } else { + printf("parent: sleeping\n"); + sleep(1); + printf("parent: unmapping origin memory region\n"); + munmap(p, SIZE); + printf("parent: alloc new memory region\n"); + + p = mmap(NULL, 9 * 1024 * 1024, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + for (j = 0; j < 1024 * 1024; j+=8) + *(p + j) = j + 10; + + for (size_t offset = 0; offset < 8 * 1024 * 1024; offset += CHUNK_SIZE) { + char *str = (char *)p + offset + PAGE_SIZE; + sprintf(str, "parent"); + } + + madvise(p, 9 * 1024 * 1024, MADV_PAGEOUT); +#endif + } + + while(1) { + sleep(100); + } + + return 0; +}