博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
kfifo 用户空间实现
阅读量:4055 次
发布时间:2019-05-25

本文共 6059 字,大约阅读时间需要 20 分钟。

按照linux内核对kfifo的实现,修改成用户空间的kfifo,kfifo是一个循环存储队列,队列是一个大块内存,通过in和out指针管理进和出队列。比较适合大小固定的数据存储。这里的实现没有加锁机制!内核kfifo原理,参考

kfifo头文件。

#ifndef _Linux_KFIFO_H#define _Linux_KFIFO_H#define __u32 unsigned long#define __u64 unsigned long long#define min(x,y) ((x) < (y) ? (x) : (y) )#define max(x,y) ((x) > (y) ? (x) : (y) )/*static inline int fls(int x){    int r;    __asm__("bsrl %1,%0nt"            "jnz 1fnt"            "movl $-1,%0n"            "1:" : "=r" (r) : "rm" (x));    return r+1;}*/static inline int fls(int x){    int r = 32;     if (!x)        return 0;    if (!(x & 0xffff0000u)) {        x <<= 16;         r -= 16;     }       if (!(x & 0xff000000u)) {        x <<= 8;        r -= 8;    }       if (!(x & 0xf0000000u)) {        x <<= 4;        r -= 4;    }       if (!(x & 0xc0000000u)) {        x <<= 2;        r -= 2;    }       if (!(x & 0x80000000u)) {        x <<= 1;        r -= 1;    }       return r;}static inline int fls64(__u64 x){    __u32 h = x >> 32;    if (h)        return fls(h) + 32;    return fls(x);}static inline unsigned fls_long(unsigned long l){    if (sizeof(l) == 4)        return fls(l);    return fls64(l);}static inline unsigned long roundup_pow_of_two(unsigned long x){    return 1UL << fls_long(x - 1);}struct kfifo {    unsigned char *buffer;    /* the buffer holding the data */    unsigned int size;    /* the size of the allocated buffer */    unsigned int in;    /* data is added at offset (in % size) */    unsigned int out;    /* data is extracted from off. (out % size) */};struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size);struct kfifo *kfifo_alloc(unsigned int size);void kfifo_free(struct kfifo *fifo);unsigned int __kfifo_put(struct kfifo *fifo, unsigned char *buffer, unsigned int len);unsigned int __kfifo_get(struct kfifo *fifo, unsigned char *buffer, unsigned int len);static inline void __kfifo_reset(struct kfifo *fifo){    fifo->in = fifo->out = 0;}static inline void kfifo_reset(struct kfifo *fifo){    __kfifo_reset(fifo);}static inline unsigned int kfifo_put(struct kfifo *fifo,                     unsigned char *buffer, unsigned int len){    unsigned int ret;    ret = __kfifo_put(fifo, buffer, len);    return ret;}static inline unsigned int kfifo_get(struct kfifo *fifo,                     unsigned char *buffer, unsigned int len){    unsigned int ret;    ret = __kfifo_get(fifo, buffer, len);    if (fifo->in == fifo->out)        fifo->in = fifo->out = 0;    return ret;}static inline unsigned int __kfifo_len(struct kfifo *fifo){    return fifo->in - fifo->out;}static inline unsigned int kfifo_len(struct kfifo *fifo){    unsigned int ret;    ret = __kfifo_len(fifo);    return ret;}#endif
kfifo实现

