diff --git a/multi_process_memory_test.c b/multi_process_memory_test.c new file mode 100644 index 0000000..d71c20d --- /dev/null +++ b/multi_process_memory_test.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +}