update
Signed-off-by: Wenchao Hao <haowenchao22@gmail.com>
This commit is contained in:
parent
c397822817
commit
956b58e3fc
|
|
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue