]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/ringbuf.h
spelling: timeout
[mirror_lxc.git] / src / lxc / ringbuf.h
1 /* liblxcapi
2 *
3 * Copyright © 2017 Christian Brauner <christian.brauner@ubuntu.com>.
4 * Copyright © 2017 Canonical Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef __LXC_RINGBUF_H
21 #define __LXC_RINGBUF_H
22
23 #include <inttypes.h>
24 #include <stdbool.h>
25 #include <stdio.h>
26 #include <sys/mman.h>
27
28 /**
29 * lxc_ringbuf - Implements a simple and efficient memory mapped ringbuffer.
30 * - The "addr" field of struct lxc_ringbuf is considered immutable. Instead the
31 * read and write offsets r_off and w_off are used to calculate the current
32 * read and write addresses. There should never be a need to use any of those
33 * fields directly. Instead use the appropriate helpers below.
34 * - Callers are expected to synchronize read and write accesses to the
35 * ringbuffer.
36 */
37 struct lxc_ringbuf {
38 char *addr; /* start address of the ringbuffer */
39 uint64_t size; /* total size of the ringbuffer in bytes */
40 uint64_t r_off; /* read offset */
41 uint64_t w_off; /* write offset */
42 };
43
44 /**
45 * lxc_ringbuf_create - Initialize a new ringbuffer.
46 *
47 * @param[in] size Size of the new ringbuffer as a power of 2.
48 */
49 extern int lxc_ringbuf_create(struct lxc_ringbuf *buf, size_t size);
50 extern void lxc_ringbuf_move_read_addr(struct lxc_ringbuf *buf, size_t len);
51 extern int lxc_ringbuf_write(struct lxc_ringbuf *buf, const char *msg, size_t len);
52 extern int lxc_ringbuf_read(struct lxc_ringbuf *buf, char *out, size_t *len);
53
54 static inline void lxc_ringbuf_release(struct lxc_ringbuf *buf)
55 {
56 munmap(buf->addr, buf->size * 2);
57 }
58
59 static inline void lxc_ringbuf_clear(struct lxc_ringbuf *buf)
60 {
61 buf->r_off = 0;
62 buf->w_off = 0;
63 }
64
65 static inline uint64_t lxc_ringbuf_used(struct lxc_ringbuf *buf)
66 {
67 return buf->w_off - buf->r_off;
68 }
69
70 static inline uint64_t lxc_ringbuf_free(struct lxc_ringbuf *buf)
71 {
72 return buf->size - lxc_ringbuf_used(buf);
73 }
74
75 static inline char *lxc_ringbuf_get_read_addr(struct lxc_ringbuf *buf)
76 {
77 return buf->addr + buf->r_off;
78 }
79
80 static inline char *lxc_ringbuf_get_write_addr(struct lxc_ringbuf *buf)
81 {
82 return buf->addr + buf->w_off;
83 }
84
85 static inline void lxc_ringbuf_move_write_addr(struct lxc_ringbuf *buf, size_t len)
86 {
87 buf->w_off += len;
88 }
89
90 #endif /* __LXC_RINGBUF_H */