/* 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 <parlib/alarm.h>
#include <parlib/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_ctor(void)
{
	if (__in_fake_parlib())
		return;
	__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;
}
