kobodl/sound/sfifo.h
Ville Lindholm dbc223eb84
Initial commit
Import existing source tree; original VCS history is no longer available.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-28 16:35:31 +03:00

111 lines
3.1 KiB
C

/*
------------------------------------------------------------
SFIFO 1.4
------------------------------------------------------------
* Simple portable lock-free FIFO
* (c) 2000-2002, David Olofson
*
* 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
* gcc / BeOS / x86: Works
* gcc / BeOS / PPC: Works
* ? / Solaris / x86 Works
* ? / Solaris / SPARC Works
* ? / AmigaOS / PPC Works
* Borland C++ / Win32 / x86PM16: Untested
* ? / Various Un*ces / ?: Untested
* ? / Mac OS Classic / PPC: Untested
* ? / ? / Alpha: Untested
* ? / ? / MIPS: 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*)
*
* 1.4: Trying to make sfifo more robust, and easier to
* use. It's now safe to close an sfifo more than
* once. I've also changed some arguments and
* variables to unsigned, to prevent signed input
* from causing things to blow up. free/malloc
* wrappers renamed _sf_free/_sf_malloc, to avoid
* confusion and macro collisions.
*
*/
#ifndef _SFIFO_H_
#define _SFIFO_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <errno.h>
/*------------------------------------------------
"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;
unsigned 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
------------------------------------------------*/
int sfifo_init(sfifo_t *f, unsigned size);
void sfifo_close(sfifo_t *f);
void sfifo_flush(sfifo_t *f);
int sfifo_write(sfifo_t *f, const void *buf, unsigned len);
int sfifo_read(sfifo_t *f, void *buf, unsigned len);
#define sfifo_used(x) (((x)->writepos - (x)->readpos) & SFIFO_SIZEMASK(x))
#define sfifo_space(x) ((x)->size - 1 - sfifo_used(x))
/*------------------------------------------------
Linux kernel space interface
------------------------------------------------*/
#ifdef __KERNEL__
int sfifo_write_user(sfifo_t *f, const void *buf, unsigned len);
int sfifo_read_user(sfifo_t *f, void *buf, unsigned len);
#else
# define sfifo_write_user sfifo_write
# define sfifo_read_user sfifo_read
#endif
#ifdef __cplusplus
};
#endif
#endif