#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; }