/*
  include/common/ticks.h
  Functions and macros for manipulation of expiration timers

  Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
  
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation, version 2.1
  exclusively.

  This library 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
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

/*
 * Using a mix of milliseconds and timeval for internal timers is expensive and
 * overkill, because we don't need such a precision to compute timeouts.
 * So we're converting them to "ticks".
 *
 * A tick is a representation of a date relative to another one, and is
 * measured in milliseconds. The natural usage is to represent an absolute date
 * relative to the current date. Since it is not practical to update all values
 * each time the current date changes, instead we use the absolute date rounded
 * down to fit in a tick. We then have to compare a tick to the current date to
 * know whether it is in the future or in the past. If a tick is below the
 * current date, it is in the past. If it is above, it is in the future. The
 * values will wrap so we can't compare that easily, instead we check the sign
 * of the difference between a tick and the current date.
 *
 * Proceeding like this allows us to manipulate dates that are stored in
 * scalars with enough precision and range. For this reason, we store ticks in
 * 32-bit integers. This is enough to handle dates that are between 24.85 days
 * in the past and as much in the future.
 * 
 * We must both support absolute dates (well in fact, dates relative to now+/-
 * 24 days), and intervals (for timeouts). Both types need an "eternity" magic
 * value. For optimal code generation, we'll use zero as the magic value
 * indicating that an expiration timer or a timeout is not set. We have to
 * check that we don't return this value when adding timeouts to <now>. If a
 * computation returns 0, we must increase it to 1 (which will push the timeout
 * 1 ms further). For this reason, timeouts must not be added by hand but via
 * the dedicated tick_add() function.
 */

#ifndef _COMMON_TICKS_H
#define _COMMON_TICKS_H

#include <haproxy/api.h>

#define TICK_ETERNITY   0

/* right now, ticks are milliseconds. Both negative ms and negative ticks
 * indicate eternity.
 */
#define MS_TO_TICKS(ms) (ms)
#define TICKS_TO_MS(tk) (tk)

/* return 1 if tick is set, otherwise 0 */
static inline int tick_isset(int expire)
{
	return expire != 0;
}

/* Add <timeout> to <now>, and return the resulting expiration date.
 * <timeout> will not be checked for null values.
 */
static inline int tick_add(int now, int timeout)
{
	now += timeout;
	if (unlikely(!now))
		now++;    /* unfortunate value */
	return now;
}

/* add <timeout> to <now> if it is set, otherwise set it to eternity.
 * Return the resulting expiration date.
 */
static inline int tick_add_ifset(int now, int timeout)
{
	if (!timeout)
		return TICK_ETERNITY;
	return tick_add(now, timeout);
}

/* return 1 if timer <t1> is before <t2>, none of which can be infinite. */
static inline int tick_is_lt(int t1, int t2)
{
	return (t1 - t2) < 0;
}

/* return 1 if timer <t1> is before or equal to <t2>, none of which can be infinite. */
static inline int tick_is_le(int t1, int t2)
{
	return (t1 - t2) <= 0;
}

/* return 1 if timer <timer> is expired at date <now>, otherwise zero */
static inline int tick_is_expired(int timer, int now)
{
	if (unlikely(!tick_isset(timer)))
		return 0;
	if (unlikely((timer - now) <= 0))
		return 1;
	return 0;
}

/* return the first one of the two timers, both of which may be infinite */
static inline int tick_first(int t1, int t2)
{
	if (!tick_isset(t1))
		return t2;
	if (!tick_isset(t2))
		return t1;
	if ((t1 - t2) <= 0)
		return t1;
	else
		return t2;
}

/* return the first one of the two timers, where only the first one may be infinite */
static inline int tick_first_2nz(int t1, int t2)
{
	if (!tick_isset(t1))
		return t2;
	if ((t1 - t2) <= 0)
		return t1;
	else
		return t2;
}

/* return the number of ticks remaining from <now> to <exp>, or zero if expired */
static inline int tick_remain(int now, int exp)
{
	if (tick_is_expired(exp, now))
		return 0;
	return exp - now;
}

#endif /* _COMMON_TICKS_H */

/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */
