96 lines
2.5 KiB
C
96 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
|