]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/ringbuf.h
start: don't overwrite file descriptors during namespace preservation
[mirror_lxc.git] / src / lxc / ringbuf.h
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #ifndef __LXC_RINGBUF_H
4 #define __LXC_RINGBUF_H
5
6 #include "config.h"
7
8 #include <inttypes.h>
9 #include <stdbool.h>
10 #include <stdio.h>
11 #include <sys/mman.h>
12
13 #include "compiler.h"
14
15 /**
16 * lxc_ringbuf - Implements a simple and efficient memory mapped ringbuffer.
17 * - The "addr" field of struct lxc_ringbuf is considered immutable. Instead the
18 * read and write offsets r_off and w_off are used to calculate the current
19 * read and write addresses. There should never be a need to use any of those
20 * fields directly. Instead use the appropriate helpers below.
21 * - Callers are expected to synchronize read and write accesses to the
22 * ringbuffer.
23 */
24 struct lxc_ringbuf {
25 char *addr; /* start address of the ringbuffer */
26 uint64_t size; /* total size of the ringbuffer in bytes */
27 uint64_t r_off; /* read offset */
28 uint64_t w_off; /* write offset */
29 };
30
31 /**
32 * lxc_ringbuf_create - Initialize a new ringbuffer.
33 *
34 * @param[in] size Size of the new ringbuffer as a power of 2.
35 */
36 __hidden extern int lxc_ringbuf_create(struct lxc_ringbuf *buf, size_t size);
37 __hidden extern void lxc_ringbuf_move_read_addr(struct lxc_ringbuf *buf, size_t len);
38 __hidden extern int lxc_ringbuf_write(struct lxc_ringbuf *buf, const char *msg, size_t len);
39 __hidden extern int lxc_ringbuf_read(struct lxc_ringbuf *buf, char *out, size_t *len);
40
41 static inline void lxc_ringbuf_release(struct lxc_ringbuf *buf)
42 {
43 if (buf->addr)
44 munmap(buf->addr, buf->size * 2);
45 }
46
47 static inline void lxc_ringbuf_clear(struct lxc_ringbuf *buf)
48 {
49 buf->r_off = 0;
50 buf->w_off = 0;
51 }
52
53 static inline uint64_t lxc_ringbuf_used(struct lxc_ringbuf *buf)
54 {
55 return buf->w_off - buf->r_off;
56 }
57
58 static inline uint64_t lxc_ringbuf_free(struct lxc_ringbuf *buf)
59 {
60 return buf->size - lxc_ringbuf_used(buf);
61 }
62
63 static inline char *lxc_ringbuf_get_read_addr(struct lxc_ringbuf *buf)
64 {
65 return buf->addr + buf->r_off;
66 }
67
68 static inline char *lxc_ringbuf_get_write_addr(struct lxc_ringbuf *buf)
69 {
70 return buf->addr + buf->w_off;
71 }
72
73 static inline void lxc_ringbuf_move_write_addr(struct lxc_ringbuf *buf, size_t len)
74 {
75 buf->w_off += len;
76 }
77
78 #endif /* __LXC_RINGBUF_H */