/* Copyright (c) 2013 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * devalarm/#A: a device for registering per-process alarms.
 *
 * Allows a process to set up alarms, where the kernel will send an event to a
 * posted ev_q at a certain TSC time.
 *
 * Every process has their own alarm sets and view of #A; gen and friends look
 * at current's alarmset when it is time to gen or open a file.
 *
 * To use, first open #A/clone, and that gives you an alarm directory aN, where
 * N is ID of the alarm.  ctl takes two commands: "evq POINTER" (to tell the
 * kernel the pointer of your ev_q) and "cancel", to stop an alarm.  timer takes
 * just the value (in absolute tsc time) to fire the alarm.
 *
 * While each process has a separate view of #A, it is possible to post a chan
 * to Qctl or Qtimer to #s.  If another proc has your Qtimer, it can set it in
 * the past, thereby triggering an immediate event.  More clever than useful.
 *
 * Notes on refcnting (the trickier parts here):
 * - the proc_alarms have counted references to their proc
 * 		proc won't free til all alarms are closed, which is fine.  we close
 * 		all files in destroy.  if a proc drops a chan in srv, the proc will stay
 * 		alive because the alarm is alive - til that chan is closed (srvremove)
 *
 * 		other shady ways to keep a chan alive: cd to it!  if it is ., we'd
 * 		keep a ref around.  however, only alarmdir *file* grab refs, not
 * 		directories.
 *
 * - proc_alarms are kref'd, since there can be multiple chans per alarm
 * 		the only thing that keeps an alarm alive is a chan on a CTL or TIMER (or
 * 		other file).  when you cloned, you got back an open CTL, which keeps the
 * 		alarm (and the dir) alive.
 *
 * 		we need to be careful generating krefs, in case alarms are concurrently
 * 		released and removed from the lists.  just like with procs and pid2proc,
 * 		we need to sync with the source of the kref. */

#include <kmalloc.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <pmap.h>
#include <sys/queue.h>
#include <smp.h>
#include <kref.h>
#include <atomic.h>
#include <alarm.h>
#include <event.h>
#include <umem.h>
#include <devalarm.h>

/* qid path types */
#define Qtopdir					1
#define Qclone					2
#define Qalarmdir				3
#define Qctl					4
#define Qtimer					5	/* Qctl + 1 */

/* This paddr/kaddr is a bit dangerous.  it'll work so long as we don't need all
 * 64 bits for a physical address (48 is the current norm on x86_64). */
#define ADDR_SHIFT 5
#define QID2A(q) ((struct proc_alarm*)KADDR(((q).path >> ADDR_SHIFT)))
#define TYPE(q) ((q).path & ((1 << ADDR_SHIFT) - 1))
#define QID(ptr, type) ((PADDR(ptr) << ADDR_SHIFT) | type)
extern char *eve;

static void alarm_release(struct kref *kref)
{
	struct proc_alarm *a = container_of(kref, struct proc_alarm, kref);
	struct proc *p = a->proc;
	assert(p);
	spin_lock(&p->alarmset.lock);
	TAILQ_REMOVE(&p->alarmset.list, a, link);
	spin_unlock(&p->alarmset.lock);
	/* When this returns, the alarm has either fired or it never will */
	unset_alarm(p->alarmset.tchain, &a->a_waiter);
	proc_decref(p);
	kfree(a);
}

static void proc_alarm_handler(struct alarm_waiter *a_waiter)
{
	struct proc_alarm *a = container_of(a_waiter, struct proc_alarm, a_waiter);
	struct event_queue *ev_q = ACCESS_ONCE(a->ev_q);
	struct event_msg msg;
	if (!ev_q || !a->proc) {
		printk("[kernel] proc_alarm, bad ev_q %p or proc %p\n", ev_q, a->proc);
		return;
	}
	memset(&msg, 0, sizeof(struct event_msg));
	msg.ev_type = EV_ALARM;
	msg.ev_arg2 = a->id;
	send_event(a->proc, ev_q, &msg, 0);
}

