/*
 * Copyright (c) 2002-2004 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 *
 *	$Id: fxszq.h,v 1.9 2005/06/16 00:09:34 ca Exp $
 */

#ifndef SM_FXSZQ_H
#define SM_FXSZQ_H 1

#include "sm/generic.h"

/*
**  This file defines some macros to deal with
**	fixed size queues
**  with the following structure:

uint		 fsq_max;	* allocated size
uint		 fsq_cur;	* currently used (basically last - first)
uint		 fsq_first;	* first index to read
uint		 fsq_last;	* last index to read (first to write)
void		*fsq_array;	* array of open transaction

*/

#define FSQ_INIT(size, fsq_max, fsq_cur, fsq_first, fsq_last)	\
	do				\
	{				\
		(fsq_max) = (size);	\
		(fsq_cur) = 0;		\
		(fsq_first) = 0;	\
		(fsq_last) = 0;		\
	} while (0)

#define FSQ_IS_EMPTY(fsq_cur) ((fsq_cur) == 0)
#define FSQ_IS_FULL(fsq_max, fsq_cur) ((fsq_max) <= (fsq_cur))

/* must be only called if !FSQ_IS_FULL() */
#define FSQ_APPEND(fsq_max, fsq_last, fsq_cur, fsq_array, elem)	\
	do							\
	{							\
		SM_ASSERT(!FSQ_IS_FULL(fsq_max, fsq_cur));	\
		(fsq_array)[fsq_last] = (elem);			\
		(fsq_last) = ((fsq_last) + 1) % (fsq_max);	\
		(fsq_cur)++;					\
	} while (0)

/* must be only called if !FSQ_IS_EMPTY(), i is an available var */
#define FSQ_GET(fsq_max, fsq_first, fsq_cur, fsq_array, i)	\
	(							\
		SM_ASSERT(!FSQ_IS_EMPTY(fsq_cur)),		\
		i = (fsq_first),				\
		(fsq_cur)--,					\
		(fsq_first) = ((fsq_first) + 1) % (fsq_max),	\
		(fsq_array)[i]					\
	)

#endif /* ! SM_FXSZQ_H */


syntax highlighted by Code2HTML, v. 0.9.1