/* Copyright (c) 2011-2014 The Regents of the University of California
 * Copyright (c) 2015 Google Inc
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Userspace utility functions for receiving events and notifications (IPIs).
 * Some are higher level than others; just use what you need. */ 

#include <ros/event.h>
#include <ros/procdata.h>
#include <parlib/ucq.h>
#include <parlib/evbitmap.h>
#include <parlib/ceq.h>
#include <parlib/vcore.h>
#include <stdlib.h>
#include <string.h>
#include <parlib/assert.h>
#include <errno.h>
#include <parlib/parlib.h>
#include <parlib/event.h>
#include <parlib/uthread.h>
#include <parlib/spinlock.h>
#include <parlib/mcs.h>
#include <parlib/poke.h>
#include <sys/queue.h>
#include <malloc.h>

/* For remote VCPD mbox event handling */
__thread bool __vc_handle_an_mbox = FALSE;
__thread uint32_t __vc_rem_vcoreid;

/********* Event_q Setup / Registration  ***********/

/* Get event_qs via these interfaces, since eventually we'll want to either
 * allocate from pinned memory or use some form of a slab allocator.  Also,
 * these stitch up the big_q so its ev_mbox points to its internal mbox.  Never
 * access the internal mbox directly.
 *
 * Raw ones need to have their mailboxes initialized.  If you're making a lot of
 * these and they perform their own mmaps (e.g. UCQs), you can do one big mmap
 * and init the ucqs on your own, which ought to perform better.
 *
 * Use the 'regular' one for big_qs if you don't want to worry about the mbox
 * initalization */
struct event_queue *get_eventq_raw(void)
{
	/* TODO: (PIN) should be pinned memory */
	struct event_queue_big *big_q = malloc(sizeof(struct event_queue_big));
	memset(big_q, 0, sizeof(struct event_queue_big));
	big_q->ev_mbox = &big_q->ev_imbox;
	return (struct event_queue*)big_q;
}

struct event_queue *get_eventq(int mbox_type)
{
	struct event_queue *big_q = get_eventq_raw();
	event_mbox_init(big_q->ev_mbox, mbox_type);
	return big_q;
}

/* Basic initialization of a single mbox.  If you know the type, you can set up
 * the mbox manually with possibly better performance.  For instance, ucq_init()
 * calls mmap internally.  You could mmap a huge blob on your own and call
 * ucq_raw_init (don't forget to set the mbox_type!) */
void event_mbox_init(struct event_mbox *ev_mbox, int mbox_type)
{
	ev_mbox->type = mbox_type;
	switch (ev_mbox->type) {
		case (EV_MBOX_UCQ):
			ucq_init(&ev_mbox->ucq);
			break;
		case (EV_MBOX_BITMAP):
			evbitmap_init(&ev_mbox->evbm);
			break;
		case (EV_MBOX_CEQ):
			ceq_init(&ev_mbox->ceq, CEQ_OR, CEQ_DEFAULT_SZ, CEQ_DEFAULT_SZ);
			break;
		default:
			printf("Unknown mbox type %d!\n", ev_mbox->type);
			break;
	}
}

/* Give it up.  I don't recommend calling these unless you're sure the queues
 * aren't in use (unregistered, etc). (TODO: consider some checks for this) */
void put_eventq_raw(struct event_queue *ev_q)
{
	/* if we use something other than malloc, we'll need to be aware that ev_q
	 * is actually an event_queue_big.  One option is to use the flags, though
	 * this could be error prone. */
	free(ev_q);
}

void put_eventq(struct event_queue *ev_q)
{
	event_mbox_cleanup(ev_q->ev_mbox);
	put_eventq_raw(ev_q);
}

void event_mbox_cleanup(struct event_mbox *ev_mbox)
{
	switch (ev_mbox->type) {
		case (EV_MBOX_UCQ):
			ucq_free_pgs(&ev_mbox->ucq);
			break;
		case (EV_MBOX_BITMAP):
			evbitmap_cleanup(&ev_mbox->evbm);
			break;
		case (EV_MBOX_CEQ):
			ceq_cleanup(&ev_mbox->ceq);
			break;
		default:
			printf("Unknown mbox type %d!\n", ev_mbox->type);
			break;
	}
}

/* Need to point this event_q to an mbox - usually to a vcpd */
struct event_queue *get_eventq_slim(void)
{
	/* TODO: (PIN) should be pinned memory */
	struct event_queue *ev_q = malloc(sizeof(struct event_queue));
	memset(ev_q, 0, sizeof(struct event_queue));
	return ev_q;
}

