Add ustctl_snapshot_sample_positions ustctl command notification-items-3-4
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 21 Mar 2017 20:45:19 +0000 (16:45 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 23 Mar 2017 05:29:11 +0000 (01:29 -0400)
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
include/lttng/ust-ctl.h
liblttng-ust-ctl/ustctl.c
libringbuffer/frontend.h
libringbuffer/ring_buffer_frontend.c

index 7b750fd4438812f530357e3355d86a672215af5c..f6c1dc4527c4d64a4318a54375d3e5ee70c94e99 100644 (file)
@@ -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,
index 2af791473f6bbdf5ee816064a49514d2db61756b..a7d81ed53603f8a45a558ad88ea39db2499a65ea 100644 (file)
@@ -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)
index 160fd45532f39573b09178f6924bba71b1f65264..a2f74596eb9c06f319236309d2f36cdae2eaca99 100644 (file)
@@ -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);
index 6dd81e14b0bbb6e767b44687d725c210b43661fc..b30325a88fa192d9c7b1cc414879be560e146675 100644 (file)
@@ -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
This page took 0.02942 seconds and 5 git commands to generate.