Lely core libraries  2.2.5
spscring.h
Go to the documentation of this file.
1 
35 #ifndef LELY_UTIL_SPSCRING_H_
36 #define LELY_UTIL_SPSCRING_H_
37 
38 #include <lely/features.h>
39 
40 #ifdef __cplusplus
41 #include <atomic>
42 #else
43 #include <lely/libc/stdatomic.h>
44 #endif
45 
46 #include <stddef.h>
47 
48 #if defined(__cplusplus)
49 typedef ::std::atomic_size_t spscring_atomic_t;
50 #elif __STDC_NO_ATOMICS__
51 typedef size_t spscring_atomic_t;
52 #else // C11
53 typedef atomic_size_t spscring_atomic_t;
54 #endif
55 
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59 
61 struct spscring {
62  struct {
63  _Alignas(LEVEL1_DCACHE_LINESIZE) struct spscring_ctx {
64  size_t size;
65  size_t base;
66  size_t pos;
67  size_t end;
68  } ctx;
69  char _pad1[LEVEL1_DCACHE_LINESIZE
70  - sizeof(struct spscring_ctx)];
71  _Alignas(LEVEL1_DCACHE_LINESIZE) spscring_atomic_t pos;
72  char _pad2[LEVEL1_DCACHE_LINESIZE - sizeof(spscring_atomic_t)];
73  _Alignas(LEVEL1_DCACHE_LINESIZE) struct spscring_sig {
74  spscring_atomic_t size;
75  void (*func)(struct spscring *ring, void *arg);
76  void *arg;
77  } sig;
78  char _pad3[LEVEL1_DCACHE_LINESIZE
79  - sizeof(struct spscring_sig)];
80  } p, c;
81 };
82 
84 #if !defined(__cplusplus) && __STDC_NO_ATOMICS__
85 #define SPSCRING_INIT(size) \
86  { \
87  { { (size), 0, 0, 0 }, { 0 }, 0, { 0 }, { 0, NULL, NULL }, \
88  { 0 } }, \
89  { \
90  { (size), 0, 0, 0 }, { 0 }, 0, { 0 }, \
91  { 0, NULL, NULL }, { 0 }, \
92  } \
93  }
94 #else
95 #define SPSCRING_INIT(size) \
96  { \
97  { \
98  { (size), 0, 0, 0 }, \
99  { 0 }, \
100  ATOMIC_VAR_INIT(0), \
101  { 0 }, \
102  { ATOMIC_VAR_INIT(0), NULL, NULL }, \
103  { 0 }, \
104  }, \
105  { \
106  { (size), 0, 0, 0 }, { 0 }, ATOMIC_VAR_INIT(0), { 0 }, \
107  { ATOMIC_VAR_INIT(0), NULL, NULL }, \
108  { 0 }, \
109  } \
110  }
111 #endif
112 
117 void spscring_init(struct spscring *ring, size_t size);
118 
120 size_t spscring_size(const struct spscring *ring);
121 
133 size_t spscring_p_capacity(struct spscring *ring);
134 
146 size_t spscring_p_capacity_no_wrap(struct spscring *ring);
147 
165 size_t spscring_p_alloc(struct spscring *ring, size_t *psize);
166 
184 size_t spscring_p_alloc_no_wrap(struct spscring *ring, size_t *psize);
185 
201 size_t spscring_p_commit(struct spscring *ring, size_t size);
202 
225 int spscring_p_submit_wait(struct spscring *ring, size_t size,
226  void (*func)(struct spscring *ring, void *arg), void *arg);
227 
238 int spscring_p_abort_wait(struct spscring *ring);
239 
251 size_t spscring_c_capacity(struct spscring *ring);
252 
264 size_t spscring_c_capacity_no_wrap(struct spscring *ring);
265 
283 size_t spscring_c_alloc(struct spscring *ring, size_t *psize);
284 
302 size_t spscring_c_alloc_no_wrap(struct spscring *ring, size_t *psize);
303 
319 size_t spscring_c_commit(struct spscring *ring, size_t size);
320 
343 int spscring_c_submit_wait(struct spscring *ring, size_t size,
344  void (*func)(struct spscring *ring, void *arg), void *arg);
345 
356 int spscring_c_abort_wait(struct spscring *ring);
357 
358 #ifdef __cplusplus
359 }
360 #endif
361 
362 #endif // !LELY_UTIL_SPSCRING_H_
size_t spscring_p_capacity(struct spscring *ring)
Returns the total capacity available for a producer in a single-producer single-consumer ring buffer...
Definition: spscring.c:65
int spscring_c_abort_wait(struct spscring *ring)
Aborts a wait operation previously registered with spscring_c_submit_wait().
Definition: spscring.c:368
size_t spscring_p_commit(struct spscring *ring, size_t size)
Makes the specified number of indices available to a consumer and, if this satisfies a wait operation...
Definition: spscring.c:138
size_t spscring_c_capacity_no_wrap(struct spscring *ring)
Returns the total capacity available for a consumer in a single-producer single-consumer ring buffer...
Definition: spscring.c:247
int spscring_c_submit_wait(struct spscring *ring, size_t size, void(*func)(struct spscring *ring, void *arg), void *arg)
Checks if the requested range of indices, including wrapping, in a single-producer, single-consumer ring buffer is available for reading and, if not, registers a signal function to be invoked once the requested range becomes available.
Definition: spscring.c:327
size_t spscring_p_alloc_no_wrap(struct spscring *ring, size_t *psize)
Allocates a consecutive range of indices, without wrapping, in a single-producer, single-consumer rin...
Definition: spscring.c:118
size_t spscring_c_capacity(struct spscring *ring)
Returns the total capacity available for a consumer in a single-producer single-consumer ring buffer...
Definition: spscring.c:229
#define LEVEL1_DCACHE_LINESIZE
The presumed size (in bytes) of a line in the L1 data cache.
Definition: features.h:292
This header file is part of the C11 and POSIX compatibility library; it includes <stdatomic.h>, if it exists, and defines any missing functionality.
size_t spscring_p_alloc(struct spscring *ring, size_t *psize)
Allocates a consecutive range of indices, including wrapping, in a single-producer, single-consumer ring buffer for writing.
Definition: spscring.c:98
size_t spscring_c_alloc(struct spscring *ring, size_t *psize)
Allocates a consecutive range of indices, including wrapping, in a single-producer, single-consumer ring buffer for reading.
Definition: spscring.c:262
void spscring_init(struct spscring *ring, size_t size)
Initializes a single-producer, single-consumer ring buffer with the specified size.
Definition: spscring.c:47
size_t spscring_c_alloc_no_wrap(struct spscring *ring, size_t *psize)
Allocates a consecutive range of indices, without wrapping, in a single-producer, single-consumer rin...
Definition: spscring.c:282
This header file is part of the C11 and POSIX compatibility library; it includes <stddef.h> and defines any missing functionality.
int spscring_p_submit_wait(struct spscring *ring, size_t size, void(*func)(struct spscring *ring, void *arg), void *arg)
Checks if the requested range of indices, including wrapping, in a single-producer, single-consumer ring buffer is available for writing and, if not, registers a signal function to be invoked once the requested range becomes available.
Definition: spscring.c:163
size_t spscring_p_capacity_no_wrap(struct spscring *ring)
Returns the total capacity available for a producer in a single-producer single-consumer ring buffer...
Definition: spscring.c:83
A single-producer, single-consumer ring buffer.
Definition: spscring.h:61
int spscring_p_abort_wait(struct spscring *ring)
Aborts a wait operation previously registered with spscring_p_submit_wait().
Definition: spscring.c:204
This header file is part of the Lely libraries; it contains the compiler feature definitions.
size_t spscring_c_commit(struct spscring *ring, size_t size)
Makes the specified number of indices available to a producer and, if this satisfies a wait operation...
Definition: spscring.c:302
size_t spscring_size(const struct spscring *ring)
Returns the size of a single-producer, single-consumer ring buffer.
Definition: spscring.c:56