/* Gets a small ev_q, with ev_mbox pointing to the vcpd mbox of vcoreid.  If
 * ev_flags has EVENT_VCORE_PRIVATE set, it'll give you the private mbox.  o/w,
 * you'll get the public one. */
struct event_queue *get_eventq_vcpd(uint32_t vcoreid, int ev_flags)
{
	struct event_queue *ev_q = get_eventq_slim();
	if (ev_flags & EVENT_VCORE_PRIVATE)
		ev_q->ev_mbox = &vcpd_of(vcoreid)->ev_mbox_private;
	else
		ev_q->ev_mbox = &vcpd_of(vcoreid)->ev_mbox_public;
	return ev_q;
}

void put_eventq_slim(struct event_queue *ev_q)
{
	/* if we use something other than malloc, we'll need to be aware that ev_q
	 * is not an event_queue_big. */
	free(ev_q);
}

void put_eventq_vcpd(struct event_queue *ev_q)
{
	put_eventq_slim(ev_q);
}

/* Sets ev_q to be the receiving end for kernel event ev_type */
void register_kevent_q(struct event_queue *ev_q, unsigned int ev_type)
{
	__procdata.kernel_evts[ev_type] = ev_q;
}

/* Clears the event, returning an ev_q if there was one there.  You'll need to
 * free it. */
struct event_queue *clear_kevent_q(unsigned int ev_type)
{
	struct event_queue *ev_q = __procdata.kernel_evts[ev_type];
	__procdata.kernel_evts[ev_type] = 0;
	return ev_q;
}

/* Enables an IPI/event combo for ev_type sent to vcoreid's default mbox.  IPI
 * if you want one or not.  If you want the event to go to the vcore private
 * mbox (meaning no other core should ever handle it), send in
 * EVENT_VCORE_PRIVATE with ev_flags.
 *
 * This is the simplest thing applications may want, and shows how you can put
 * the other event functions together to get similar things done. */
void enable_kevent(unsigned int ev_type, uint32_t vcoreid, int ev_flags)
{
	struct event_queue *ev_q = get_eventq_vcpd(vcoreid, ev_flags);
	ev_q->ev_flags = ev_flags;
	ev_q->ev_vcore = vcoreid;
	ev_q->ev_handler = 0;
	wmb();	/* make sure ev_q is filled out before registering */
	register_kevent_q(ev_q, ev_type);
}

/* Stop receiving the events (one could be on the way).  Caller needs to be
 * careful, since the kernel might be sending an event to the ev_q.  Depending
 * on the ev_q, it may be hard to know when it is done (for instance, if all
 * syscalls you ever registered with the ev_q are done, then it would be okay).
 * o/w, don't free it. */
struct event_queue *disable_kevent(unsigned int ev_type)
{
	return clear_kevent_q(ev_type);
}

/********* Event Handling / Reception ***********/
/* Somewhat ghetto helper, for the lazy.  If all you care about is an event
 * number, this will see if the event happened or not.  It will try for a
 * message, but if there is none, it will go for a bit.  Note that multiple
 * bit messages will turn into just one bit. */
unsigned int get_event_type(struct event_mbox *ev_mbox)
{
	struct event_msg local_msg = {0};

	if (extract_one_mbox_msg(ev_mbox, &local_msg))
		return local_msg.ev_type;
	return EV_NONE;
}

/* Attempts to register ev_q with sysc, so long as sysc is not done/progress.
 * Returns true if it succeeded, and false otherwise.  False means that the
 * syscall is done, and does not need an event set (and should be handled
 * accordingly).
 *
 * A copy of this is in glibc/sysdeps/akaros/syscall.c.  Keep them in sync. */
bool register_evq(struct syscall *sysc, struct event_queue *ev_q)
{
	int old_flags;
	sysc->ev_q = ev_q;
	wrmb();	/* don't let that write pass any future reads (flags) */
	/* Try and set the SC_UEVENT flag (so the kernel knows to look at ev_q) */
	do {
		/* no cmb() needed, the atomic_read will reread flags */
		old_flags = atomic_read(&sysc->flags);
		/* Spin if the kernel is mucking with syscall flags */
		while (old_flags & SC_K_LOCK)
			old_flags = atomic_read(&sysc->flags);
		/* If the kernel finishes while we are trying to sign up for an event,
		 * we need to bail out */
		if (old_flags & (SC_DONE | SC_PROGRESS)) {
			sysc->ev_q = 0;		/* not necessary, but might help with bugs */
			return FALSE;
		}
	} while (!atomic_cas(&sysc->flags, old_flags, old_flags | SC_UEVENT));
	return TRUE;
}

