/* 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 /* 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