Commit | Line | Data |
---|---|---|
a6352fd4 MD |
1 | #ifndef _LIBRINGBUFFER_SHM_H |
2 | #define _LIBRINGBUFFER_SHM_H | |
3 | ||
4 | /* | |
5 | * libringbuffer/shm.h | |
6 | * | |
7 | * Copyright 2011 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
8 | * | |
9 | * Dual LGPL v2.1/GPL v2 license. | |
10 | */ | |
11 | ||
12 | #include <stdint.h> | |
13 | #include "ust/core.h" | |
431d5cf0 | 14 | #include "usterr_signal_safe.h" |
a6352fd4 MD |
15 | |
16 | #define SHM_MAGIC 0x54335433 | |
17 | #define SHM_MAJOR 0 | |
18 | #define SHM_MINOR 1 | |
19 | ||
20 | /* | |
21 | * Defining a max shm offset, for debugging purposes. | |
22 | */ | |
23 | #if (CAA_BITS_PER_LONG == 32) | |
24 | /* Define the maximum shared memory size to 128MB on 32-bit machines */ | |
25 | #define MAX_SHM_SIZE 134217728 | |
26 | #else | |
27 | /* Define the maximum shared memory size to 8GB on 64-bit machines */ | |
28 | #define MAX_SHM_SIZE 8589934592 | |
29 | #endif | |
30 | ||
31 | #define DECLARE_SHMP(type, name) type *****name | |
32 | ||
33 | struct shm_header { | |
34 | uint32_t magic; | |
35 | uint8_t major; | |
36 | uint8_t minor; | |
37 | uint8_t bits_per_long; | |
38 | size_t shm_size, shm_allocated; | |
39 | ||
40 | DECLARE_SHMP(struct channel, chan); | |
41 | }; | |
42 | ||
431d5cf0 MD |
43 | struct shm_handle { |
44 | struct shm_header *header; /* beginning of mapping */ | |
45 | int shmfd; /* process-local file descriptor */ | |
46 | }; | |
47 | ||
a6352fd4 MD |
48 | #define shmp(shm_offset) \ |
49 | ((__typeof__(****(shm_offset))) (((char *) &(shm_offset)) + (ptrdiff_t) (shm_offset))) | |
50 | ||
51 | #define _shmp_abs(a) ((a < 0) ? -(a) : (a)) | |
52 | ||
53 | static inline | |
54 | void _set_shmp(ptrdiff_t *shm_offset, void *ptr) | |
55 | { | |
56 | *shm_offset = (((char *) ptr) - ((char *) shm_offset)); | |
57 | assert(_shmp_abs(*shm_offset) < MAX_SHM_SIZE); | |
58 | } | |
59 | ||
60 | #define set_shmp(shm_offset, ptr) \ | |
61 | _set_shmp((ptrdiff_t *) ****(shm_offset), ptr) | |
62 | ||
63 | /* Shared memory is already zeroed by shmget */ | |
64 | /* *NOT* multithread-safe (should be protected by mutex) */ | |
65 | static inline | |
66 | void *zalloc_shm(struct shm_header *shm_header, size_t len) | |
67 | { | |
68 | void *ret; | |
69 | ||
70 | if (shm_header->shm_size - shm_header->shm_allocated < len) | |
71 | return NULL; | |
72 | ret = (char *) shm_header + shm_header->shm_allocated; | |
73 | shm_header->shm_allocated += len; | |
74 | return ret; | |
75 | } | |
76 | ||
431d5cf0 MD |
77 | static inline |
78 | void align_shm(struct shm_header *shm_header, size_t align) | |
79 | { | |
80 | size_t offset_len = offset_align(shm_header->shm_allocated, align); | |
81 | shm_header->shm_allocated += offset_len; | |
82 | } | |
83 | ||
a6352fd4 | 84 | #endif /* _LIBRINGBUFFER_SHM_H */ |