/* De-registers a syscall, so that the kernel will not send an event when it is
 * done.  The call could already be SC_DONE, or could even finish while we try
 * to unset SC_UEVENT.
 *
 * There is a chance the kernel sent an event if you didn't do this in time, but
 * once this returns, the kernel won't send a message.
 *
 * If the kernel is trying to send a message right now, this will spin (on
 * SC_K_LOCK).  We need to make sure we deregistered, and that if a message
 * is coming, that it already was sent (and possibly overflowed), before
 * returning. */
void deregister_evq(struct syscall *sysc)
{
	int old_flags;
	sysc->ev_q = 0;
	wrmb();	/* don't let that write pass any future reads (flags) */
	/* Try and unset the SC_UEVENT flag */
	do {
		/* no cmb() needed, the atomic_read will reread flags */
		old_flags = atomic_read(&sysc->flags);
		/* Spin if the kernel is mucking with syscall flags */
		while (old_flags & SC_K_LOCK)
			old_flags = atomic_read(&sysc->flags);
		/* Note we don't care if the SC_DONE flag is getting set.  We just need
		 * to avoid clobbering flags */
	} while (!atomic_cas(&sysc->flags, old_flags, old_flags & ~SC_UEVENT));
}

/* Actual Event Handling */

/* List of handler lists, process-wide.  They all must return (don't context
 * switch to a u_thread) */
struct ev_handler *ev_handlers[MAX_NR_EVENT] = {0};
spinpdrlock_t ev_h_wlock = SPINPDR_INITIALIZER;

int register_ev_handler(unsigned int ev_type, handle_event_t handler,
                        void *data)
{
	/* Nasty uthread code assumes this was malloced */
	struct ev_handler *new_h = malloc(sizeof(struct ev_handler));

	if (!new_h)
		return -1;
	new_h->func = handler;
	new_h->data = data;
	spin_pdr_lock(&ev_h_wlock);
	new_h->next = ev_handlers[ev_type];
	wmb();	/* make sure new_h is done before publishing to readers */
	ev_handlers[ev_type] = new_h;
	spin_pdr_unlock(&ev_h_wlock);
	return 0;
}

int deregister_ev_handler(unsigned int ev_type, handle_event_t handler,
                          void *data)
{
	/* TODO: User-level RCU */
	printf("Failed to dereg handler, not supported yet!\n");
	return -1;
}

static void run_ev_handlers(unsigned int ev_type, struct event_msg *ev_msg)
{
	struct ev_handler *handler;
	/* TODO: RCU read lock */
	handler = ev_handlers[ev_type];
	while (handler) {
		handler->func(ev_msg, ev_type, handler->data);
		handler = handler->next;
	}
}

/* Attempts to extract a message from an mbox, copying it into ev_msg.
 * Returns TRUE on success. */
bool extract_one_mbox_msg(struct event_mbox *ev_mbox, struct event_msg *ev_msg)
{
	switch (ev_mbox->type) {
		case (EV_MBOX_UCQ):
			return get_ucq_msg(&ev_mbox->ucq, ev_msg);
		case (EV_MBOX_BITMAP):
			return get_evbitmap_msg(&ev_mbox->evbm, ev_msg);
		case (EV_MBOX_CEQ):
			return get_ceq_msg(&ev_mbox->ceq, ev_msg);
		default:
			printf("Unknown mbox type %d!\n", ev_mbox->type);
			return FALSE;
	}
}

/* Attempts to handle a message.  Returns 1 if we dequeued a msg, 0 o/w. */
int handle_one_mbox_msg(struct event_mbox *ev_mbox)
{
	struct event_msg local_msg;
	unsigned int ev_type;
	/* extract returns TRUE on success, we return 1. */
	if (!extract_one_mbox_msg(ev_mbox, &local_msg))
		return 0;
	ev_type = local_msg.ev_type;
	assert(ev_type < MAX_NR_EVENT);
	printd("[event] UCQ (mbox %08p), ev_type: %d\n", ev_mbox, ev_type);
	run_ev_handlers(ev_type, &local_msg);
	return 1;
}

/* Handle an mbox.  This is the receive-side processing of an event_queue.  It
 * takes an ev_mbox, since the vcpd mbox isn't a regular ev_q.  Returns 1 if we
 * handled something, 0 o/w. */
int handle_mbox(struct event_mbox *ev_mbox)
{
	int retval = 0;
	printd("[event] handling ev_mbox %08p on vcore %d\n", ev_mbox, vcore_id());
	/* Some stack-smashing bugs cause this to fail */
	assert(ev_mbox);
	/* Handle all full messages, tracking if we do at least one. */
	while (handle_one_mbox_msg(ev_mbox))
		retval = 1;
	return retval;
}