void devalarm_init(struct proc *p)
{
	TAILQ_INIT(&p->alarmset.list);
	spinlock_init(&p->alarmset.lock);
	/* Just running all the proc alarms on core 0. */
	p->alarmset.tchain = &per_cpu_info[0].tchain;
	p->alarmset.id_counter = 0;
}

static int alarmgen(struct chan *c, char *entry_name,
					struct dirtab *unused, int unused_nr_dirtab,
					int s, struct dir *dp)
{
	struct qid q;
	struct proc_alarm *a_i;
	struct proc *p = current;
	/* Whether we're in one dir or at the top, .. still takes us to the top. */
	if (s == DEVDOTDOT) {
		mkqid(&q, Qtopdir, 0, QTDIR);
		devdir(c, q, "#A", 0, eve, 0555, dp);
		return 1;
	}
	switch (TYPE(c->qid)) {
		case Qtopdir:
			/* Generate elements for the top level dir.  We support a clone and
			 * alarm dirs at the top level */
			if (s == 0) {
				mkqid(&q, Qclone, 0, QTFILE);
				devdir(c, q, "clone", 0, eve, 0666, dp);
				return 1;
			}
			s--;	/* 1 -> 0th element, 2 -> 1st element, etc */
			/* Gets the s-th element (0 index)
			 * 
			 * I would like to take advantage of the state machine and our
			 * previous answer to get the sth element of the list.  We can get
			 * at our previous run of gen from dp (struct dir), and use that to
			 * get the next item.  I'd like to do something like:
			 *
			 * if (dp->qid.path >> ADDR_SHIFT)
			 *      a_i = TAILQ_NEXT(QID2A(dp->qid), link);
			 *
			 * Dev would give us a 0'd dp path on the first run, so if we have a
			 * path, we know we're on an iterative run.  However, the problem is
			 * that we could have lost the element dp refers to (QID2A(dp->qid))
			 * since our previous run, so we can't even access that memory to
			 * check for refcnts or anything.  We need a new model for how gen
			 * works (probably a gen_start and gen_stop devop, passed as
			 * parameters to devwalk), so that we can have some invariants
			 * between gen runs.
			 *
			 * Til then, we're stuck with arrays like in #I (though we can use
			 * Linux style fdsets) or lousy O(n^2) linked lists (like #s).
			 *
			 * Note that we won't always start a gen loop with s == 0
			 * (devdirread, for instance) */
			spin_lock(&p->alarmset.lock);
			TAILQ_FOREACH(a_i, &p->alarmset.list, link) {
				if (s-- == 0)
					break;
			}
			/* As soon as we unlock, someone could free a_i */
			if (!a_i) {
				spin_unlock(&p->alarmset.lock);
				return -1;
			}
			snprintf(get_cur_genbuf(), GENBUF_SZ, "a%d", a_i->id);
			mkqid(&q, QID(a_i, Qalarmdir), 0, QTDIR);
			devdir(c, q, get_cur_genbuf(), 0, eve, 0555, dp);
			spin_unlock(&p->alarmset.lock);
			return 1;
		case Qalarmdir:
			/* Gen the contents of the alarm dirs */
			s += Qctl;	/* first time through, start on Qctl */
			switch (s) {
				case Qctl:
					mkqid(&q, QID(QID2A(c->qid), Qctl), 0, QTFILE);
					devdir(c, q, "ctl", 0, eve, 0666, dp);
					return 1;
				case Qtimer:
					mkqid(&q, QID(QID2A(c->qid), Qtimer), 0, QTFILE);
					devdir(c, q, "timer", 0, eve, 0666, dp);
					return 1;
			}
			return -1;
			/* Need to also provide a direct hit for Qclone and all other files
			 * (at all levels of the hierarchy).  Every file is both generated
			 * (via the s increments in their respective directories) and
			 * directly gen-able.  devstat() will call gen with a specific path
			 * in the qid.  In these cases, we make a dir for whatever they are
			 * asking for.  Note the qid stays the same.  I think this is what
			 * the old plan9 comments above devgen were talking about for (ii).
			 *
			 * We don't need to do this for the directories - devstat will look
			 * for the a directory by path and fail.  Then it will manually
			 * build the stat output (check the -1 case in devstat). */
		case Qclone:
			devdir(c, c->qid, "clone", 0, eve, 0666, dp);
			return 1;
		case Qctl:
			devdir(c, c->qid, "ctl", 0, eve, 0666, dp);
			return 1;
		case Qtimer:
			devdir(c, c->qid, "timer", 0, eve, 0666, dp);
			return 1;
	}
	return -1;
}

