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>
111 lines
3.1 KiB
C
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
|