📄 sfifo.c
字号:
/* SFIFO 1.3 Simple portable lock-free FIFO (c) 2000-2002, David Olofson - free software under the terms of the LGPL 2.1*//*-----------------------------------------------------------TODO: * Is there a way to avoid losing one byte of buffer space to avoid extra variables or locking? * Test more compilers and environments.----------------------------------------------------------- */#include <string.h>#include <stdlib.h>#include "sfifo.h"#define free(x, y) free(x)#define DBG(x)/* * Alloc buffer, init FIFO etc... */int sfifo_init(sfifo_t *f, int size){ memset(f, 0, sizeof(sfifo_t)); if(size > SFIFO_MAX_BUFFER_SIZE) return -EINVAL; /* * Set sufficient power-of-2 size. * * No, there's no bug. If you need * room for N bytes, the buffer must * be at least N+1 bytes. (The fifo * can't tell 'empty' from 'full' * without unsafe index manipulations * otherwise.) */ f->size = 1; for(; f->size <= size; f->size <<= 1) ; /* Get buffer */ if( 0 == (f->buffer = (void *)malloc(f->size)) ) return -ENOMEM; return 0;}/* * Dealloc buffer etc... */void sfifo_close(sfifo_t *f){ if(f->buffer) free(f->buffer, f->size);}/* * Empty FIFO buffer */void sfifo_flush(sfifo_t *f){ /* Reset positions */ f->readpos = 0; f->writepos = 0;}/* * Write bytes to a FIFO * Return number of bytes written, or an error code */int sfifo_write(sfifo_t *f, const void *_buf, int len){ int total; int i; const char *buf = (const char *)_buf; if(!f->buffer) return -ENODEV; /* No buffer! */ /* total = len = min(space, len) */ total = sfifo_space(f); DBG(printf("sfifo_space() = %d\n",total)); if(len > total) len = total; else total = len; i = f->writepos; if(i + len > f->size) { memcpy(f->buffer + i, buf, f->size - i); buf += f->size - i; len -= f->size - i; i = 0; } memcpy(f->buffer + i, buf, len); f->writepos = i + len; return total;}/* * Read bytes from a FIFO * Return number of bytes read, or an error code */int sfifo_read(sfifo_t *f, void *_buf, int len){ int total; int i; char *buf = (char *)_buf; if(!f->buffer) return -ENODEV; /* No buffer! */ /* total = len = min(used, len) */ total = sfifo_used(f); DBG(printf("sfifo_used() = %d\n",total)); if(len > total) len = total; else total = len; i = f->readpos; if(i + len > f->size) { memcpy(buf, f->buffer + i, f->size - i); buf += f->size - i; len -= f->size - i; i = 0; } memcpy(buf, f->buffer + i, len); f->readpos = i + len; return total;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -