/* gsm_timer.cpp
 *
 * Copyright (C) 2012 Ivan Klyuchnikov
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * 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 for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 
/* These store the amount of frame number that we wait until next timer expires. */
static int nearest;
static int *nearest_p;

/*! \addtogroup gsm_timer
 *  @{
 */

/*! \file gsm_timer.cpp
 */

#include <assert.h>
#include <string.h>
#include <limits.h>
#include <gsm_timer.h>
#include <pcu_l1_if.h>
#include <bts.h>


static struct rb_root timer_root = RB_ROOT;

/*
 * TODO: make this depend on the BTS. This means that
 * all time functions schedule based on the BTS they
 * are scheduled on.
 */
static int get_current_fn()
{
	return BTS::main_bts()->current_frame_number();
}

static void __add_gsm_timer(struct osmo_gsm_timer_list *timer)
{
	struct rb_node **new_node = &(timer_root.rb_node);
	struct rb_node *parent = NULL;

	while (*new_node) {
		struct osmo_gsm_timer_list *this_timer;

		this_timer = container_of(*new_node, struct osmo_gsm_timer_list, node);

		parent = *new_node;
		if (timer->fn < this_timer->fn)
			new_node = &((*new_node)->rb_left);
		else
			new_node = &((*new_node)->rb_right);
		}

		rb_link_node(&timer->node, parent, new_node);
		rb_insert_color(&timer->node, &timer_root);
}

/*! \brief add a new timer to the timer management
 *  \param[in] timer the timer that should be added
 */
void osmo_gsm_timer_add(struct osmo_gsm_timer_list *timer)
{
	osmo_gsm_timer_del(timer);
	timer->active = 1;
	INIT_LLIST_HEAD(&timer->list);
	__add_gsm_timer(timer);
}

/*! \brief schedule a gsm timer at a given future relative time
 *  \param[in] timer the to-be-added timer
 *  \param[in] number of frames from now
 *
 * This function can be used to (re-)schedule a given timer at a
 * specified number of frames in the future.  It will
 * internally add it to the timer management data structures, thus
 * osmo_timer_add() is automatically called.
 */
void
osmo_gsm_timer_schedule(struct osmo_gsm_timer_list *timer, int fn)
{
	int current_fn;

	current_fn = get_current_fn();
	timer->fn = current_fn + fn;
	osmo_gsm_timer_add(timer);
}

/*! \brief delete a gsm timer from timer management
 *  \param[in] timer the to-be-deleted timer
 *
 * This function can be used to delete a previously added/scheduled
 * timer from the timer management code.
 */
void osmo_gsm_timer_del(struct osmo_gsm_timer_list *timer)
{
	if (timer->active) {
		timer->active = 0;
		rb_erase(&timer->node, &timer_root);
		/* make sure this is not already scheduled for removal. */
		if (!llist_empty(&timer->list))
			llist_del_init(&timer->list);
	}
}

/*! \brief check if given timer is still pending
 *  \param[in] timer the to-be-checked timer
 *  \return 1 if pending, 0 otherwise
 *
 * This function can be used to determine whether a given timer
 * has alredy expired (returns 0) or is still pending (returns 1)
 */
int osmo_gsm_timer_pending(struct osmo_gsm_timer_list *timer)
{
	return timer->active;
}

/*
 * if we have a nearest frame number return the delta between the current
 * FN and the FN of the nearest timer.
 * If the nearest timer timed out return NULL and then we will
 * dispatch everything after the select
 */
int *osmo_gsm_timers_nearest(void)
{
	/* nearest_p is exactly what we need already: NULL if nothing is
	 * waiting, {0,0} if we must dispatch immediately, and the correct
	 * delay if we need to wait */
	return nearest_p;
}

static void update_nearest(int *cand, int *current)
{
	if (*cand != LONG_MAX) {
		if (*cand > *current)
			nearest = *cand - *current;
		else {
			/* loop again inmediately */
			nearest = 0;
		}
		nearest_p = &nearest;
	} else {
		nearest_p = NULL;
	}
}

/*
 * Find the nearest FN and update s_nearest_time
 */
void osmo_gsm_timers_prepare(void)
{
	struct rb_node *node;
	int current_fn;

	current_fn = get_current_fn();

	node = rb_first(&timer_root);
	if (node) {
		struct osmo_gsm_timer_list *this_timer;
		this_timer = container_of(node, struct osmo_gsm_timer_list, node);
		update_nearest(&this_timer->fn, &current_fn);
	} else {
		nearest_p = NULL;
	}
}

/*
 * fire all timers... and remove them
 */
int osmo_gsm_timers_update(void)
{
	int current_fn;
	struct rb_node *node;
	struct llist_head timer_eviction_list;
	struct osmo_gsm_timer_list *this_timer;
	int work = 0;

	current_fn = get_current_fn();

	INIT_LLIST_HEAD(&timer_eviction_list);
	for (node = rb_first(&timer_root); node; node = rb_next(node)) {
		this_timer = container_of(node, struct osmo_gsm_timer_list, node);

		if (this_timer->fn > current_fn)
			break;

		llist_add(&this_timer->list, &timer_eviction_list);
	}

	/*
	 * The callbacks might mess with our list and in this case
	 * even llist_for_each_entry_safe is not safe to use. To allow
	 * osmo_gsm_timer_del to be called from within the callback we need
	 * to restart the iteration for each element scheduled for removal.
	 *
	 * The problematic scenario is the following: Given two timers A
	 * and B that have expired at the same time. Thus, they are both
	 * in the eviction list in this order: A, then B. If we remove
	 * timer B from the A's callback, we continue with B in the next
	 * iteration step, leading to an access-after-release.
	 */
restart:
	llist_for_each_entry(this_timer, &timer_eviction_list, list) {
		osmo_gsm_timer_del(this_timer);
		this_timer->cb(this_timer->data);
		work = 1;
		goto restart;
	}

	return work;
}

int osmo_gsm_timers_check(void)
{
	struct rb_node *node;
	int i = 0;

	for (node = rb_first(&timer_root); node; node = rb_next(node)) {
		i++;
	}
	return i;
}

/*! }@ */

