/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lnet/selftest/timer.c
 *
 * Author: Isaac Huang <isaac@clusterfs.com>
 */

#define DEBUG_SUBSYSTEM S_LNET

#include "selftest.h"


/*
 * Timers are implemented as a sorted queue of expiry times. The queue
 * is slotted, with each slot holding timers which expire in a
 * 2**STTIMER_MINPOLL (8) second period. The timers in each slot are
 * sorted by increasing expiry time. The number of slots is 2**7 (128),
 * to cover a time period of 1024 seconds into the future before wrapping.
 */
#define STTIMER_MINPOLL	3   /* log2 min poll interval (8 s) */
#define STTIMER_SLOTTIME       (1 << STTIMER_MINPOLL)
#define STTIMER_SLOTTIMEMASK   (~(STTIMER_SLOTTIME - 1))
#define STTIMER_NSLOTS	       (1 << 7)
#define STTIMER_SLOT(t)	       (&stt_data.stt_hash[(((t) >> STTIMER_MINPOLL) & \
						    (STTIMER_NSLOTS - 1))])

static struct st_timer_data {
	spinlock_t	 stt_lock;
	/* start time of the slot processed previously */
	unsigned long       stt_prev_slot;
	struct list_head       stt_hash[STTIMER_NSLOTS];
	int	      stt_shuttingdown;
	wait_queue_head_t      stt_waitq;
	int	      stt_nthreads;
} stt_data;

void
stt_add_timer(stt_timer_t *timer)
{
	struct list_head *pos;

	spin_lock(&stt_data.stt_lock);

	LASSERT(stt_data.stt_nthreads > 0);
	LASSERT(!stt_data.stt_shuttingdown);
	LASSERT(timer->stt_func != NULL);
	LASSERT(list_empty(&timer->stt_list));
	LASSERT(cfs_time_after(timer->stt_expires, get_seconds()));

	/* a simple insertion sort */
	list_for_each_prev(pos, STTIMER_SLOT(timer->stt_expires)) {
		stt_timer_t *old = list_entry(pos, stt_timer_t, stt_list);

		if (cfs_time_aftereq(timer->stt_expires, old->stt_expires))
			break;
	}
	list_add(&timer->stt_list, pos);

	spin_unlock(&stt_data.stt_lock);
}

/*
 * The function returns whether it has deactivated a pending timer or not.
 * (ie. del_timer() of an inactive timer returns 0, del_timer() of an
 * active timer returns 1.)
 *
 * CAVEAT EMPTOR:
 * When 0 is returned, it is possible that timer->stt_func _is_ running on
 * another CPU.
 */
int
stt_del_timer(stt_timer_t *timer)
{
	int ret = 0;

	spin_lock(&stt_data.stt_lock);

	LASSERT(stt_data.stt_nthreads > 0);
	LASSERT(!stt_data.stt_shuttingdown);

	if (!list_empty(&timer->stt_list)) {
		ret = 1;
		list_del_init(&timer->stt_list);
	}

	spin_unlock(&stt_data.stt_lock);
	return ret;
}

/* called with stt_data.stt_lock held */
static int
stt_expire_list(struct list_head *slot, unsigned long now)
{
	int	  expired = 0;
	stt_timer_t *timer;

	while (!list_empty(slot)) {
		timer = list_entry(slot->next, stt_timer_t, stt_list);

		if (cfs_time_after(timer->stt_expires, now))
			break;

		list_del_init(&timer->stt_list);
		spin_unlock(&stt_data.stt_lock);

		expired++;
		(*timer->stt_func) (timer->stt_data);

		spin_lock(&stt_data.stt_lock);
	}

	return expired;
}

static int
stt_check_timers(unsigned long *last)
{
	int	expired = 0;
	unsigned long now;
	unsigned long this_slot;

	now = get_seconds();
	this_slot = now & STTIMER_SLOTTIMEMASK;

	spin_lock(&stt_data.stt_lock);

	while (cfs_time_aftereq(this_slot, *last)) {
		expired += stt_expire_list(STTIMER_SLOT(this_slot), now);
		this_slot = cfs_time_sub(this_slot, STTIMER_SLOTTIME);
	}

	*last = now & STTIMER_SLOTTIMEMASK;
	spin_unlock(&stt_data.stt_lock);
	return expired;
}


static int
stt_timer_main(void *arg)
{
	cfs_block_allsigs();

	while (!stt_data.stt_shuttingdown) {
		stt_check_timers(&stt_data.stt_prev_slot);

		wait_event_timeout(stt_data.stt_waitq,
				   stt_data.stt_shuttingdown,
				   cfs_time_seconds(STTIMER_SLOTTIME));
	}

	spin_lock(&stt_data.stt_lock);
	stt_data.stt_nthreads--;
	spin_unlock(&stt_data.stt_lock);
	return 0;
}

static int
stt_start_timer_thread(void)
{
	struct task_struct *task;

	LASSERT(!stt_data.stt_shuttingdown);

	task = kthread_run(stt_timer_main, NULL, "st_timer");
	if (IS_ERR(task))
		return PTR_ERR(task);

	spin_lock(&stt_data.stt_lock);
	stt_data.stt_nthreads++;
	spin_unlock(&stt_data.stt_lock);
	return 0;
}


int
stt_startup(void)
{
	int rc = 0;
	int i;

	stt_data.stt_shuttingdown = 0;
	stt_data.stt_prev_slot = get_seconds() & STTIMER_SLOTTIMEMASK;

	spin_lock_init(&stt_data.stt_lock);
	for (i = 0; i < STTIMER_NSLOTS; i++)
		INIT_LIST_HEAD(&stt_data.stt_hash[i]);

	stt_data.stt_nthreads = 0;
	init_waitqueue_head(&stt_data.stt_waitq);
	rc = stt_start_timer_thread();
	if (rc != 0)
		CERROR("Can't spawn timer thread: %d\n", rc);

	return rc;
}

void
stt_shutdown(void)
{
	int i;

	spin_lock(&stt_data.stt_lock);

	for (i = 0; i < STTIMER_NSLOTS; i++)
		LASSERT(list_empty(&stt_data.stt_hash[i]));

	stt_data.stt_shuttingdown = 1;

	wake_up(&stt_data.stt_waitq);
	lst_wait_until(stt_data.stt_nthreads == 0, stt_data.stt_lock,
		       "waiting for %d threads to terminate\n",
		       stt_data.stt_nthreads);

	spin_unlock(&stt_data.stt_lock);
}