/* Empty if the UCQ is empty and the bits don't need checked */
bool mbox_is_empty(struct event_mbox *ev_mbox)
{
	switch (ev_mbox->type) {
		case (EV_MBOX_UCQ):
			return ucq_is_empty(&ev_mbox->ucq);
		case (EV_MBOX_BITMAP):
			return evbitmap_is_empty(&ev_mbox->evbm);
		case (EV_MBOX_CEQ):
			return ceq_is_empty(&ev_mbox->ceq);
		default:
			printf("Unknown mbox type %d!\n", ev_mbox->type);
			return FALSE;
	}
}

/* The EV_EVENT handler - extract the ev_q from the message. */
void handle_ev_ev(struct event_msg *ev_msg, unsigned int ev_type, void *data)
{
	struct event_queue *ev_q;
	/* EV_EVENT can't handle not having a message / being a bit.  If we got a
	 * bit message, it's a bug somewhere */
	assert(ev_msg);
	ev_q = ev_msg->ev_arg3;
	/* Same deal, a null ev_q is probably a bug, or someone being a jackass */
	assert(ev_q);
	/* Clear pending, so we can start getting INDIRs and IPIs again.  We must
	 * set this before (compared to handle_events, then set it, then handle
	 * again), since there is no guarantee handle_event_q() will return.  If
	 * there is a pending preemption, the vcore quickly yields and will deal
	 * with the remaining events in the future - meaning it won't return to
	 * here. */
	ev_q->ev_alert_pending = FALSE;
	wmb();	/* don't let the pending write pass the signaling of an ev recv */
	handle_event_q(ev_q);
}

/* Handles VCPD events (public and private).  The kernel always sets
 * notif_pending after posting a message to either public or private mailbox.
 * When this returns, as far as we are concerned, notif_pending is FALSE.
 * However, a concurrent kernel writer could have reset it to true.  This is
 * fine; whenever we leave VC ctx we double check notif_pending.  Returns 1 or 2
 * if we actually handled a message, 0 o/w.
 *
 * WARNING: this might not return and/or current_uthread may change. */
int handle_events(uint32_t vcoreid)
{
	struct preempt_data *vcpd = vcpd_of(vcoreid);
	int retval = 0;
	vcpd->notif_pending = FALSE;
	wrmb();	/* prevent future reads from happening before notif_p write */
	retval += handle_mbox(&vcpd->ev_mbox_private);
	retval += handle_mbox(&vcpd->ev_mbox_public);
	return retval;
}

/* Handles the events on ev_q IAW the event_handlers[].  If the ev_q is
 * application specific, then this will dispatch/handle based on its flags. */
void handle_event_q(struct event_queue *ev_q)
{
	printd("[event] handling ev_q %08p on vcore %d\n", ev_q, vcore_id());
	/* If the program wants to handle the ev_q on its own: */
	if (ev_q->ev_handler) {
		/* Remember this can't block or page fault */
		ev_q->ev_handler(ev_q);
		return;
	}
	/* Raw ev_qs that haven't been connected to an mbox, user bug: */
	assert(ev_q->ev_mbox);
	/* The "default" ev_handler, common enough that I don't want a func ptr */
	handle_mbox(ev_q->ev_mbox);
}

/* Sends the calling vcore a message to its public mbox.  This is purposefully
 * limited to just the calling vcore, since in future versions, we can send via
 * ucqs directly (in many cases).  That will require the caller to be the
 * vcoreid, due to some preemption recovery issues (another ucq poller is
 * waiting on us when we got preempted, and we never up nr_cons). */
void send_self_vc_msg(struct event_msg *ev_msg)
{
	// TODO: try to use UCQs (requires additional support)
	/* ev_type actually gets ignored currently.  ev_msg is what matters if it is
	 * non-zero.  FALSE means it's going to the public mbox */
	sys_self_notify(vcore_id(), ev_msg->ev_type, ev_msg, FALSE);
}

/* Helper: makes the current core handle a remote vcore's VCPD public mbox events.
 *
 * Both cases (whether we are handling someone else's already or not) use some
 * method of telling our future self what to do.  When we aren't already
 * handling it, we use TLS, and jump to vcore entry.  When we are already
 * handling, then we send a message to ourself, which we deal with when we
 * handle our own events (which is later in vcore entry).
 *
 * We need to reset the stack and deal with it in vcore entry to avoid recursing
 * deeply and running off the transition stack.  (handler calling handle event).
 *
 * Note that we might not be the one that gets the message we send.  If we pull
 * a sys_change_to, someone else might be polling our public message box.  All
 * we're doing is making sure that we don't forget to check rem_vcoreid's mbox.
 *
 * Finally, note that this function might not return.  However, it'll handle the
 * details related to vcpd mboxes, so you don't use the ev_might_not_return()
 * helpers with this. */
