/* Copyright (c) 2013 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Simple ring-buffer tracing for in-kernel events.  The rings have a
 * power-of-two number of slots, and each entry size will be rounded up to the
 * nearest power of two.  Ring slot acquisition by default is thread-safe, but
 * we provide racy helpers if you want a little less overhead.
 *
 * Users need to provide a contiguous memory buffer and the size of an event
 * struct to init.  For example:
 *
 * 		trace_ring_init(my_trace_ring_ptr, my_buf, buf_sz, event_sz);
 *
 * And then to store a trace, first get a slot, then fill it in:
 *
 * 		struct my_trace_event *my_trace = get_trace_slot(my_trace_ring_ptr);
 * 		if (my_trace)	// only need to check if we aren't overwriting
 * 			my_trace = whatever;
 *
 * Later, to process the traces, provide a function pointer to
 * trace_ring_foreach().  This performs the func on all traces in the ring,
 * including the unused:
 *
 * 		void trace_handler(void *trace_event, void *data)
 * 		{
 * 			whatever();
 * 		}
 * 		trace_ring_foreach(my_trace_ring_ptr, trace_handler, optional_blob);
 *
 * Rings can be racy or not, and can overwrite entries or not.  If you are not
 * overwriting, the ring will stop giving you slots.  You need to reset the ring
 * to get fresh slots again.  If you are overwriting, you don't need to check
 * the return value of get_trace_slot_overwrite().
 *
 * Given there is overwrite, tr_next doesn't really tell us which ones were
 * used.  So your handler should check for a flag or something.  Timestamps
 * might help make sense of the data in these cases too. */

#pragma once

#include <ros/common.h>
#include <assert.h>

struct trace_ring {
	unsigned char				*tr_buf;
	size_t						tr_buf_sz;
	unsigned int				tr_event_sz_shift;
	unsigned int				tr_max;
	unsigned long				tr_next;
};

typedef void (*trace_handler_t)(void *event, void *blob);

static inline void *get_trace_slot(struct trace_ring *tr);
static inline void *get_trace_slot_overwrite(struct trace_ring *tr);
static inline void *get_trace_slot_racy(struct trace_ring *tr);
static inline void *get_trace_slot_overwrite_racy(struct trace_ring *tr);

void trace_ring_init(struct trace_ring *tr, void *buf, size_t buf_size,
                     size_t event_size);
void trace_ring_reset(struct trace_ring *tr);
void trace_ring_reset_and_clear(struct trace_ring *tr);
void trace_ring_foreach(struct trace_ring *tr, trace_handler_t tr_func,
                        void *data);

/* Inlined funcs, declared above */

/* Helper */
/* Get next trace ring slot with no wrapping */
static inline void *__get_tr_slot(struct trace_ring *tr, unsigned long ind)
{
	dassert(0 <= ind && ind < tr->tr_max);
	/* event sizes are rounded up to the nearest power of 2 (sz_shift) */
	return (void *) (tr->tr_buf + (ind << tr->tr_event_sz_shift));
}

/* Get next trace ring slot with wrapping */
static inline void *
__get_tr_slot_overwrite(struct trace_ring *tr, unsigned long slot)
{
	/* tr_max is a power of 2, we're ignoring the upper bits of slot */
	slot &= tr->tr_max - 1;
	return __get_tr_slot(tr, slot);
}

static inline void *get_trace_slot(struct trace_ring *tr)
{
	/* Using syncs, instead of atomics, since we access tr_next as both atomic
	 * and 'normal'. */
	unsigned long my_slot = __sync_fetch_and_add(&tr->tr_next, 1);
	/* We can briefly go over, so long as we subtract back down to where we were
	 * before.  This will work so long as we don't have ~2^64 threads... */
	if (my_slot >= tr->tr_max) {
		__sync_fetch_and_add(&tr->tr_next, -1);
		return 0;
	}
	return __get_tr_slot(tr, my_slot);
}

static inline void *get_trace_slot_overwrite(struct trace_ring *tr)
{
	return __get_tr_slot_overwrite(tr, __sync_fetch_and_add(&tr->tr_next, 1));
}

static inline void *get_trace_slot_racy(struct trace_ring *tr)
{
	unsigned long my_slot = tr->tr_next;
	if (my_slot >= tr->tr_max)
		return 0;
	tr->tr_next++;
	return __get_tr_slot(tr, my_slot);
}

static inline void *get_trace_slot_overwrite_racy(struct trace_ring *tr)
{
	return __get_tr_slot_overwrite(tr, tr->tr_next++);
}
