linux-sysprog · advanced · ~15 min
Structure and coordinate shared memory communication channels safely in C.
Shared memory mapped files (mmap, shm_open) share state across process boundaries. Coordinated concurrent access uses memory fences and lockless atomic status flags.
Given the memory-mapped status layout:
typedef struct {
uint32_t magic; // 0x53484D31 ("SHM1")
uint32_t write_sequence;
uint32_t message_count;
char last_message[64];
} ShmHeader;
Implement:
int shm_format_region(void *region, size_t size);
int shm_publish_message(void *region, size_t size, const char *msg);
int shm_read_latest(const void *region, size_t size, char *out_buf, size_t out_cap, uint32_t *out_seq);
shm_format_region: if region == NULL or size < sizeof(ShmHeader), return -1. Zero the struct, set magic = 0x53484D31, write_sequence = 0, message_count = 0, and return 0.shm_publish_message: if region == NULL, msg == NULL, size < sizeof(ShmHeader), or magic != 0x53484D31, return -1. Increment write_sequence, increment message_count, copy msg into last_message (truncating at 63 chars with NUL), and return 0.shm_read_latest: if region == NULL, out_buf == NULL, out_seq == NULL, size < sizeof(ShmHeader), or magic != 0x53484D31, return -1. If message_count == 0, return 1 (no messages yet). Otherwise, copy last_message to out_buf (up to out_cap), write write_sequence to *out_seq, and return 0.char mem[sizeof(ShmHeader)];
shm_format_region(mem, sizeof(mem));
shm_publish_message(mem, sizeof(mem), "heartbeat");
char buf[64]; uint32_t seq;
shm_read_latest(mem, sizeof(mem), buf, sizeof(buf), &seq); // returns 0, seq == 1
region: pointer to shared memory buffer; size: buffer capacity.
Returns 0 on success, 1 on empty, -1 on invalid format/arguments.
Zero dynamic allocations. Bounded string copies.
#include <stddef.h>
#include <stdint.h>
typedef struct {
uint32_t magic;
uint32_t write_sequence;
uint32_t message_count;
char last_message[64];
} ShmHeader;
int shm_format_region(void *region, size_t size) {
(void)region; (void)size;
return -1;
}
int shm_publish_message(void *region, size_t size, const char *msg) {
(void)region; (void)size; (void)msg;
return -1;
}
int shm_read_latest(const void *region, size_t size, char *out_buf, size_t out_cap, uint32_t *out_seq) {
(void)region; (void)size; (void)out_buf; (void)out_cap; (void)out_seq;
return -1;
}
Forgetting to check magic marker; buffer overflow on last_message copy.
Unformatted region (bad magic) rejected; reading from formatted region with 0 messages returns 1.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.