static void alarminit(void)
{
}

static struct chan *alarmattach(char *spec)
{
	struct chan *c = devattach('A', spec);
	mkqid(&c->qid, Qtopdir, 0, QTDIR);
	return c;
}

static struct walkqid *alarmwalk(struct chan *c, struct chan *nc, char **name,
								 int nname)
{
	return devwalk(c, nc, name, nname, 0, 0, alarmgen);
}

static int alarmstat(struct chan *c, uint8_t * db, int n)
{
	return devstat(c, db, n, 0, 0, alarmgen);
}

/* It shouldn't matter if p = current is DYING.  We'll eventually fail to insert
 * the open chan into p's fd table, then decref the chan. */
static struct chan *alarmopen(struct chan *c, int omode)
{
	struct proc *p = current;
	struct proc_alarm *a, *a_i;
	switch (TYPE(c->qid)) {
		case Qtopdir:
		case Qalarmdir:
			if (omode & ORCLOSE)
				error(Eperm);
			if (!IS_RDONLY(omode))
				error(Eisdir);
			break;
		case Qclone:
			a = kzmalloc(sizeof(struct proc_alarm), KMALLOC_WAIT);
			kref_init(&a->kref, alarm_release, 1);
			init_awaiter(&a->a_waiter, proc_alarm_handler);
			spin_lock(&p->alarmset.lock);
			a->id = p->alarmset.id_counter++;
			proc_incref(p, 1);
			a->proc = p;
			TAILQ_INSERT_TAIL(&p->alarmset.list, a, link);
			spin_unlock(&p->alarmset.lock);
			mkqid(&c->qid, QID(a, Qctl), 0, QTFILE);
			break;
		case Qctl:
		case Qtimer:
			/* the purpose of opening is to hold a kref on the proc_alarm */
			a = QID2A(c->qid);
			assert(a);
			/* this isn't a valid pointer yet, since our chan doesn't have a
			 * ref.  since the time that walk gave our chan the qid, the chan
			 * could have been closed, and the alarm decref'd and freed.  the
			 * qid is essentially an uncounted reference, and we need to go to
			 * the source to attempt to get a real ref.  Unfortunately, this is
			 * another scan of the list, same as devsrv. */
			spin_lock(&p->alarmset.lock);
			TAILQ_FOREACH(a_i, &p->alarmset.list, link) {
				if (a_i == a) {
					assert(a->proc == current);
					/* it's still possible we're not getting the ref, racing
					 * with the release method */
					if (!kref_get_not_zero(&a->kref, 1)) {
						a_i = 0;	/* lost the race, will error out later */
					}
					break;
				}
			}
			spin_unlock(&p->alarmset.lock);
			if (!a_i)
				error("Unable to open alarm, concurrent closing");
			break;
	}
	c->mode = openmode(omode);
	/* Assumes c is unique (can't be closed concurrently */
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

static void alarmcreate(struct chan *c, char *name, int omode, uint32_t perm)
{
	error(Eperm);
}

static void alarmremove(struct chan *c)
{
	error(Eperm);
}

static int alarmwstat(struct chan *c, uint8_t * dp, int n)
{
	error("No alarmwstat");
	return 0;
}

static void alarmclose(struct chan *c)
{
	/* There are more closes than opens.  For instance, sysstat doesn't open,
	 * but it will close the chan it got from namec.  We only want to clean
	 * up/decref chans that were actually open. */
	if (!(c->flag & COPEN))
		return;
	switch (TYPE(c->qid)) {
		case Qctl:
		case Qtimer:
			kref_put(&QID2A(c->qid)->kref);
			break;
	}
}

static long alarmread(struct chan *c, void *ubuf, long n, int64_t offset)
{
	struct proc_alarm *p_alarm;
	switch (TYPE(c->qid)) {
		case Qtopdir:
		case Qalarmdir:
			return devdirread(c, ubuf, n, 0, 0, alarmgen);
		case Qctl:
			p_alarm = QID2A(c->qid);
			return readnum(offset, ubuf, n, p_alarm->id, NUMSIZE32);
		case Qtimer:
			p_alarm = QID2A(c->qid);
			return readnum(offset, ubuf, n, p_alarm->a_waiter.wake_up_time,
						   NUMSIZE64);
		default:
			panic("Bad QID %p in devalarm", c->qid.path);
	}
	return 0;
}

/* Note that in read and write we have an open chan, which means we have an
 * active kref on the p_alarm.  Also note that we make no assumptions about
 * current here - we find the proc (and the tchain) via the ref stored in the
 * proc_alarm. */
static long alarmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
{
	ERRSTACK(1);
	char buf[32];
	struct cmdbuf *cb;
	struct proc_alarm *p_alarm;
	uint64_t hexval;

	switch (TYPE(c->qid)) {
		case Qtopdir:
		case Qalarmdir:
			error(Eperm);
		case Qctl:
			p_alarm = QID2A(c->qid);
			cb = parsecmd(ubuf, n);
			if (waserror()) {
				kfree(cb);
				nexterror();
			}
			if (cb->nf < 1)
				error("short control request");
			if (!strcmp(cb->f[0], "evq")) {
				if (cb->nf < 2)
					error("evq needs a pointer");
				/* i think it's safe to do a stroul on a parsecmd.  it's kernel
				 * memory, and space or 0 terminated */
				hexval = strtoul(cb->f[1], 0, 16);
				/* This is just to help userspace - event code can handle it */
				if (!is_user_rwaddr((void *)hexval, sizeof(struct event_queue)))
					error("Non-user ev_q pointer");
				p_alarm->ev_q = (struct event_queue *)hexval;
			} else if (!strcmp(cb->f[0], "cancel")) {
				unset_alarm(p_alarm->proc->alarmset.tchain, &p_alarm->a_waiter);
			} else {
				error("%s: not implemented", cb->f[0]);
			}
			kfree(cb);
			poperror();
			break;
		case Qtimer:
			/* want to give strtoul a null-terminated buf (can't handle random
			 * user strings) */
			if (n >= sizeof(buf))
				error(Egreg);
			memcpy(buf, ubuf, n);
			buf[n] = 0;
			hexval = strtoul(buf, 0, 16);
			p_alarm = QID2A(c->qid);
			/* if you don't know if it was running or not, resetting will turn
			 * it on regardless. */
			reset_alarm_abs(p_alarm->proc->alarmset.tchain, &p_alarm->a_waiter,
							hexval);
			break;
		default:
			panic("Bad QID %p in devalarm", c->qid.path);
	}
	return n;
}

struct dev alarmdevtab __devtab = {
	'A',
	"alarm",

	devreset,
	alarminit,
	devshutdown,
	alarmattach,
	alarmwalk,
	alarmstat,
	alarmopen,
	alarmcreate,
	alarmclose,
	alarmread,
	devbread,
	alarmwrite,
	devbwrite,
	alarmremove,
	alarmwstat,
	devpower,
	//devconfig,
	devchaninfo,
};