#include "kfifo.h"#include 
#include
#include
struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size){ struct kfifo *fifo; fifo = (struct kfifo *)malloc(sizeof(struct kfifo)); if (!fifo) return NULL; fifo->buffer = buffer; fifo->size = size; fifo->in = fifo->out = 0; return fifo;}struct kfifo *kfifo_alloc(unsigned int size){ unsigned char *buffer; struct kfifo *ret; if (size & (size - 1)) { fprintf(stderr,"size > 0x80000000n"); size = roundup_pow_of_two(size); } buffer = (unsigned char *)malloc(size); if (!buffer) return NULL; ret = kfifo_init(buffer, size); if ((unsigned long)ret <= 0) { free(buffer); } return ret;}void kfifo_free(struct kfifo *fifo){ free(fifo->buffer); free(fifo);}unsigned int __kfifo_put(struct kfifo *fifo, unsigned char *buffer, unsigned int len){ unsigned int l; len = min(len, fifo->size - fifo->in + fifo->out); l = min(len, fifo->size - (fifo->in & (fifo->size - 1))); memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l); memcpy(fifo->buffer, buffer + l, len - l); fifo->in += len; return len;}unsigned int __kfifo_get(struct kfifo *fifo, unsigned char *buffer, unsigned int len){ unsigned int l; len = min(len, fifo->in - fifo->out); l = min(len, fifo->size - (fifo->out & (fifo->size - 1))); memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l); fifo->out += len; return len;}
kfifo测试(来自网友的代码)
#define FIFO_LENGTH 4096#include 
#include
#include
#include
#include "kfifo.h"struct ll_param{ struct kfifo * fifo; int msg_len;};static struct ll_param fifo;void thread_reader(void * param){ int read_len=0; unsigned int counter=0; unsigned char buffer[FIFO_LENGTH]; struct ll_param * p=(struct ll_param *)param; printf("nnn = %d\n", roundup_pow_of_two(5)); for(;;) { bzero(buffer, FIFO_LENGTH); read_len=kfifo_get(p->fifo, buffer, 25); if(read_len !=0 ) { printf("Read len:%d, buffer is :< %s >n\n", read_len, buffer); } else { counter++; } if(counter > 20) { break; } usleep(50000); }}void thread_writer(void * param){ unsigned int write_len = 0; unsigned int counter = 0; unsigned char buffer[32]; struct ll_param * p = (struct ll_param *)param; for(counter = 0; counter < 100; counter++) { bzero(buffer,32); sprintf((char *)buffer, "This is %d message.n", counter); write_len=kfifo_put(p->fifo, buffer, 25); //strlen((char *)buffer) usleep(100); }}int main(void){ pthread_t pidr; pthread_t pidw; fifo.msg_len = 10; fifo.fifo = kfifo_alloc(FIFO_LENGTH); pthread_create(&pidw, NULL, (void *)thread_writer, &fifo); pthread_create(&pidr, NULL, (void *)thread_reader, &fifo); pthread_join(pidr, NULL); pthread_join(pidw, NULL); kfifo_free(fifo.fifo); printf("nGoodbye!n\n"); return 0;}
Makefile

CFLAGS = -O2  -Wall INCLUDE = -I /CC =  gcc   test:test.o  kfifo.o	${CC} ${CFLAGS} test.o  kfifo.o -o $@ ${INCLUDE} -pthreadtest.o:	$(CC) -c test.c ${INCLUDE} -pthreadkfifo.o:	$(CC) -c kfifo.c ${INCLUDE}clean:	rm -rf *.o test

转载地址:http://tfqci.baihongyu.com/

你可能感兴趣的文章
Android Binder(zt)
查看>>
android Binder
查看>>
Android 本地代码如何输出日志
查看>>
[Android] 内存泄漏调试经验分享
查看>>
Android 设计思想
查看>>
Android 反编译资料整理
查看>>
Android最佳实践之响应灵敏性
查看>>
Android - AudioService(Java)
查看>>
Android 系统稳定性 - ANR
查看>>
Android 系统稳定性 - OOM
查看>>
Android Binder机制(超级详尽)
查看>>
Android中UID机制和共享进程
查看>>
Android Media Scanner工作流程及原理
查看>>
Android dumpsys
查看>>
L1 L2 L3 cache
查看>>
新人学习计划
查看>>
Android L中水波纹点击效果的实现
查看>>
import static和import的区别
查看>>
个人使用的Android Studio快捷键(MAC版)
查看>>
Android Fragment 你应该知道的一切
查看>>