void handle_vcpd_mbox(uint32_t rem_vcoreid)
{
	uint32_t vcoreid = vcore_id();
	struct preempt_data *vcpd = vcpd_of(vcoreid);
	struct event_msg local_msg = {0};
	assert(vcoreid != rem_vcoreid);			/* this shouldn't happen */
	/* If they are empty, then we're done */
	if (mbox_is_empty(&vcpd_of(rem_vcoreid)->ev_mbox_public))
		return;
	if (__vc_handle_an_mbox) {
		/* we might be already handling them, in which case, abort */
		if (__vc_rem_vcoreid == rem_vcoreid)
			return;
		/* Already handling message for someone, need to send ourselves a
		 * message to check rem_vcoreid, which we'll process later. */
		local_msg.ev_type = EV_CHECK_MSGS;
		local_msg.ev_arg2 = rem_vcoreid;	/* 32bit arg */
		send_self_vc_msg(&local_msg);
		return;
	}
	/* No return after here */
	/* At this point, we aren't in the process of handling someone else's
	 * messages, so just tell our future self what to do */
	__vc_handle_an_mbox = TRUE;
	__vc_rem_vcoreid = rem_vcoreid;
	/* Reset the stack and start over in vcore context */
	set_stack_pointer((void*)vcpd->vcore_stack);
	vcore_entry();
	assert(0);
}

/* Handle remote vcpd public mboxes, if that's what we want to do.  Call this
 * from vcore entry, pairs with handle_vcpd_mbox(). */
void try_handle_remote_mbox(void)
{
	if (__vc_handle_an_mbox) {
		handle_mbox(&vcpd_of(__vc_rem_vcoreid)->ev_mbox_public);
		/* only clear the flag when we have returned from handling messages.  if
		 * an event handler (like preempt_recover) doesn't return, we'll clear
		 * this flag elsewhere. (it's actually not a big deal if we don't). */
		cmb();
		__vc_handle_an_mbox = FALSE;
	}
}

/* Event handler helpers */

/* For event handlers that might not return, we need to call this before the
 * command that might not return.  In the event we were handling a remote
 * vcore's messages, it'll send ourselves a messages that we (or someone who
 * polls us) will get so that someone finishes off that vcore's messages).
 * Doesn't matter who does, so long as someone does.
 *
 * This returns whether or not we were handling someone's messages.  Pass the
 * parameter to ev_we_returned() */
bool ev_might_not_return(void)
{
	struct event_msg local_msg = {0};
	bool were_handling_remotes = FALSE;
	if (__vc_handle_an_mbox) {
		/* slight chance we finished with their mbox (were on the last one) */
		if (!mbox_is_empty(&vcpd_of(__vc_rem_vcoreid)->ev_mbox_public)) {
			/* But we aren't, so we'll need to send a message */
			local_msg.ev_type = EV_CHECK_MSGS;
			local_msg.ev_arg2 = __vc_rem_vcoreid;	/* 32bit arg */
			send_self_vc_msg(&local_msg);
		}
		/* Either way, we're not working on this one now.  Note this is more of
		 * an optimization - it'd be harmless (I think) to poll another vcore's
		 * pub mbox once when we pop up in vc_entry in the future */
		__vc_handle_an_mbox = FALSE;
		return TRUE;
	}
	return FALSE;
}

/* Call this when you return, paired up with ev_might_not_return().  If
 * ev_might_not_return turned off uth_handle, we'll turn it back on. */
void ev_we_returned(bool were_handling_remotes)
{
	if (were_handling_remotes)
		__vc_handle_an_mbox = TRUE;
}

/* Debugging */
void print_ev_msg(struct event_msg *msg)
{
	printf("MSG at %08p\n", msg);
	printf("\ttype: %d\n", msg->ev_type);
	printf("\targ1 (16): 0x%4x\n", msg->ev_arg1);
	printf("\targ2 (32): 0x%8x\n", msg->ev_arg2);
	printf("\targ3 (32): 0x%8x\n", msg->ev_arg3);
	printf("\targ4 (64): 0x%16x\n", msg->ev_arg4);
}

