1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
/*
------------------------------------------------------------
SFIFO 1.3
------------------------------------------------------------
* Simple portable lock-free FIFO
* (c) 2000-2002, David Olofson
* Released under the GNU LESSER GENERAL PUBLIC LICENSE Version 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>
/*------------------------------------------------
"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
------------------------------------------------*/
int sfifo_init(sfifo_t *f, int size);
void sfifo_close(sfifo_t *f);
void sfifo_flush(sfifo_t *f);
int sfifo_write(sfifo_t *f, const void *buf, int len);
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))
/*------------------------------------------------
Linux kernel space interface
------------------------------------------------*/
#ifdef __KERNEL__
int sfifo_write_user(sfifo_t *f, const void *buf, int len);
int sfifo_read_user(sfifo_t *f, void *buf, int len);
#else
# define sfifo_write_user sfifo_write
# define sfifo_read_user sfifo_read
#endif
#ifdef __cplusplus
};
#endif
#endif
|