Documentation: ring buffer: SWITCH_FLUSH can be used when active
[lttng-ust.git] / libringbuffer / ring_buffer_frontend.c
index 3cba68d4e7ef354b9d9ddd842378459fa975a4d1..43496254ce443baaace6dd910bd89938edc30398 100644 (file)
@@ -164,10 +164,14 @@ static struct timer_signal_data timer_signal = {
 void lib_ring_buffer_reset(struct lttng_ust_lib_ring_buffer *buf,
                           struct lttng_ust_shm_handle *handle)
 {
-       struct channel *chan = shmp(handle, buf->backend.chan);
-       const struct lttng_ust_lib_ring_buffer_config *config = &chan->backend.config;
+       struct channel *chan;
+       const struct lttng_ust_lib_ring_buffer_config *config;
        unsigned int i;
 
+       chan = shmp(handle, buf->backend.chan);
+       if (!chan)
+               abort();
+       config = &chan->backend.config;
        /*
         * Reset iterator first. It will put the subbuffer if it currently holds
         * it.
@@ -400,6 +404,9 @@ void lib_ring_buffer_channel_switch_timer(int sig, siginfo_t *si, void *uc)
                for_each_possible_cpu(cpu) {
                        struct lttng_ust_lib_ring_buffer *buf =
                                shmp(handle, chan->backend.buf[cpu].shmp);
+
+                       if (!buf)
+                               abort();
                        if (uatomic_read(&buf->active_readers))
                                lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE,
                                        chan->handle);
@@ -408,6 +415,8 @@ void lib_ring_buffer_channel_switch_timer(int sig, siginfo_t *si, void *uc)
                struct lttng_ust_lib_ring_buffer *buf =
                        shmp(handle, chan->backend.buf[0].shmp);
 
+               if (!buf)
+                       abort();
                if (uatomic_read(&buf->active_readers))
                        lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE,
                                chan->handle);
@@ -435,6 +444,8 @@ void lib_ring_buffer_channel_do_read(struct channel *chan)
                        struct lttng_ust_lib_ring_buffer *buf =
                                shmp(handle, chan->backend.buf[cpu].shmp);
 
+                       if (!buf)
+                               abort();
                        if (uatomic_read(&buf->active_readers)
                            && lib_ring_buffer_poll_deliver(config, buf,
                                        chan, handle)) {
@@ -445,6 +456,8 @@ void lib_ring_buffer_channel_do_read(struct channel *chan)
                struct lttng_ust_lib_ring_buffer *buf =
                        shmp(handle, chan->backend.buf[0].shmp);
 
+               if (!buf)
+                       abort();
                if (uatomic_read(&buf->active_readers)
                    && lib_ring_buffer_poll_deliver(config, buf,
                                chan, handle)) {
@@ -629,7 +642,7 @@ void lib_ring_buffer_channel_switch_timer_start(struct channel *chan)
        }
 
        its.it_value.tv_sec = chan->switch_timer_interval / 1000000;
-       its.it_value.tv_nsec = chan->switch_timer_interval % 1000000;
+       its.it_value.tv_nsec = (chan->switch_timer_interval % 1000000) * 1000;
        its.it_interval.tv_sec = its.it_value.tv_sec;
        its.it_interval.tv_nsec = its.it_value.tv_nsec;
 
@@ -683,7 +696,7 @@ void lib_ring_buffer_channel_read_timer_start(struct channel *chan)
        }
 
        its.it_value.tv_sec = chan->read_timer_interval / 1000000;
-       its.it_value.tv_nsec = chan->read_timer_interval % 1000000;
+       its.it_value.tv_nsec = (chan->read_timer_interval % 1000000) * 1000;
        its.it_interval.tv_sec = its.it_value.tv_sec;
        its.it_interval.tv_nsec = its.it_value.tv_nsec;
 
@@ -773,7 +786,8 @@ static void channel_free(struct channel *chan,
  *                         padding to let readers get those sub-buffers.
  *                         Used for live streaming.
  * @read_timer_interval: Time interval (in us) to wake up pending readers.
- * @shm_path: Shared memory files path.
+ * @stream_fds: array of stream file descriptors.
+ * @nr_stream_fds: number of file descriptors in array.
  *
  * Holds cpu hotplug.
  * Returns NULL on failure.
@@ -787,7 +801,7 @@ struct lttng_ust_shm_handle *channel_create(const struct lttng_ust_lib_ring_buff
                   void *buf_addr, size_t subbuf_size,
                   size_t num_subbuf, unsigned int switch_timer_interval,
                   unsigned int read_timer_interval,
-                  const char *shm_path)
+                  const int *stream_fds, int nr_stream_fds)
 {
        int ret;
        size_t shmsize, chansize;
@@ -801,6 +815,9 @@ struct lttng_ust_shm_handle *channel_create(const struct lttng_ust_lib_ring_buff
        else
                nr_streams = 1;
 
+       if (nr_stream_fds != nr_streams)
+               return NULL;
+
        if (lib_ring_buffer_check_config(config, switch_timer_interval,
                                         read_timer_interval))
                return NULL;
@@ -825,7 +842,7 @@ struct lttng_ust_shm_handle *channel_create(const struct lttng_ust_lib_ring_buff
 
        /* Allocate normal memory for channel (not shared) */
        shmobj = shm_object_table_alloc(handle->table, shmsize, SHM_OBJECT_MEM,
-                       NULL);
+                       -1);
        if (!shmobj)
                goto error_append;
        /* struct channel is at object 0, offset 0 (hardcoded) */
@@ -856,7 +873,7 @@ struct lttng_ust_shm_handle *channel_create(const struct lttng_ust_lib_ring_buff
 
        ret = channel_backend_init(&chan->backend, name, config,
                                   subbuf_size, num_subbuf, handle,
-                                  shm_path);
+                                  stream_fds);
        if (ret)
                goto error_backend_init;
 
@@ -1475,7 +1492,8 @@ void lib_ring_buffer_print_errors(struct channel *chan,
 /*
  * lib_ring_buffer_switch_old_start: Populate old subbuffer header.
  *
- * Only executed when the buffer is finalized, in SWITCH_FLUSH.
+ * Only executed by SWITCH_FLUSH, which can be issued while tracing is
+ * active or at buffer finalization (destroy).
  */
 static
 void lib_ring_buffer_switch_old_start(struct lttng_ust_lib_ring_buffer *buf,
@@ -1649,12 +1667,14 @@ int lib_ring_buffer_try_switch_slow(enum switch_mode mode,
                unsigned long sb_index, commit_count;
 
                /*
-                * We are performing a SWITCH_FLUSH. At this stage, there are no
-                * concurrent writes into the buffer.
+                * We are performing a SWITCH_FLUSH. There may be concurrent
+                * writes into the buffer if e.g. invoked while performing a
+                * snapshot on an active trace.
                 *
-                * The client does not save any header information.  Don't
-                * switch empty subbuffer on finalize, because it is invalid to
-                * deliver a completely empty subbuffer.
+                * If the client does not save any header information
+                * (sub-buffer header size == 0), don't switch empty subbuffer
+                * on finalize, because it is invalid to deliver a completely
+                * empty subbuffer.
                 */
                if (!config->cb.subbuffer_header_size())
                        return -1;
This page took 0.024674 seconds and 4 git commands to generate.