当前位置: 首页 > news >正文

数据结构:内核kfifo的实践

        实践了内核的数据结构kfifo记录下,其特点分析看了下这篇博客写的很详细。https://blog.csdn.net/zhoutaopower/article/details/86491852

fifo.c 实现kfifo的主干函数接口,但是很多有用的接口没有扩展,需要的时候再扩展。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include"fifo.h"

#define min(a, b)              \
({                             \
    typeof(a) _a = (a);        \
    typeof(b) _b = (b);        \
    _a <= _b ? _a : _b         \
})

static inline int fls(int x)
{
    int position;
    int i;

    if(0 != x)
    {
        for(i = (x >> 1), position = 0; i != 0; ++position)
            i >>= 1;
    }
    else
    {
        position = -1;
    }
    return position+1;
}

static inline unsigned int roundup_pow_of_two(unsigned int x)
{
    return 1UL << fls(x - 1);
}

int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, size_t esize)
{
        /*
         * round up to the next power of 2, since our 'let the indices
         * wrap' technique works only in this case.
         */
        size = roundup_pow_of_two(size);

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

        if (size < 2) {
                fifo->data = NULL;
                fifo->mask = 0;
                return -1;
        }

//      fifo->data = kmalloc_array(esize, size, gfp_mask);
        fifo->data = malloc(esize*size);
        if (!fifo->data) {
                fifo->mask = 0;
                return -1;
        }
        fifo->mask = size - 1;

        return 0;
}

int __kfifo_init(struct __kfifo *fifo, void *buffer, unsigned int size, size_t esize)
{
        size /= esize;

        size = roundup_pow_of_two(size);

        fifo->in = 0;
        fifo->out = 0;
        fifo->esize = esize;
        fifo->data = buffer;

        if (size < 2) {
                fifo->mask = 0;
                return -1;
        }
        fifo->mask = size - 1;

        return 0;
}

void __kfifo_free(struct __kfifo *fifo)
{
        free(fifo->data);
        fifo->in = 0;
        fifo->out = 0;
        fifo->esize = 0;
        fifo->data = NULL;
        fifo->mask = 0;
}

/*
 * internal helper to calculate the unused elements in a fifo
 */
static inline unsigned int kfifo_unused(struct __kfifo *fifo)
{
        return (fifo->mask + 1) - (fifo->in - fifo->out);
}

static void kfifo_copy_in(struct __kfifo *fifo, const void *src, unsigned int len, unsigned int off)
{
        unsigned int size = fifo->mask + 1;
        unsigned int esize = fifo->esize;
        unsigned int l;

        off &= fifo->mask;
        if (esize != 1) {
                off *= esize;
                size *= esize;
                len *= esize;
        }
        l = min(len, size - off);

        memcpy(fifo->data + off, src, l);
        memcpy(fifo->data, src + l, len - l);
        /*
         * make sure that the data in the fifo is up to date before
         * incrementing the fifo->in index counter
         */
//      smp_wmb();
}

unsigned int __kfifo_in(struct __kfifo *fifo, const void *buf, unsigned int len)
{
        unsigned int l;

        l = kfifo_unused(fifo);
        if (len > l)
                len = l;

        kfifo_copy_in(fifo, buf, len, fifo->in);
        fifo->in += len;
        return len;
}

static void kfifo_copy_out(struct __kfifo *fifo, void *dst,
                unsigned int len, unsigned int off)
{
        unsigned int size = fifo->mask + 1;
        unsigned int esize = fifo->esize;
        unsigned int l;

        off &= fifo->mask;
        if (esize != 1) {
                off *= esize;
                size *= esize;
                len *= esize;
        }
        l = min(len, size - off);

        memcpy(dst, fifo->data + off, l);
        memcpy(dst + l, fifo->data, len - l);
        /*
         * make sure that the data is copied before
         * incrementing the fifo->out index counter
         */
//      smp_wmb();
}

