liblttng-ust-ctl: Implement SIGBUS handling
[lttng-ust.git] / src / common / ringbuffer / frontend.h
1 /*
2 * SPDX-License-Identifier: LGPL-2.1-only
3 *
4 * Copyright (C) 2005-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * Ring Buffer Library Synchronization Header (API).
7 *
8 * See ring_buffer_frontend.c for more information on wait-free algorithms.
9 */
10
11 #ifndef _LTTNG_RING_BUFFER_FRONTEND_H
12 #define _LTTNG_RING_BUFFER_FRONTEND_H
13
14 #include <stddef.h>
15 #include <stdint.h>
16
17 #include <urcu/compiler.h>
18 #include <urcu/uatomic.h>
19
20 #include "common/smp.h"
21
22 /* Internal helpers */
23 #include "frontend_internal.h"
24
25 /* Buffer creation/removal and setup operations */
26
27 /*
28 * switch_timer_interval is the time interval (in us) to fill sub-buffers with
29 * padding to let readers get those sub-buffers. Used for live streaming.
30 *
31 * read_timer_interval is the time interval (in us) to wake up pending readers.
32 *
33 * buf_addr is a pointer the the beginning of the preallocated buffer contiguous
34 * address mapping. It is used only by RING_BUFFER_STATIC configuration. It can
35 * be set to NULL for other backends.
36 *
37 * private data is a memory area for configuration data. This memory is
38 * managed by lib ring buffer. priv_data_align is the alignment required
39 * for the private data area.
40 */
41
42 extern
43 struct lttng_ust_shm_handle *channel_create(const struct lttng_ust_ring_buffer_config *config,
44 const char *name,
45 size_t priv_data_align,
46 size_t priv_data_size,
47 void *priv_data_init,
48 void *priv,
49 void *buf_addr,
50 size_t subbuf_size, size_t num_subbuf,
51 unsigned int switch_timer_interval,
52 unsigned int read_timer_interval,
53 const int *stream_fds, int nr_stream_fds,
54 int64_t blocking_timeout)
55 __attribute__((visibility("hidden")));
56
57 /*
58 * channel_destroy finalizes all channel's buffers, waits for readers to
59 * release all references, and destroys the channel.
60 */
61 void channel_destroy(struct lttng_ust_ring_buffer_channel *chan,
62 struct lttng_ust_shm_handle *handle,
63 int consumer)
64 __attribute__((visibility("hidden")));
65
66
67 /* Buffer read operations */
68
69 /*
70 * Iteration on channel cpumask needs to issue a read barrier to match the write
71 * barrier in cpu hotplug. It orders the cpumask read before read of per-cpu
72 * buffer data. The per-cpu buffer is never removed by cpu hotplug; teardown is
73 * only performed at channel destruction.
74 */
75 #define for_each_channel_cpu(cpu, chan) \
76 for_each_possible_cpu(cpu)
77
78 extern struct lttng_ust_ring_buffer *channel_get_ring_buffer(
79 const struct lttng_ust_ring_buffer_config *config,
80 struct lttng_ust_ring_buffer_channel *chan, int cpu,
81 struct lttng_ust_shm_handle *handle,
82 int *shm_fd, int *wait_fd,
83 int *wakeup_fd,
84 uint64_t *memory_map_size,
85 void **memory_map_addr)
86 __attribute__((visibility("hidden")));
87
88 extern
89 int ring_buffer_channel_close_wait_fd(const struct lttng_ust_ring_buffer_config *config,
90 struct lttng_ust_ring_buffer_channel *chan,
91 struct lttng_ust_shm_handle *handle)
92 __attribute__((visibility("hidden")));
93
94 extern
95 int ring_buffer_channel_close_wakeup_fd(const struct lttng_ust_ring_buffer_config *config,
96 struct lttng_ust_ring_buffer_channel *chan,
97 struct lttng_ust_shm_handle *handle)
98 __attribute__((visibility("hidden")));
99
100 extern
101 int ring_buffer_stream_close_wait_fd(const struct lttng_ust_ring_buffer_config *config,
102 struct lttng_ust_ring_buffer_channel *chan,
103 struct lttng_ust_shm_handle *handle,
104 int cpu)
105 __attribute__((visibility("hidden")));
106
107 extern
108 int ring_buffer_stream_close_wakeup_fd(const struct lttng_ust_ring_buffer_config *config,
109 struct lttng_ust_ring_buffer_channel *chan,
110 struct lttng_ust_shm_handle *handle,
111 int cpu)
112 __attribute__((visibility("hidden")));
113
114 extern int lib_ring_buffer_open_read(struct lttng_ust_ring_buffer *buf,
115 struct lttng_ust_shm_handle *handle)
116 __attribute__((visibility("hidden")));
117
118 extern void lib_ring_buffer_release_read(struct lttng_ust_ring_buffer *buf,
119 struct lttng_ust_shm_handle *handle)
120 __attribute__((visibility("hidden")));
121
122 /*
123 * Initialize signals for ring buffer. Should be called early e.g. by
124 * main() in the program to affect all threads.
125 */
126 void lib_ringbuffer_signal_init(void)
127 __attribute__((visibility("hidden")));
128
129 /*
130 * Read sequence: snapshot, many get_subbuf/put_subbuf, move_consumer.
131 */
132 extern int lib_ring_buffer_snapshot(struct lttng_ust_ring_buffer *buf,
133 unsigned long *consumed,
134 unsigned long *produced,
135 struct lttng_ust_shm_handle *handle)
136 __attribute__((visibility("hidden")));
137
138 extern int lib_ring_buffer_snapshot_sample_positions(
139 struct lttng_ust_ring_buffer *buf,
140 unsigned long *consumed,
141 unsigned long *produced,
142 struct lttng_ust_shm_handle *handle)
143 __attribute__((visibility("hidden")));
144
145 extern void lib_ring_buffer_move_consumer(struct lttng_ust_ring_buffer *buf,
146 unsigned long consumed_new,
147 struct lttng_ust_shm_handle *handle)
148 __attribute__((visibility("hidden")));
149
150 extern int lib_ring_buffer_get_subbuf(struct lttng_ust_ring_buffer *buf,
151 unsigned long consumed,
152 struct lttng_ust_shm_handle *handle)
153 __attribute__((visibility("hidden")));
154
155 extern void lib_ring_buffer_put_subbuf(struct lttng_ust_ring_buffer *buf,
156 struct lttng_ust_shm_handle *handle)
157 __attribute__((visibility("hidden")));
158
159 /*
160 * lib_ring_buffer_get_next_subbuf/lib_ring_buffer_put_next_subbuf are helpers
161 * to read sub-buffers sequentially.
162 */
163 static inline int lib_ring_buffer_get_next_subbuf(struct lttng_ust_ring_buffer *buf,
164 struct lttng_ust_shm_handle *handle)
165 {
166 int ret;
167
168 ret = lib_ring_buffer_snapshot(buf, &buf->cons_snapshot,
169 &buf->prod_snapshot, handle);
170 if (ret)
171 return ret;
172 ret = lib_ring_buffer_get_subbuf(buf, buf->cons_snapshot, handle);
173 return ret;
174 }
175
176 static inline
177 void lib_ring_buffer_put_next_subbuf(struct lttng_ust_ring_buffer *buf,
178 struct lttng_ust_shm_handle *handle)
179 {
180 struct lttng_ust_ring_buffer_channel *chan;
181
182 chan = shmp(handle, buf->backend.chan);
183 if (!chan)
184 return;
185 lib_ring_buffer_put_subbuf(buf, handle);
186 lib_ring_buffer_move_consumer(buf, subbuf_align(buf->cons_snapshot, chan),
187 handle);
188 }
189
190 extern void channel_reset(struct lttng_ust_ring_buffer_channel *chan)
191 __attribute__((visibility("hidden")));
192
193 extern void lib_ring_buffer_reset(struct lttng_ust_ring_buffer *buf,
194 struct lttng_ust_shm_handle *handle)
195 __attribute__((visibility("hidden")));
196
197 static inline
198 unsigned long lib_ring_buffer_get_offset(const struct lttng_ust_ring_buffer_config *config,
199 struct lttng_ust_ring_buffer *buf)
200 {
201 return v_read(config, &buf->offset);
202 }
203
204 static inline
205 unsigned long lib_ring_buffer_get_consumed(
206 const struct lttng_ust_ring_buffer_config *config __attribute__((unused)),
207 struct lttng_ust_ring_buffer *buf)
208 {
209 return uatomic_read(&buf->consumed);
210 }
211
212 /*
213 * Must call lib_ring_buffer_is_finalized before reading counters (memory
214 * ordering enforced with respect to trace teardown).
215 */
216 static inline
217 int lib_ring_buffer_is_finalized(
218 const struct lttng_ust_ring_buffer_config *config __attribute__((unused)),
219 struct lttng_ust_ring_buffer *buf)
220 {
221 int finalized = CMM_ACCESS_ONCE(buf->finalized);
222 /*
223 * Read finalized before counters.
224 */
225 cmm_smp_rmb();
226 return finalized;
227 }
228
229 static inline
230 int lib_ring_buffer_channel_is_finalized(const struct lttng_ust_ring_buffer_channel *chan)
231 {
232 return chan->finalized;
233 }
234
235 static inline
236 int lib_ring_buffer_channel_is_disabled(const struct lttng_ust_ring_buffer_channel *chan)
237 {
238 return uatomic_read(&chan->record_disabled);
239 }
240
241 static inline
242 unsigned long lib_ring_buffer_get_read_data_size(
243 const struct lttng_ust_ring_buffer_config *config,
244 struct lttng_ust_ring_buffer *buf,
245 struct lttng_ust_shm_handle *handle)
246 {
247 return subbuffer_get_read_data_size(config, &buf->backend, handle);
248 }
249
250 static inline
251 unsigned long lib_ring_buffer_get_records_count(
252 const struct lttng_ust_ring_buffer_config *config,
253 struct lttng_ust_ring_buffer *buf)
254 {
255 return v_read(config, &buf->records_count);
256 }
257
258 static inline
259 unsigned long lib_ring_buffer_get_records_overrun(
260 const struct lttng_ust_ring_buffer_config *config,
261 struct lttng_ust_ring_buffer *buf)
262 {
263 return v_read(config, &buf->records_overrun);
264 }
265
266 static inline
267 unsigned long lib_ring_buffer_get_records_lost_full(
268 const struct lttng_ust_ring_buffer_config *config,
269 struct lttng_ust_ring_buffer *buf)
270 {
271 return v_read(config, &buf->records_lost_full);
272 }
273
274 static inline
275 unsigned long lib_ring_buffer_get_records_lost_wrap(
276 const struct lttng_ust_ring_buffer_config *config,
277 struct lttng_ust_ring_buffer *buf)
278 {
279 return v_read(config, &buf->records_lost_wrap);
280 }
281
282 static inline
283 unsigned long lib_ring_buffer_get_records_lost_big(
284 const struct lttng_ust_ring_buffer_config *config,
285 struct lttng_ust_ring_buffer *buf)
286 {
287 return v_read(config, &buf->records_lost_big);
288 }
289
290 static inline
291 unsigned long lib_ring_buffer_get_records_read(
292 const struct lttng_ust_ring_buffer_config *config,
293 struct lttng_ust_ring_buffer *buf)
294 {
295 return v_read(config, &buf->backend.records_read);
296 }
297
298 #endif /* _LTTNG_RING_BUFFER_FRONTEND_H */
This page took 0.03548 seconds and 4 git commands to generate.