/* Uthreads blocking on event queues
 *
 * It'd be nice to have a uthread sleep until an event queue has some activity
 * (e.g. a new message).  It'd also be nice to wake up early with a timer.  It
 * is tempting to try something like an INDIR and have one evq multiplex two
 * others (the real event and an alarm).  But then you can't separate the two
 * streams; what if one thread sleeps on just the event at the same time?  What
 * if we want to support something like Go's select: a thread wants to block
 * until there is some activity on some channel?
 *
 * Ultimately, we want to allow M uthreads to block on possibly different
 * subsets of N event queues.
 *
 * Every uthread will have a sleep controller, and every event queue will have a
 * wakeup controller.  There are up to MxN linkage structures connecting these.
 *
 * We'll use the event_queue handler to override the default event processing.
 * This means the event queues that are used for blocking uthreads can *only* be
 * used for that; the regular event processing will not happen.  This is mostly
 * true.  It is possible to extract events from an evq's mbox concurrently.
 *
 * I briefly considered having one global lock to protect all of the lists and
 * structures.  That's lousy for the obvious scalability reason, but it seemed
 * like it'd make things easier, especially when I thought I needed locks in
 * both the ectlr and the uctlr (in early versions, I considered having the
 * handler yank itself out of the ectlr, copying a message into that struct, or
 * o/w needing protection).  On occasion, we run into the "I'd like to split my
 * lock between two components and still somehow synchronize" issue (e.g. FD
 * taps, with the FDT lock and the blocking/whatever that goes on in a device).
 * Whenever that comes up, we usually can get some help from other shared memory
 * techniques.  For FD taps, it's the kref.  For us, it's post-and-poke, though
 * it didn't solve all of our problems - I use it as a tool with some basic
 * shared memory signalling. */

struct evq_wait_link;
TAILQ_HEAD(wait_link_tailq, evq_wait_link);

/* Bookkeeping for the uthread sleeping on a bunch of event queues.
 *
 * Notes on concurrency: most fields are not protected.  check_evqs is racy, and
 * written to by handlers.  The tailq is only used by the uthread.  blocked is
 * never concurrently *written*; see __uth_wakeup_poke() for details. */
struct uth_sleep_ctlr {
	struct uthread				*uth;
	struct spin_pdr_lock		in_use;
	bool						check_evqs;
	bool						blocked;
	struct poke_tracker			poker;
	struct wait_link_tailq		evqs;
};

/* Attaches to an event_queue (ev_udata), tracks the uthreads for this evq */
struct evq_wakeup_ctlr {
	struct wait_link_tailq		waiters;
	struct spin_pdr_lock		lock;
};

/* Up to MxN of these, N of them per uthread. */
struct evq_wait_link {
	struct uth_sleep_ctlr		*uth_ctlr;
	TAILQ_ENTRY(evq_wait_link)	link_uth;
	struct evq_wakeup_ctlr		*evq_ctlr;
	TAILQ_ENTRY(evq_wait_link)	link_evq;
};

/* Poke function: ensures the uth managed by uctlr wakes up.  poke() ensures
 * there is only one thread in this function at a time.  However, it could be
 * called spuriously, which is why we check 'blocked.' */
static void __uth_wakeup_poke(void *arg)
{
	struct uth_sleep_ctlr *uctlr = arg;
	/* There are no concurrent writes to 'blocked'.  Blocked is only ever
	 * written when the uth sleeps and only ever cleared here.  Once the uth
	 * writes it, it does not write it again until after we clear it.
	 *
	 * This is still racy - we could see !blocked, then blocked gets set.  In
	 * that case, the poke failed, and that is harmless.  The uth will see
	 * 'check_evqs', which was set before poke, which would be before writing
	 * blocked, and the uth checks 'check_evqs' after writing. */
	if (uctlr->blocked) {
		uctlr->blocked = FALSE;
		cmb();	/* clear blocked before starting the uth */
		uthread_runnable(uctlr->uth);
	}
}

static void uth_sleep_ctlr_init(struct uth_sleep_ctlr *uctlr,
                                struct uthread *uth)
{
	uctlr->uth = uth;
	spin_pdr_init(&uctlr->in_use);
	uctlr->check_evqs = FALSE;
	uctlr->blocked = FALSE;
	poke_init(&uctlr->poker, __uth_wakeup_poke);
	TAILQ_INIT(&uctlr->evqs);
}

/* This handler runs when the ev_q is checked.  Instead of doing anything with
 * the ev_q, we make sure that every uthread that was waiting on us wakes up.
 * The uthreads could be waiting on several evqs, so there could be multiple
 * independent wake-up attempts, hence the poke.  Likewise, the uthread could be
 * awake when we poke.  The uthread will check check_evqs after sleeping, in
 * case we poke before it blocks (and the poke fails).
 *
 * Also, there could be concurrent callers of this handler, and other uthreads
 * signing up for a wakeup. */
