linux kernel fifo移植

一、直接编译即可使用到项目中

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <error.h>

#include "kfifo4.h"

 

static inline int is_power_of_2(unsigned int n)

{

return !((n - 1) & n);

}

 

unsigned int roundup_pow_of_two(unsigned int n)

{

if(is_power_of_2(n))

return n;

 

int i = 32;

while(i--)

{

if((n >> i) & 1)

break;

}

 

n = 1 << (i + 1);

return n;

}

 

struct fifo *fifo_init(unsigned char *buffer, unsigned int size)

{

struct fifo *fifo;

 

fifo = malloc(sizeof(struct fifo));

if (!fifo)

{

fprintf(stderr, "malloc %ubyte failed\n", sizeof(struct fifo));

return NULL;

}

 

fifo->buffer = buffer;

fifo->size = size;

fifo->in = fifo->out = 0;

 

return fifo;

}

 

struct fifo *fifo_alloc(unsigned int size)

{

unsigned char *buffer;

struct fifo *ret;

 

/* round up to the next power of 2 */

if(size > 0x80000000)

{

fprintf(stderr, "The size is too lager\n");

return NULL;

}

size = roundup_pow_of_two(size);

 

buffer = malloc(size);

if (!buffer)

{

fprintf(stderr, "malloc %ubyte failed\n", size);

return NULL;

}

 

ret = fifo_init(buffer, size);

 

if (!ret)

free(buffer);

 

return ret;

}

 

void fifo_free(struct fifo *fifo)

{

free(fifo->buffer);

free(fifo);

}

 

unsigned int _fifo_put(struct fifo *fifo, const unsigned char *buffer, unsigned int len)

{

unsigned int l;

 

len = min(len, fifo->size - fifo->in + fifo->out);

 

/* first put the data starting from fifo->in to buffer end */

l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));

memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);

 

/* then put the rest (if any) at the beginning of the buffer */

memcpy(fifo->buffer, buffer + l, len - l);

 

fifo->in += len;

 

return len;

}

 

unsigned int _fifo_get(struct fifo *fifo, unsigned char *buffer, unsigned int len)

{

unsigned int l;

 

len = min(len, fifo->in - fifo->out);

 

/* first get the data from fifo->out until the end of the buffer */

l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));

memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);

 

/* then get the rest (if any) from the beginning of the buffer */

memcpy(buffer + l, fifo->buffer, len - l);

 

fifo->out += len;

 

return len;

}

 

char test[3] = "123";

char test1[3] = "000";

//char test2[3] = {"123456"};

 

void *consumer_proc(void *arg)

{

struct my_fifo *my_fifo = (struct my_fifo *)arg;

while(1)

{

usleep(50*1000);

memset(test1, 0x0, sizeof(test1));

_fifo_get(my_fifo, (void *)&test1, sizeof(test1));

printf("test1 =%s\n",test1);

//printf("test2 =%s\n",test2);

}

return (void *)my_fifo;

}

 

void *producer_proc(void *arg)

{

struct my_fifo *my_fifo = (struct my_fifo *)arg;

while(1)

{

_fifo_put(my_fifo, (void *)&test, sizeof(test));

usleep(200*1000);

}

return (void *)my_fifo;

}

 

 

int producer_thread(void *arg)

{

int err;

pthread_t tid;

err = pthread_create(&tid, NULL, producer_proc, arg);

if (err != 0)

{

printf("Failed to create consumer thread\n");

return -1;

}

return tid;

}

 

int consumer_thread(void *arg)

{

int err;

pthread_t tid;

err = pthread_create(&tid, NULL, consumer_proc, arg);

if (err != 0)

{

printf("Failed to create consumer thread\n");

return -1;

}

return tid;

}

 

int main(void)

{

struct fifo *my_fifo;

my_fifo = fifo_alloc(512);

int count = 0;

pthread_t consume_pid, produce_pid;

if (my_fifo == NULL)

{

printf("my fifo null");

}

produce_pid = producer_thread((void*)my_fifo);

consume_pid = consumer_thread((void*)my_fifo);

while(1)

{

count++;

usleep(50*1000);

}

return 0;

}

 

#ifndef _FIFO_H_

#define _FIFO_H_

 

struct fifo {

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

};

 

#define min(a, b) ((a) > (b) ? (b) : (a))

 

extern struct fifo *fifo_alloc(unsigned int size);

extern void fifo_free(struct fifo *fifo);

extern unsigned int _fifo_put(struct fifo *fifo,

const unsigned char *buffer, unsigned int len);

extern unsigned int _fifo_get(struct fifo *fifo,

unsigned char *buffer, unsigned int len);

 

static inline void _fifo_reset(struct fifo *fifo)

{

fifo->in = fifo->out = 0;

}

 

 

static inline unsigned int _fifo_len(struct fifo *fifo)

{

return fifo->in - fifo->out;

}

 

/****************************************************/

/* 根据需要进行封装,这儿我封装为保存int数

/****************************************************/

 

static inline void fifo_reset(struct fifo *fifo)

{

_fifo_reset(fifo);

}

 

static inline unsigned int fifo_len(struct fifo *fifo)

{

return _fifo_len(fifo)/4;

}

 

static inline unsigned int fifo_put(struct fifo *fifo, int n)

{

return _fifo_put(fifo, (unsigned char *)&n, sizeof(int));

}

 

static inline unsigned int fifo_get(struct fifo *fifo, int *n)

{

return _fifo_get(fifo, (unsigned char *)n, sizeof(int));

}

 

#endif

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值