looper/subprojects/mpg123/src/libout123/sfifo.h
2024-09-28 10:31:18 -07:00

95 lines
2.5 KiB
C

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