unsigned int __kfifo_out_peek(struct __kfifo *fifo,
                void *buf, unsigned int len)
{
        unsigned int l;

        l = fifo->in - fifo->out;
        if (len > l)
                len = l;

        kfifo_copy_out(fifo, buf, len, fifo->out);
        return len;
}

unsigned int __kfifo_out(struct __kfifo *fifo,
                void *buf, unsigned int len)
{
        len = __kfifo_out_peek(fifo, buf, len);
        fifo->out += len;
        return len;
}

fifo.h

#include<stdio.h>
#include<stdlib.h>

struct __kfifo {
        unsigned int    in;      // 入列的时候增加的位置
        unsigned int    out;     // 出列的时候增加的位置
        unsigned int    mask;    // 巧妙的 mask 设计,同时包含了数据的个数信息
        unsigned int    esize;   // 元素的大小
        void            *data;   // 数据
};

int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, size_t esize);
int __kfifo_init(struct __kfifo *fifo, void *buffer,unsigned int size, size_t esize);
void __kfifo_free(struct __kfifo *fifo);
unsigned int __kfifo_in(struct __kfifo *fifo, const void *buf, unsigned int len);
unsigned int __kfifo_out(struct __kfifo *fifo, void *buf, unsigned int len);

test.c

2024-04-07 记录

#include<stdio.h>
#include<stdlib.h>
#include"fifo.h"

typedef struct node
{
        int a;
        int b;
}node;

int main()
{
        int esize = sizeof(node);
        int size = 8;
        void *buf = NULL;
        struct __kfifo fifo;
        int count;
        node aa;
        aa.a = 12;
        aa.b = 13;

        node bb;
        bb.a = 0;
        bb.b = 0;

        __kfifo_init(&fifo, buf, size, esize);
        __kfifo_alloc(&fifo, size, esize);

        count = __kfifo_in(&fifo, (void *)&aa, 1); //注意这里传参是node的数量,不是node的大小。一开始实践赋值了node的大小,会有内存溢出。
        printf("in count: %d.\n", count);

        count = __kfifo_out(&fifo, (void *)&bb, 1);
        printf("out count: %d.\n", count);

        printf("bb.a :%d, bb.b :%d.\n", bb.a, bb.b);
        return 0;
}

相关文章:

  • 【WSN覆盖优化】基于灰狼优化算法的无线传感器网络覆盖 GWO-WSN覆盖优化【Matlab代码#74】
  • MySQL 用来查询表结构的 SQL 语句
  • AOP 切面判断 token 是否有效
  • OpenAI的Whisper
  • Vue3学习01 Vue3核心语法
  • 大语言模型的指令调优:综述
  • 基于STM32的智能交通系统设计与实现
  • 液冷方式介绍
  • 在Debian 12系统上安装Docker
  • 专业级股票交易系统 股票金融平台 带新股申购 通信达源码
  • three.js尝试渲染gbl模型成功!(三)
  • unable to find a medium containing a live file system解决办法!
  • 深入浅出 -- 系统架构之负载均衡Nginx的性能优化
  • 深入浅出 -- 系统架构之负载均衡Nginx反向代理
  • Go语言map、slice、channel底层实现(go面试)
  • Harmony鸿蒙南向驱动开发-DAC
  • 损失函数:BCE Loss(二元交叉熵损失函数)、Dice Loss(Dice相似系数损失函数)
  • SSM实战项目——哈哈音乐(二)后台模块开发
  • Node.js环境调用百度智能云(百度云)api鉴权认证三步走
  • 北航计算机软件技术基础课程作业笔记【3】
  • https://app.hackthebox.com/machines/Inject
  • Spring —— Spring简单的读取和存储对象 Ⅱ
  • 渗透测试之冰蝎实战
  • Mybatis、TKMybatis对比
  • Microsoft Office 2019(2022年10月批量许可版)图文教程
  • 《谷粒商城基础篇》分布式基础环境搭建
  • 哈希表题目:砖墙
  • Vue 3.0 选项 生命周期钩子
  • 【车载嵌入式开发】AutoSar架构入门介绍篇
  • 【计算机视觉 | 目标检测】DETR风格的目标检测框架解读