#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 = ;
fifo->out = ;
} /********************************************************
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 = ;
unsigned int y = ; if (!x)
{
return ;
} for (i = x; i != ; )
{
i >>= ;
y <<= ;
} 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 - ))
{
size = gfifo_roundup(size);
} buffer = calloc(, size);
if (NULL == buffer)
{
return -;
} gfifo_init(fifo, buffer, size); return ;
} /********************************************************
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 = ; /*
计算出实际写入队列数据大小
(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 - ))); //拷贝数据到in后面
memcpy(fifo->buffer + (fifo->in & (fifo->size - )), 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 = ; /*
计算出实际可读队列数据大小
(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 - ))); //拷贝数据
memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - )), readable_length); //拷贝能从头部获取的数据
memcpy(buffer + readable_length, fifo->buffer, len - readable_length); //更新out
fifo->out += len; return len;
}

Sword 内核队列二的更多相关文章

  1. Sword 内核队列一

    1.gfifo概述 gfifo是一个First In First Out数据结构,它采用环形循环队列的数据结构来实现:它提供一个无边界的字节流服务,最重要的一点是,它使用并行无锁编程技术,即当它用于只 ...

  2. linux内核(二)内核移植(DM365-DM368开发攻略——linux-2.6.32的移植)

    一.介绍linux-2.6.32: Linux-2.6.32的网上介绍:增添了虚拟化内存 de-duplicacion.重写了 writeback 代码.改进了 Btrfs 文件系统.添加了 ATI ...

  3. SDUT-2132_数据结构实验之栈与队列二:一般算术表达式转换成后缀式

    数据结构实验之栈与队列二:一般算术表达式转换成后缀式 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 对于一个基于二元运 ...

  4. (笔记)Linux内核学习(二)之进程

    一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器. 内核调度的对象是线程而不是进程.对 ...

  5. Android组件内核之Fragment管理与内核(二)

    阿里P7Android高级架构进阶视频免费学习请点击:https://space.bilibili.com/474380680本篇文章将先从以下三个内容来介绍Fragment管理与内核: [Fragm ...

  6. 深入理解PHP内核(十二)函数-函数的定义、传参及返回值

    原文链接:http://www.orlion.ga/344/ 一.函数的定义 用户函数的定义从function 关键字开始,如下 function foo($var) {    echo $var; ...

  7. ActiveMQ_点对点队列(二)

      一.本文章包含的内容 1.列举了ActiveMQ中通过Queue方式发送.消费队列的代码(普通文本.json/xml字符串.对象数据) 2.spring+activemq方式   二.配置信息 1 ...

  8. linux内核系列(二)内核数据结构之链表

    双向链表 传统链表与linu内核链表的区别图: 图一 图二 从上图中看出在传统链表中各种不同链表间没有通用性,因为各个数据域不同,而在linux内核中巧妙将链表结构内嵌到数据域结构中使得不同结构之间能 ...

  9. RabbitMQ 消息队列 二

    一:查看MQ的用户角色 rabbitmqctl list_users 二:添加新的角色,并授予权限 rabbitmqctl add_user xiaoyao 123456 rabbitmqctl se ...

随机推荐

  1. System.ServiceModel.AddressAccessDeniedException

    发生了 System.ServiceModel.AddressAccessDeniedException   HResult=0x80131501   Message=HTTP 无法注册 URL ht ...

  2. Little Pony and Alohomora Part 3 [HihoCoder 1075]

    描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它.初始时,崔克茜将会随机地选择 k 个盒子用魔法将它 ...

  3. windows配置java运行环境

    配置jdk环境    https://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.html 配置tomcat环境      https://j ...

  4. 数据结构 BM算法

    BM算法是比KMP算法更快的字符串模式匹配算法.BM算法最好情况下的时间复杂度是O(n),KMP算法最好情况下的时间复杂度是O(n+m),两者最坏情况下的时间复杂度均是O(m*n).其中,n指目标串长 ...

  5. windows下安装和配置redis

    1.windows下安装和配置redis 1.1 下载: 官网(linux下载地址):https://redis.io/ Windows系统下载地址:https://github.com/MSOpen ...

  6. 学习Struts--Chap03:struts.xml常用配置(基础)

    1.package属性 name:包名 用来唯一的指定一个package.package可以扩展,当一个package扩展自 另一个package时该package会在本身配置的基础上加入扩展的pac ...

  7. 自定义simple_tag和filter在html中渲染出来的联系和区别

    关于 simple_tag: 1,在app下创建一个(templatetags)目录,(被引用的模块必须放在该目录下,且目录名称不可更改): 2,创建任意py文件: 3,创建template对象: f ...

  8. linux > 和 >> 、< 区别

    linux中经常会用到将内容输出到某文件当中,只需要在执行命令后面加上>或者>>号即可进入操作. 大于号:将一条命令执行结果(标准输出,或者错误输出,本来都要打印到屏幕上面的)重定向 ...

  9. openjdk for window

    https://developers.redhat.com/products/openjdk/download/ https://github.com/dmlloyd/openjdk

  10. python3 读取dbf文件报错 UnicodeDecodeError: 'gbk' codec can't decode

    在读取dbf文件时由于编码问题报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0xb5 in position 49: incomplete ...