/*
 * 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))])

struct st_timer_data {
	spinlock_t	 stt_lock;
	/* start time of the slot processed previously */
	cfs_time_t       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, cfs_time_current_sec()));

	/* 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 */
int
stt_expire_list(struct list_head *slot, cfs_time_t 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;
}

int
stt_check_timers(cfs_time_t *last)
{
	int	expired = 0;
	cfs_time_t now;
	cfs_time_t this_slot;

	now = cfs_time_current_sec();
	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;
}


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;
}

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 = cfs_time_current_sec() & 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);
}
