/* Copyright (c) 2016 Google Inc.
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Vcore timer ticks. */

#include <parlib/vcore.h>
#include <parlib/uthread.h>
#include <parlib/assert.h>
#include <parlib/tsc-compat.h>
#include <parlib/arch/bitmask.h>
#include <benchutil/alarm.h>
#include <benchutil/vcore_tick.h>

/* TODO: if we use some other form of per-vcore memory, we can also have a
 * per-vcore init function that we run before the VC spools up, removing the
 * need to check for PREINIT. */

enum {
	VC_TICK_PREINIT = 0,
	VC_TICK_ENABLED = 1,
	VC_TICK_DISABLED = 2,
};

struct vcore_tick {
	int							state;
	int							ctl_fd;
	int							timer_fd;
	uint64_t					next_deadline;
	uint64_t					period_ticks;
	struct event_queue			*ev_q;
};

static struct vcore_tick *__vc_ticks;

static void __attribute__((constructor)) vcore_tick_lib_init(void)
{
	__vc_ticks = calloc(max_vcores(), sizeof(struct vcore_tick));
	assert(__vc_ticks);
}

/* Only call this from vcore context or with notifs disabled. */
static struct vcore_tick *get_my_tick(void)
{
	return &__vc_ticks[vcore_id()];
}

static void vcore_tick_init(struct vcore_tick *vc_tick)
{
	int ret;

	ret = devalarm_get_fds(&vc_tick->ctl_fd, &vc_tick->timer_fd, 0);
	assert(!ret);
	/* We want an IPI and a bit set in the bitmask.  But no wakeups, in case
	 * we're offline. */
	vc_tick->ev_q = get_eventq(EV_MBOX_BITMAP);
	assert(vc_tick->ev_q);
	vc_tick->ev_q->ev_flags = EVENT_IPI;
	vc_tick->ev_q->ev_vcore = vcore_id();
	ret = devalarm_set_evq(vc_tick->timer_fd, vc_tick->ev_q, 0);
	assert(!ret);
	vc_tick->state = VC_TICK_DISABLED;
}

static void __vcore_tick_start(struct vcore_tick *vc_tick, uint64_t from_now)
{
	int ret;

	ret = devalarm_set_time(vc_tick->timer_fd, read_tsc() + from_now);
	assert(!ret);
}

/* Starts a timer tick for this vcore, in virtual time (time the vcore is
 * actually online).  You can call this repeatedly, even if the timer is already
 * on.  You also can update the period of an already-running tick. */
void vcore_tick_enable(uint64_t period_usec)
{
	struct vcore_tick *vc_tick;

	uth_disable_notifs();
	vc_tick = get_my_tick();
	if (vc_tick->state == VC_TICK_PREINIT)
		vcore_tick_init(vc_tick);

	vc_tick->period_ticks = usec2tsc(period_usec);
	if (vc_tick->state == VC_TICK_DISABLED) {
		vc_tick->next_deadline = vcore_account_uptime_ticks(vcore_id()) +
		                         vc_tick->period_ticks;
		__vcore_tick_start(vc_tick, vc_tick->period_ticks);
		vc_tick->state = VC_TICK_ENABLED;
	}
	uth_enable_notifs();
}

/* Disables the timer tick.  You can call this repeatedly.  It is possible that
 * you will still have a timer tick pending after this returns. */
void vcore_tick_disable(void)
{
	struct vcore_tick *vc_tick;
	int ret;

	uth_disable_notifs();
	vc_tick = get_my_tick();
	if (vc_tick->state == VC_TICK_PREINIT)
		vcore_tick_init(vc_tick);

	if (vc_tick->state == VC_TICK_ENABLED) {
		ret = devalarm_disable(vc_tick->timer_fd);
		assert(!ret);
		vc_tick->state = VC_TICK_DISABLED;
	}
	uth_enable_notifs();
}

/* Polls the vcore timer tick.  Returns the number of times it has expired, 0
 * for not yet otherwise.  Either way, it will ensure that the underlying alarm
 * is still turned on. */
int vcore_tick_poll(void)
{
	struct vcore_tick *vc_tick;
	struct evbitmap *evbm;
	int ret = 0;
	uint64_t from_now, virtual_now;

	uth_disable_notifs();
	vc_tick = get_my_tick();
	if (vc_tick->state == VC_TICK_PREINIT)
		vcore_tick_init(vc_tick);

	evbm = &vc_tick->ev_q->ev_mbox->evbm;
	if (!GET_BITMASK_BIT(evbm->bitmap, EV_ALARM)) {
		/* It might be possible that the virtual time has passed, but the alarm
		 * hasn't arrived yet.
		 *
		 * We assume that if the bit is not set and the tick is enabled that
		 * the kernel still has an alarm set for us.  It is possible for the bit
		 * to be set more than expected (disable an alarm, but fail to cancel
		 * the alarm before it goes off, then enable it, and then we'll have the
		 * bit set before the alarm expired).  However, it is not possible that
		 * the bit is clear and there is no alarm pending at this point.  This
		 * is because the only time we clear the bit is below, and then right
		 * after that we set an alarm. (The bit is also clear at init time, and
		 * we start the alarm when we enable the tick).
		 *
		 * Anyway, the alarm should be arriving shortly.  In this case, as in
		 * the case where the bit gets set right after we check, we missed
		 * polling for the event.  The kernel will still __notify us, setting
		 * notif_pending, and we'll notice the next time we attempt to leave
		 * vcore context. */
		uth_enable_notifs();
		return 0;
	}
	/* Don't care about clobbering neighboring bits (non-atomic op) */
	CLR_BITMASK_BIT(evbm->bitmap, EV_ALARM);
	/* As mentioned above, it is possible to still have an active alarm in the
	 * kernel.  We can still set a new time for the alarm, and it will just
	 * update the kernel's awaiter.  And if that alarm has fired, then we'll
	 * just have a spurious setting of the bit.  This does not affect our return
	 * value, which is based on virtual time, not alarm resets. */
	virtual_now = vcore_account_uptime_ticks(vcore_id());
	/* It's possible that we've fallen multiple ticks behind virtual now.
	 * In that case, we'll just jump ahead a bit */
	while (vc_tick->next_deadline <= virtual_now) {
		ret++;
		vc_tick->next_deadline += vc_tick->period_ticks;
	}
	/* There's a slight chance we miss an alarm if the period is very small.
	 * virtual_now is a little old.  If the period is so small that this is a
	 * problem and if we updated virtual now in the while loop, then we'd also
	 * get caught in the while loop forever. */
	from_now = vc_tick->next_deadline - virtual_now;
	__vcore_tick_start(vc_tick, from_now);
	uth_enable_notifs();
	return ret;
}
