From d9772eef03595ed41fa66d766b9c8dd3664ba12e Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Tue, 21 Mar 2017 16:45:19 -0400 Subject: [PATCH] Add ustctl_snapshot_sample_positions ustctl command MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérémie Galarneau --- include/lttng/ust-ctl.h | 1 + liblttng-ust-ctl/ustctl.c | 15 +++++++++++ libringbuffer/frontend.h | 5 ++++ libringbuffer/ring_buffer_frontend.c | 39 ++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+) diff --git a/include/lttng/ust-ctl.h b/include/lttng/ust-ctl.h index 7b750fd4..f6c1dc45 100644 --- a/include/lttng/ust-ctl.h +++ b/include/lttng/ust-ctl.h @@ -226,6 +226,7 @@ int ustctl_put_next_subbuf(struct ustctl_consumer_stream *stream); /* snapshot */ int ustctl_snapshot(struct ustctl_consumer_stream *stream); +int ustctl_snapshot_sample_positions(struct ustctl_consumer_stream *stream); int ustctl_snapshot_get_consumed(struct ustctl_consumer_stream *stream, unsigned long *pos); int ustctl_snapshot_get_produced(struct ustctl_consumer_stream *stream, diff --git a/liblttng-ust-ctl/ustctl.c b/liblttng-ust-ctl/ustctl.c index 2af79147..a7d81ed5 100644 --- a/liblttng-ust-ctl/ustctl.c +++ b/liblttng-ust-ctl/ustctl.c @@ -1500,6 +1500,21 @@ int ustctl_snapshot(struct ustctl_consumer_stream *stream) &buf->prod_snapshot, consumer_chan->chan->handle); } +/* Get a snapshot of the current ring buffer producer and consumer positions */ +int ustctl_snapshot_sample_positions(struct ustctl_consumer_stream *stream) +{ + struct lttng_ust_lib_ring_buffer *buf; + struct ustctl_consumer_channel *consumer_chan; + + if (!stream) + return -EINVAL; + buf = stream->buf; + consumer_chan = stream->chan; + return lib_ring_buffer_snapshot_sample_positions(buf, + &buf->cons_snapshot, &buf->prod_snapshot, + consumer_chan->chan->handle); +} + /* Get the consumer position (iteration start) */ int ustctl_snapshot_get_consumed(struct ustctl_consumer_stream *stream, unsigned long *pos) diff --git a/libringbuffer/frontend.h b/libringbuffer/frontend.h index 160fd455..a2f74596 100644 --- a/libringbuffer/frontend.h +++ b/libringbuffer/frontend.h @@ -131,6 +131,11 @@ extern int lib_ring_buffer_snapshot(struct lttng_ust_lib_ring_buffer *buf, unsigned long *consumed, unsigned long *produced, struct lttng_ust_shm_handle *handle); +extern int lib_ring_buffer_snapshot_sample_positions( + struct lttng_ust_lib_ring_buffer *buf, + unsigned long *consumed, + unsigned long *produced, + struct lttng_ust_shm_handle *handle); extern void lib_ring_buffer_move_consumer(struct lttng_ust_lib_ring_buffer *buf, unsigned long consumed_new, struct lttng_ust_shm_handle *handle); diff --git a/libringbuffer/ring_buffer_frontend.c b/libringbuffer/ring_buffer_frontend.c index 6dd81e14..b30325a8 100644 --- a/libringbuffer/ring_buffer_frontend.c +++ b/libringbuffer/ring_buffer_frontend.c @@ -1305,6 +1305,45 @@ nodata: return -EAGAIN; } +/** + * Performs the same function as lib_ring_buffer_snapshot(), but the positions + * are saved regardless of whether the consumed and produced positions are + * actually in the same subbuffer. + * + * This function is meant to provide information on the exact producer and + * consumer positions without regard for the actual "snapshot" feature. + */ +int lib_ring_buffer_snapshot_sample_positions( + struct lttng_ust_lib_ring_buffer *buf, + unsigned long *consumed, unsigned long *produced, + struct lttng_ust_shm_handle *handle) +{ + struct channel *chan; + const struct lttng_ust_lib_ring_buffer_config *config; + unsigned long consumed_cur, write_offset; + + chan = shmp(handle, buf->backend.chan); + if (!chan) + return -EPERM; + config = &chan->backend.config; + cmm_smp_rmb(); + consumed_cur = uatomic_read(&buf->consumed); + /* + * No need to issue a memory barrier between consumed count read and + * write offset read, because consumed count can only change + * concurrently in overwrite mode, and we keep a sequence counter + * identifier derived from the write offset to check we are getting + * the same sub-buffer we are expecting (the sub-buffers are atomically + * "tagged" upon writes, tags are checked upon read). + */ + write_offset = v_read(config, &buf->offset); + + *consumed = consumed_cur; + *produced = write_offset; + + return 0; +} + /** * lib_ring_buffer_move_consumer - move consumed counter forward * @buf: ring buffer -- 2.34.1