void evq_wakeup_handler(struct event_queue *ev_q)
{
	struct evq_wakeup_ctlr *ectlr = ev_q->ev_udata;
	struct evq_wait_link *i;
	assert(ectlr);
	spin_pdr_lock(&ectlr->lock);
	/* Note we wake up all sleepers, even though only one is likely to get the
	 * message.  See the notes in unlink_ectlr() for more info. */
	TAILQ_FOREACH(i, &ectlr->waiters, link_evq) {
		i->uth_ctlr->check_evqs = TRUE;
		cmb();	/* order check write before poke (poke has atomic) */
		poke(&i->uth_ctlr->poker, i->uth_ctlr);
	}
	spin_pdr_unlock(&ectlr->lock);
}

/* Helper, attaches a wakeup controller to the event queue. */
void evq_attach_wakeup_ctlr(struct event_queue *ev_q)
{
	struct evq_wakeup_ctlr *ectlr = malloc(sizeof(struct evq_wakeup_ctlr));
	memset(ectlr, 0, sizeof(struct evq_wakeup_ctlr));
	spin_pdr_init(&ectlr->lock);
	TAILQ_INIT(&ectlr->waiters);
	ev_q->ev_udata = ectlr;
	ev_q->ev_handler = evq_wakeup_handler;
}

void evq_remove_wakeup_ctlr(struct event_queue *ev_q)
{
	free(ev_q->ev_udata);
	ev_q->ev_udata = 0;
	ev_q->ev_handler = 0;
}

static void link_uctlr_ectlr(struct uth_sleep_ctlr *uctlr,
                             struct evq_wakeup_ctlr *ectlr,
                             struct evq_wait_link *link)
{
	/* No lock needed for the uctlr; we're the only one modifying evqs */
	link->uth_ctlr = uctlr;
	TAILQ_INSERT_HEAD(&uctlr->evqs, link, link_uth);
	/* Once we add ourselves to the ectrl list, we could start getting poked */
	link->evq_ctlr = ectlr;
	spin_pdr_lock(&ectlr->lock);
	TAILQ_INSERT_HEAD(&ectlr->waiters, link, link_evq);
	spin_pdr_unlock(&ectlr->lock);
}

/* Disconnects us from a wakeup controller.
 *
 * Our evq handlers wake up *all* uthreads that are waiting for activity
 * (broadcast).  It's a tradeoff.  If the list of uthreads is long, then it is
 * wasted effort.  An alternative is to wake up exactly one, with slightly
 * greater overheads.  In the exactly-one case, multiple handlers could wake
 * this uth up at once, but we can only extract one message.  If we do the
 * single wake up, then when we detach from an ectlr, we need to peak in the
 * mbox to see if it is not empty, and conditionally run its handler again, such
 * that no uthread sits on a ectlr that has activity/pending messages (in
 * essence, level triggered). */
static void unlink_ectlr(struct evq_wait_link *link)
{
	struct evq_wakeup_ctlr *ectlr = link->evq_ctlr;
	spin_pdr_lock(&ectlr->lock);
	TAILQ_REMOVE(&ectlr->waiters, link, link_evq);
	spin_pdr_unlock(&ectlr->lock);
}

/* Helper: polls all evqs once and extracts the first message available.  The
 * message is copied into ev_msg, and the evq with the activity is copied into
 * which_evq (if it is non-zero).  Returns TRUE on success. */
static bool extract_evqs_msg(struct event_queue *evqs[], size_t nr_evqs,
                             struct event_msg *ev_msg,
                             struct event_queue **which_evq)
{
	struct event_queue *evq_i;
	bool ret = FALSE;
	/* We need to have notifs disabled when extracting messages from some
	 * mboxes.  Many mboxes have some form of busy waiting between consumers
	 * (userspace).  If we're just a uthread, we could wind up on a runqueue
	 * somewhere while someone else spins, possibly in VC ctx. */
	uth_disable_notifs();
	for (int i = 0; i < nr_evqs; i++) {
		evq_i = evqs[i];
		if (extract_one_mbox_msg(evq_i->ev_mbox, ev_msg)) {
			if (which_evq)
				*which_evq = evq_i;
			ret = TRUE;
			break;
		}
	}
	uth_enable_notifs();
	return ret;
}

