Signed-off-by: Wenchao Hao <haowenchao22@gmail.com>
This commit is contained in:
Wenchao Hao 2025-01-28 07:36:11 +08:00
parent c397822817
commit 956b58e3fc
1 changed files with 173 additions and 0 deletions

173
multi_process_memory_test.c Normal file
View File

@ -0,0 +1,173 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/wait.h>
#define MAX_ALLOC_SIZE (256 * 1024 * 1024) // Maximum size for a single anonymous allocation (256MB)
#define MAX_SLEEP_TIME 5 // Maximum sleep time (5 seconds)
#define MMAP_FILE "testfile.dat" // File used for mmap operations
#define DIRECT_IO_FILE "direct_io_file.dat" // File used for direct read/write operations
#define FILE_SIZE (128 * 1024 * 1024) // File size (128MB)
#define NUM_PROCESSES 4 // Number of child processes
// Generate a random size within the given limit
size_t random_size(size_t max) {
return (rand() % max) + 1;
}
void allocate_anonymous_memory() {
// Randomly allocate fragmented anonymous memory
size_t alloc_size = random_size(MAX_ALLOC_SIZE);
void *mem = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mem == MAP_FAILED) {
perror("Anonymous mmap failed");
return;
}
// Touch the memory to trigger physical allocation
for (size_t i = 0; i < alloc_size; i += 4096) {
((char *)mem)[i] = rand() % 256;
}
// Lock part of the allocated memory
if (mlock(mem, alloc_size / 2) != 0) {
perror("mlock failed");
}
// Sleep for a random time
unsigned int sleep_time = random_size(MAX_SLEEP_TIME);
sleep(sleep_time);
// Unlock and release the memory
if (munmap(mem, alloc_size) != 0) {
perror("munmap failed");
}
}
void allocate_file_backed_memory() {
// Open or create the file for mmap
int fd = open(MMAP_FILE, O_CREAT | O_RDWR, 0644);
if (fd < 0) {
perror("File open failed (mmap file)");
return;
}
// Expand the file to the target size
if (ftruncate(fd, FILE_SIZE) != 0) {
perror("File truncate failed (mmap file)");
close(fd);
return;
}
// Map the file into memory
void *file_mem = mmap(NULL, FILE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (file_mem == MAP_FAILED) {
perror("File-backed mmap failed");
close(fd);
return;
}
// Modify the memory-mapped file region
for (size_t i = 0; i < FILE_SIZE; i += 4096) {
((char *)file_mem)[i] = rand() % 256;
}
// Sleep for a random time
unsigned int sleep_time = random_size(MAX_SLEEP_TIME);
sleep(sleep_time);
// Unmap the file-backed memory
if (munmap(file_mem, FILE_SIZE) != 0) {
perror("munmap failed");
}
close(fd);
}
void direct_file_read_write() {
// Open or create the file for direct I/O
int fd = open(DIRECT_IO_FILE, O_CREAT | O_RDWR, 0644);
if (fd < 0) {
perror("File open failed (direct I/O file)");
return;
}
// Expand the file to the target size
if (ftruncate(fd, FILE_SIZE) != 0) {
perror("File truncate failed (direct I/O file)");
close(fd);
return;
}
// Perform read/write operations on the file
char buffer[4096];
for (size_t i = 0; i < FILE_SIZE; i += sizeof(buffer)) {
// Write random data
memset(buffer, rand() % 256, sizeof(buffer));
if (write(fd, buffer, sizeof(buffer)) < 0) {
perror("File write failed (direct I/O file)");
close(fd);
return;
}
// Reset the file offset
lseek(fd, i, SEEK_SET);
// Read data back
if (read(fd, buffer, sizeof(buffer)) < 0) {
perror("File read failed (direct I/O file)");
close(fd);
return;
}
}
close(fd);
}
void child_process_task() {
srand(time(NULL) ^ getpid()); // Use a different random seed for each child process
while (1) {
// Execute anonymous memory allocation
allocate_anonymous_memory();
// Execute file-backed memory operations
allocate_file_backed_memory();
// Execute direct file read/write operations
direct_file_read_write();
// Sleep for a short time between iterations
unsigned int sleep_time = random_size(3); // Short sleep
sleep(sleep_time);
}
}
int main() {
pid_t pids[NUM_PROCESSES];
// Create multiple child processes
for (int i = 0; i < NUM_PROCESSES; i++) {
pids[i] = fork();
if (pids[i] == 0) {
// Child process executes the task
child_process_task();
exit(0); // Prevent the child process from continuing in the parent code
} else if (pids[i] < 0) {
perror("Fork failed");
exit(1);
}
}
// Parent process waits for child processes to exit
for (int i = 0; i < NUM_PROCESSES; i++) {
waitpid(pids[i], NULL, 0);
}
return 0;
}