zoukankan      html  css  js  c++  java
  • Sword 内核队列二

    #ifndef __GTC_FIFO_H_
    #define __GTC_FIFO_H_
    
    #ifndef GTC_MAX
    #define GTC_MAX(a,b) ((a) > (b) ? (a) : (b))
    #endif
    
    #ifndef GTC_MIN
    #define GTC_MIN(a,b) ((a) < (b) ? (a) : (b))
    #endif
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
        struct gfifo {
            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) */
        };
    
        //队列初始化
        int gfifo_alloc(struct gfifo *fifo, unsigned int size);
    
        //压入队列
        unsigned int gfifo_put(struct gfifo *fifo, const unsigned char *buffer, unsigned int len);
    
        //弹出队列
        unsigned int gfifo_get(struct gfifo *fifo, unsigned char *buffer, unsigned int len);
    
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    #include "gfifo.h"
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    
    /********************************************************
       Func Name: gfifo_init
    Date Created: 2019-4-1
     Description: 初始化
           Input: 
          Output: 
          Return: 
         Caution: 
    *********************************************************/
    static void gfifo_init(struct gfifo *fifo, void *buffer, unsigned int size)
    {
        fifo->buffer = buffer;
        fifo->size = size;
        fifo->in = 0;
        fifo->out = 0;
    }
    
    /********************************************************
       Func Name: gfifo_roundup
    Date Created: 2019-4-1
     Description: 扩展
           Input: 
          Output: 
          Return: size
         Caution: 
    *********************************************************/
    static unsigned int gfifo_roundup(unsigned int x)
    {
        unsigned int i = 0;
        unsigned int y = 1;
    
        if (!x)
        {
            return 1;
        }
    
        for (i = x; i != 0; )
        {
            i >>= 1;
            y <<= 1;
        }
    
        return y;
    
    }
    
    /********************************************************
       Func Name: gfifo_alloc
    Date Created: 2019-4-1
     Description: 内存分配
           Input: 
          Output: 
          Return: error code
         Caution: 
    *********************************************************/
    int gfifo_alloc(struct gfifo *fifo, unsigned int size)
    {
        assert(fifo);
    
        unsigned char *buffer;
    
        /*
            size的值总是在调用者传进来的size参数的基础上向2的幂扩展,这是内核一贯的做法。
        这样的好处不言而喻--对kfifo->size取模运算可以转化为与运算,如下:
        fifo->in % fifo->size 可以转化为 fifo->in & (fifo->size – 1)
        在kfifo_alloc函数中,使用size & (size – 1)来判断size 是否为2幂,如果条件为真,则表示size不是2的幂,然后调用roundup_pow_of_two将之向上扩展为2的幂。
        */
        if (size & (size - 1)) 
        {
            size = gfifo_roundup(size);
        }
    
        buffer = calloc(1, size);
        if (NULL == buffer)
        {
            return -1;
        }
    
        gfifo_init(fifo, buffer, size);
    
        return 0;
    }
    
    /********************************************************
       Func Name: gfifo_put
    Date Created: 2019-4-1
     Description: 压入队列
           Input: 
          Output: 
          Return: 压入队列数据长度
         Caution: 
    *********************************************************/
    unsigned int gfifo_put(struct gfifo *fifo, const unsigned char *buffer, unsigned int len)
    {
        unsigned int left_over = 0;
    
        /*
        计算出实际写入队列数据大小
            (fifo->in - fifo->out)  已经使用空间大小
            fifo->size - (fifo->in - fifo->out)  可以使用空间大小
            len  需要写入数据大小
        */
        len = GTC_MIN(len, fifo->size - (fifo->in - fifo->out)); 
    
        /*
        计算出在队列in后面插入数据的大小
            fifo->in & (fifo->size - 1) 等同于 fifo->in % fifo->size
            fifo->size - (fifo->in & (fifo->size - 1))  表示in后面可写数据的长度
        */
        left_over = GTC_MIN(len, fifo->size - (fifo->in & (fifo->size - 1))); 
    
        //拷贝数据到in后面
        memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, left_over);
    
        //将剩余的数据拷贝到out前面
        memcpy(fifo->buffer, buffer + left_over, len - left_over);
        
        //更新in
        fifo->in += len;
    
        return len; 
    }
    
    /********************************************************
       Func Name: gfifo_get
    Date Created: 2019-4-1
     Description: 弹出队列
           Input: 
          Output: 
          Return: 弹出队列
         Caution: 
    *********************************************************/
    unsigned int gfifo_get(struct gfifo *fifo, unsigned char *buffer, unsigned int len)
    {
        assert(buffer);
    
        unsigned int readable_length = 0;
    
        /*
        计算出实际可读队列数据大小
            (fifo->in - fifo->out)  已经使用空间大小
        */
    
        len = GTC_MIN(len, fifo->in - fifo->out);
    
        /*
        计算出在队列out后面插入数据的大小
            fifo->in & (fifo->size - 1) 等同于 fifo->in % fifo->size
            fifo->size - (fifo->out & (fifo->size - 1))  表示out后面可读数据的长度
        */
        readable_length = GTC_MIN(len, fifo->size - (fifo->out & (fifo->size - 1))); 
    
        //拷贝数据
        memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), readable_length);
    
        //拷贝能从头部获取的数据
        memcpy(buffer + readable_length, fifo->buffer, len - readable_length);
    
        //更新out
        fifo->out += len;
    
        return len; 
    }
  • 相关阅读:
    绿色版 notepad++ 添加鼠标右键菜单
    Scala 安装与配置
    Scala 神奇的下划线 _
    Kafka 安装部署
    Pulsar 下一代消息平台
    Sqoop 安装部署
    Flume 常用配置项
    Android-selector
    android- 9patch
    有关内存的思考题
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/10638829.html
Copyright © 2011-2022 走看看