/* Yield callback */
static void __uth_blockon_evq_cb(struct uthread *uth, void *arg)
{
	struct uth_sleep_ctlr *uctlr = arg;
	uthread_has_blocked(uth, UTH_EXT_BLK_EVENTQ);
	cmb();	/* actually block before saying 'blocked' */
	uctlr->blocked = TRUE;	/* can be woken up now */
	wrmb();	/* write 'blocked' before read 'check_evqs' */
	/* If someone set check_evqs, we should wake up.  We're competing with other
	 * wakers via poke (we may have already woken up!). */
	if (uctlr->check_evqs)
		poke(&uctlr->poker, uctlr);
	/* Once we say we're blocked, we could be woken up (possibly by our poke
	 * here) and the uthread could run on another core.  Holding this lock
	 * prevents the uthread from quickly returning and freeing the memory of
	 * uctrl before we have a chance to check_evqs or poke. */
	spin_pdr_unlock(&uctlr->in_use);
}

/* Direct version, with *evqs[]. */
void uth_blockon_evqs_arr(struct event_msg *ev_msg,
                          struct event_queue **which_evq,
                          struct event_queue *evqs[], size_t nr_evqs)
{
	struct uth_sleep_ctlr uctlr;
	struct evq_wait_link linkage[nr_evqs];

	/* Catch user mistakes.  If they lack a handler, they didn't attach.  They
	 * are probably using our evq_wakeup_handler, but they might have their own
	 * wrapper function. */
	for (int i = 0; i < nr_evqs; i++)
		assert(evqs[i]->ev_handler);
	/* Check for activity on the evqs before going through the hassle of
	 * sleeping.  ("check, signal, check again" pattern). */
	if (extract_evqs_msg(evqs, nr_evqs, ev_msg, which_evq))
		return;
	uth_sleep_ctlr_init(&uctlr, current_uthread);
	memset(linkage, 0, sizeof(struct evq_wait_link) * nr_evqs);
	for (int i = 0; i < nr_evqs; i++)
		link_uctlr_ectlr(&uctlr, (struct evq_wakeup_ctlr*)evqs[i]->ev_udata,
		                 &linkage[i]);
	/* Mesa-style sleep until we get a message.  Mesa helps a bit here, since we
	 * can just deregister from them all when we're done.  o/w it is tempting to
	 * have us deregister from *the* one in the handler and extract the message
	 * there; which can be tricky and harder to reason about. */
	while (1) {
		/* We need to make sure only one 'version/ctx' of this thread is active
		 * at a time.  Later on, we'll unlock in vcore ctx on the other side of
		 * a yield.  We could restart from the yield, return, and free the uctlr
		 * before that ctx has a chance to finish. */
		spin_pdr_lock(&uctlr.in_use);
		/* We're signed up.  We might already have been told to check the evqs,
		 * or there could be messages still sitting in the evqs.  check_evqs is
		 * only ever cleared here, and only ever set in evq handlers. */
		uctlr.check_evqs = FALSE;
		cmb();	/* look for messages after clearing check_evqs */
		if (extract_evqs_msg(evqs, nr_evqs, ev_msg, which_evq))
			break;
		uthread_yield(TRUE, __uth_blockon_evq_cb, &uctlr);
	}
	/* On the one hand, it's not necessary to unlock, since the memory will be
	 * freed.  But we do need to go through the process to turn on notifs and
	 * adjust the notif_disabled_depth for the case where we don't yield. */
	spin_pdr_unlock(&uctlr.in_use);
	for (int i = 0; i < nr_evqs; i++)
		unlink_ectlr(&linkage[i]);
}

/* ... are event_queue *s, nr_evqs of them.  This will block until it can
 * extract some message from one of evqs.  The message will be placed in ev_msg,
 * and the particular evq it extracted it from will be placed in which_evq, if
 * which is non-zero. */
void uth_blockon_evqs(struct event_msg *ev_msg, struct event_queue **which_evq,
                      size_t nr_evqs, ...)
{
	struct event_queue *evqs[nr_evqs];
	va_list va;
	va_start(va, nr_evqs);
	for (int i = 0; i < nr_evqs; i++)
		evqs[i] = va_arg(va, struct event_queue *);
	va_end(va);
	uth_blockon_evqs_arr(ev_msg, which_evq, evqs, nr_evqs);
}

/* ... are event_queue *s, nr_evqs of them.  This will attempt to extract some
 * message from one of evqs.  The message will be placed in ev_msg, and the
 * particular evq it extracted it from will be placed in which_evq.  Returns
 * TRUE if it extracted a message. */
bool uth_check_evqs(struct event_msg *ev_msg, struct event_queue **which_evq,
                    size_t nr_evqs, ...)
{
	struct event_queue *evqs[nr_evqs];
	va_list va;
	va_start(va, nr_evqs);
	for (int i = 0; i < nr_evqs; i++)
		evqs[i] = va_arg(va, struct event_queue *);
	va_end(va);
	return extract_evqs_msg(evqs, nr_evqs, ev_msg, which_evq);
}
