/*
 * 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)
{
	int rc = 0;
	UNUSED(arg);

	SET_BUT_UNUSED(rc);

	cfs_block_allsigs();

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

		rc = 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)
{
	task_t *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);
}
