Blame src/libout123/sfifo.h

Packit c32a2d
/*
Packit c32a2d
	SFIFO 1.3 Simple portable lock-free FIFO
Packit c32a2d
Packit c32a2d
	(c) 2000-2002, David Olofson - free software under the terms of the LGPL 2.1
Packit c32a2d
*/
Packit c32a2d
Packit c32a2d
Packit c32a2d
/*
Packit c32a2d
 * Platform support:
Packit c32a2d
 *	gcc / Linux / x86:		Works
Packit c32a2d
 *	gcc / Linux / x86 kernel:	Works
Packit c32a2d
 *	gcc / FreeBSD / x86:		Works
Packit c32a2d
 *	gcc / NetBSD / x86:		Works
Packit c32a2d
 *	gcc / Mac OS X / PPC:		Works
Packit c32a2d
 *	gcc / Win32 / x86:		Works
Packit c32a2d
 *	Borland C++ / DOS / x86RM:	Works
Packit c32a2d
 *	Borland C++ / Win32 / x86PM16:	Untested
Packit c32a2d
 *	? / Various Un*ces / ?:		Untested
Packit c32a2d
 *	? / Mac OS / PPC:		Untested
Packit c32a2d
 *	gcc / BeOS / x86:		Untested
Packit c32a2d
 *	gcc / BeOS / PPC:		Untested
Packit c32a2d
 *	? / ? / Alpha:			Untested
Packit c32a2d
 *
Packit c32a2d
 * 1.2: Max buffer size halved, to avoid problems with
Packit c32a2d
 *	the sign bit...
Packit c32a2d
 *
Packit c32a2d
 * 1.3:	Critical buffer allocation bug fixed! For certain
Packit c32a2d
 *	requested buffer sizes, older version would
Packit c32a2d
 *	allocate a buffer of insufficient size, which
Packit c32a2d
 *	would result in memory thrashing. (Amazing that
Packit c32a2d
 *	I've manage to use this to the extent I have
Packit c32a2d
 *	without running into this... *heh*)
Packit c32a2d
 */
Packit c32a2d
Packit c32a2d
#ifndef	_SFIFO_H_
Packit c32a2d
#define	_SFIFO_H_
Packit c32a2d
Packit c32a2d
#ifdef __cplusplus
Packit c32a2d
extern "C" {
Packit c32a2d
#endif
Packit c32a2d
Packit c32a2d
#include <errno.h>
Packit c32a2d
Packit c32a2d
/* Defining SFIFO_STATIC and then including the sfifo.c will result in local code. */
Packit c32a2d
#ifdef SFIFO_STATIC
Packit c32a2d
#define SFIFO_SCOPE static
Packit c32a2d
#else
Packit c32a2d
#define SFIFO_SCOPE
Packit c32a2d
#endif
Packit c32a2d
Packit c32a2d
/*------------------------------------------------
Packit c32a2d
	"Private" stuff
Packit c32a2d
------------------------------------------------*/
Packit c32a2d
/*
Packit c32a2d
 * Porting note:
Packit c32a2d
 *	Reads and writes of a variable of this type in memory
Packit c32a2d
 *	must be *atomic*! 'int' is *not* atomic on all platforms.
Packit c32a2d
 *	A safe type should be used, and  sfifo should limit the
Packit c32a2d
 *	maximum buffer size accordingly.
Packit c32a2d
 */
Packit c32a2d
typedef int sfifo_atomic_t;
Packit c32a2d
#ifdef __TURBOC__
Packit c32a2d
#	define	SFIFO_MAX_BUFFER_SIZE	0x7fff
Packit c32a2d
#else /* Kludge: Assume 32 bit platform */
Packit c32a2d
#	define	SFIFO_MAX_BUFFER_SIZE	0x7fffffff
Packit c32a2d
#endif
Packit c32a2d
Packit c32a2d
typedef struct sfifo_t
Packit c32a2d
{
Packit c32a2d
	char *buffer;
Packit c32a2d
	int size;			/* Number of bytes */
Packit c32a2d
	sfifo_atomic_t readpos;		/* Read position */
Packit c32a2d
	sfifo_atomic_t writepos;	/* Write position */
Packit c32a2d
} sfifo_t;
Packit c32a2d
Packit c32a2d
#define SFIFO_SIZEMASK(x)	((x)->size - 1)
Packit c32a2d
Packit c32a2d
Packit c32a2d
/*------------------------------------------------
Packit c32a2d
	API
Packit c32a2d
------------------------------------------------*/
Packit c32a2d
SFIFO_SCOPE int sfifo_init(sfifo_t *f, int size);
Packit c32a2d
SFIFO_SCOPE void sfifo_close(sfifo_t *f);
Packit c32a2d
SFIFO_SCOPE void sfifo_flush(sfifo_t *f);
Packit c32a2d
SFIFO_SCOPE int sfifo_write(sfifo_t *f, const void *buf, int len);
Packit c32a2d
SFIFO_SCOPE int sfifo_read(sfifo_t *f, void *buf, int len);
Packit c32a2d
#define sfifo_used(x)	(((x)->writepos - (x)->readpos) & SFIFO_SIZEMASK(x))
Packit c32a2d
#define sfifo_space(x)	((x)->size - 1 - sfifo_used(x))
Packit c32a2d
#define sfifo_size(x)	((x)->size - 1)
Packit c32a2d
Packit c32a2d
Packit c32a2d
#ifdef __cplusplus
Packit c32a2d
};
Packit c32a2d
#endif
Packit c32a2d
#endif