[lttng-dev] [RFC PATCH lttng-ust] Add ustctl_snapshot_sample_positions ustctl command

Jérémie Galarneau jeremie.galarneau at efficios.com
Thu May 4 21:26:17 UTC 2017


The major version is bumped as a new API entry point is
introduced.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau at efficios.com>
---
 include/lttng/ust-abi.h              |  2 +-
 include/lttng/ust-ctl.h              |  1 +
 liblttng-ust-ctl/ustctl.c            | 19 ++++++++++++++++++
 libringbuffer/frontend.h             |  5 +++++
 libringbuffer/ring_buffer_frontend.c | 38 ++++++++++++++++++++++++++++++++++++
 5 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/include/lttng/ust-abi.h b/include/lttng/ust-abi.h
index 6e8f8d7b..35b8da00 100644
--- a/include/lttng/ust-abi.h
+++ b/include/lttng/ust-abi.h
@@ -42,7 +42,7 @@
 #define LTTNG_UST_COMM_MAGIC			0xC57C57C5
 
 /* Version for ABI between liblttng-ust, sessiond, consumerd */
-#define LTTNG_UST_ABI_MAJOR_VERSION		7
+#define LTTNG_UST_ABI_MAJOR_VERSION		8
 #define LTTNG_UST_ABI_MINOR_VERSION		1
 
 enum lttng_ust_instrumentation {
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..a317de96 100644
--- a/liblttng-ust-ctl/ustctl.c
+++ b/liblttng-ust-ctl/ustctl.c
@@ -1500,6 +1500,25 @@ 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
+ * even if the consumed and produced positions are contained withinin the same
+ * subbuffer.
+ */
+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..4627ff2a 100644
--- a/libringbuffer/ring_buffer_frontend.c
+++ b/libringbuffer/ring_buffer_frontend.c
@@ -1306,6 +1306,44 @@ nodata:
 }
 
 /**
+ * Performs the same function as lib_ring_buffer_snapshot(), but the positions
+ * are saved regardless of whether the consumed and produced positions are
+ * in the same subbuffer.
+ * @buf: ring buffer
+ * @consumed: consumed count indicating the position where to read
+ * @produced: produced count, indicates position when to stop reading
+ *
+ * This function is meant to provide information on the exact producer and
+ * consumer positions without regard for the "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 = 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).
+	 */
+	*produced = v_read(config, &buf->offset);
+	return 0;
+}
+
+/**
  * lib_ring_buffer_move_consumer - move consumed counter forward
  * @buf: ring buffer
  * @consumed_new: new consumed count value
-- 
2.12.2



More information about the lttng-dev mailing list