From df551a7653b2e4573fcdea243f50c8d1954c3540 Mon Sep 17 00:00:00 2001 From: Rokas Puzonas Date: Sat, 6 Jan 2024 21:36:40 +0200 Subject: [PATCH] add memory mapped files example --- file-mmap/build.zig | 20 ++++++++ file-mmap/main.c | 114 ++++++++++++++++++++++++++++++++++++++++++++ shm_open/main.c | 8 ++-- 3 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 file-mmap/build.zig create mode 100644 file-mmap/main.c diff --git a/file-mmap/build.zig b/file-mmap/build.zig new file mode 100644 index 0000000..7590388 --- /dev/null +++ b/file-mmap/build.zig @@ -0,0 +1,20 @@ +const std = @import("std"); + +pub fn build(b: *std.build.Builder) void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const exe = b.addExecutable(.{ + .name = "mmap-example", + .root_source_file = .{ .path = "main.c" }, + .optimize = optimize, + .target = target + }); + exe.linkLibC(); + + const run_cmd = b.addRunArtifact(exe); + const run_step = b.step("run", "Run simple program"); + run_step.dependOn(&run_cmd.step); + + b.installArtifact(exe); +} diff --git a/file-mmap/main.c b/file-mmap/main.c new file mode 100644 index 0000000..f51130b --- /dev/null +++ b/file-mmap/main.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include +#include + +struct shared_data { + pthread_mutex_t mutex; + int counter; +}; + +struct shm_shared_data { + int file_fd; + struct shared_data *shared_data; +}; + +void increment_counter(struct shared_data *data) { + for (int i = 0; i < 100000; i++) { + if (pthread_mutex_lock(&data->mutex) != 0) { + perror("pthread_mutex_lock"); + } + + data->counter++; + + if (pthread_mutex_unlock(&data->mutex) != 0) { + perror("pthread_mutex_unlock"); + } + } +} + +struct shm_shared_data shared_data_open() { + // Open or create a file + int fd = open("/tmp/shared_memory", O_CREAT | O_RDWR, 0666); + if (fd == -1) { + perror("open"); + exit(EXIT_FAILURE); + } + + int shm_size = sizeof(struct shared_data); + + // Set the size of the file + if (ftruncate(fd, shm_size) == -1) { + perror("ftruncate"); + exit(EXIT_FAILURE); + } + + // Map the file into the process address space + struct shared_data *shared_data = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (shared_data == MAP_FAILED) { + perror("mmap"); + exit(EXIT_FAILURE); + } + + struct shm_shared_data shm_shared_data = { + .file_fd = fd, + .shared_data = shared_data + }; + + return shm_shared_data; +} + +void shared_data_close(struct shm_shared_data shm_data) { + // Unmap the shared memory + if (munmap(shm_data.shared_data, sizeof(struct shared_data)) == -1) { + perror("munmap"); + exit(EXIT_FAILURE); + } + + // Close the file + if (close(shm_data.file_fd) == -1) { + perror("close"); + exit(EXIT_FAILURE); + } +} + +void *thread_callback(void *p) { + struct shm_shared_data shm_data = shared_data_open(); + + increment_counter(shm_data.shared_data); + + shared_data_close(shm_data); + + return NULL; +} + +int main() { + struct shm_shared_data shm_data = shared_data_open(); + + pthread_mutexattr_t mutex_attr; + pthread_mutexattr_init(&mutex_attr); + pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED); + + shm_data.shared_data->counter = 0; + if (pthread_mutex_init(&shm_data.shared_data->mutex, &mutex_attr) < 0) { + printf("Failed to initialise mutex\n"); + return -1; + } + + pthread_t thread1; + pthread_create(&thread1, NULL, thread_callback, NULL); + + pthread_t thread2; + pthread_create(&thread2, NULL, thread_callback, NULL); + + pthread_join(thread1, NULL); + pthread_join(thread2, NULL); + + printf("Counter is %d\n", shm_data.shared_data->counter); + + shared_data_close(shm_data); + + return 0; +} diff --git a/shm_open/main.c b/shm_open/main.c index fe832a4..29e7a54 100644 --- a/shm_open/main.c +++ b/shm_open/main.c @@ -67,13 +67,13 @@ struct shm_shared_data shared_data_open() { void shared_data_close(struct shm_shared_data shm_data) { // Unmap the shared memory and close the file descriptor if (munmap(shm_data.shared_data, sizeof(struct shared_data)) == -1) { - perror("munmap"); - exit(EXIT_FAILURE); + perror("munmap"); + exit(EXIT_FAILURE); } if (close(shm_data.shm_fd) == -1) { - perror("close"); - exit(EXIT_FAILURE); + perror("close"); + exit(EXIT_FAILURE); } }