- * ltt_reserve_switch_old_subbuf: switch old subbuffer
- *
- * Concurrency safe because we are the last and only thread to alter this
- * sub-buffer. As long as it is not delivered and read, no other thread can
- * alter the offset, alter the reserve_count or call the
- * client_buffer_end_callback on this sub-buffer.
- *
- * The only remaining threads could be the ones with pending commits. They will
- * have to do the deliver themselves. Not concurrency safe in overwrite mode.
- * We detect corrupted subbuffers with commit and reserve counts. We keep a
- * corrupted sub-buffers count and push the readers across these sub-buffers.
- *
- * Not concurrency safe if a writer is stalled in a subbuffer and another writer
- * switches in, finding out it's corrupted. The result will be than the old
- * (uncommited) subbuffer will be declared corrupted, and that the new subbuffer
- * will be declared corrupted too because of the commit count adjustment.
- *
- * Note : offset_old should never be 0 here.
- */
-static inline void ltt_reserve_switch_old_subbuf(
- struct ust_channel *channel,
- struct ust_buffer *buf,
- struct ltt_reserve_switch_offsets *offsets, u64 *tsc)
-{
- long oldidx = SUBBUF_INDEX(offsets->old - 1, channel);
-
- channel->buffer_end(buf, *tsc, offsets->old, oldidx);
- /* Must write buffer end before incrementing commit count */
- smp_wmb();
- offsets->commit_count =
- local_add_return(channel->subbuf_size
- - (SUBBUF_OFFSET(offsets->old - 1, channel)
- + 1),
- &buf->commit_count[oldidx]);
- if ((BUFFER_TRUNC(offsets->old - 1, channel)
- >> channel->n_subbufs_order)
- - ((offsets->commit_count - channel->subbuf_size)
- & channel->commit_count_mask) == 0)
- ltt_deliver(buf, oldidx, offsets->commit_count);
-}
-
-/*
- * ltt_reserve_switch_new_subbuf: Populate new subbuffer.
- *
- * This code can be executed unordered : writers may already have written to the
- * sub-buffer before this code gets executed, caution. The commit makes sure
- * that this code is executed before the deliver of this sub-buffer.
- */
-static /*inline*/ void ltt_reserve_switch_new_subbuf(
- struct ust_channel *channel,
- struct ust_buffer *buf,
- struct ltt_reserve_switch_offsets *offsets, u64 *tsc)
-{
- long beginidx = SUBBUF_INDEX(offsets->begin, channel);
-
- channel->buffer_begin(buf, *tsc, beginidx);
- /* Must write buffer end before incrementing commit count */
- smp_wmb();
- offsets->commit_count = local_add_return(ltt_subbuffer_header_size(),
- &buf->commit_count[beginidx]);
- /* Check if the written buffer has to be delivered */
- if ((BUFFER_TRUNC(offsets->begin, channel)
- >> channel->n_subbufs_order)
- - ((offsets->commit_count - channel->subbuf_size)
- & channel->commit_count_mask) == 0)
- ltt_deliver(buf, beginidx, offsets->commit_count);
-}
-
-
-/*
- * ltt_reserve_end_switch_current: finish switching current subbuffer
- *
- * Concurrency safe because we are the last and only thread to alter this
- * sub-buffer. As long as it is not delivered and read, no other thread can
- * alter the offset, alter the reserve_count or call the
- * client_buffer_end_callback on this sub-buffer.
- *
- * The only remaining threads could be the ones with pending commits. They will
- * have to do the deliver themselves. Not concurrency safe in overwrite mode.
- * We detect corrupted subbuffers with commit and reserve counts. We keep a
- * corrupted sub-buffers count and push the readers across these sub-buffers.
- *
- * Not concurrency safe if a writer is stalled in a subbuffer and another writer
- * switches in, finding out it's corrupted. The result will be than the old
- * (uncommited) subbuffer will be declared corrupted, and that the new subbuffer
- * will be declared corrupted too because of the commit count adjustment.
- */
-static inline void ltt_reserve_end_switch_current(
- struct ust_channel *channel,
- struct ust_buffer *buf,
- struct ltt_reserve_switch_offsets *offsets, u64 *tsc)
-{
- long endidx = SUBBUF_INDEX(offsets->end - 1, channel);
-
- channel->buffer_end(buf, *tsc, offsets->end, endidx);
- /* Must write buffer begin before incrementing commit count */
- smp_wmb();
- offsets->commit_count =
- local_add_return(channel->subbuf_size
- - (SUBBUF_OFFSET(offsets->end - 1, channel)
- + 1),
- &buf->commit_count[endidx]);
- if ((BUFFER_TRUNC(offsets->end - 1, channel)
- >> channel->n_subbufs_order)
- - ((offsets->commit_count - channel->subbuf_size)
- & channel->commit_count_mask) == 0)
- ltt_deliver(buf, endidx, offsets->commit_count);
-}
-
-/**
- * ltt_relay_reserve_slot - Atomic slot reservation in a LTTng buffer.
- * @trace: the trace structure to log to.
- * @ltt_channel: channel structure
- * @transport_data: data structure specific to ltt relay
- * @data_size: size of the variable length data to log.
- * @slot_size: pointer to total size of the slot (out)
- * @buf_offset : pointer to reserved buffer offset (out)
- * @tsc: pointer to the tsc at the slot reservation (out)
- * @cpu: cpuid
- *
- * Return : -ENOSPC if not enough space, else returns 0.
- * It will take care of sub-buffer switching.