分析的内核版本号截止到2014-04-15,基于1.05正式版。blogs会及时跟进最新版本号的内核开发进度,若源代码凝视出现”???”字样,则是未深究理解部分。

Raw-OS官方站点:http://www.raw-os.org/

Raw-OS托管地址:https://github.com/jorya/raw-os/

有了之前的queue和queue_size的解读之后。这个queue_buffer就很之简单了~对于queue是转发消息的指针,queue_size则是转发消息指针和消息大小。那么queue_buffer不在转存消息的指针,而是将消息copy一份,转发消息内容和消息大小。

这个定义一个queue_buffer消息的概念~

一个queue_buffer消息包含消息的大小,消息详细数据内容,然后依照上图的结构进行排列~那么在queue_buffer中,详细消息是封装成以上的结构进行转发的~

那么在queue_buffer建立的内部数据存储仓库,queue_buffer的消息按这样排列的

当中,head指针指向queue_buffer消息存在的開始位置。tail指针指向queue_buffer消息存在的末尾位置,剩余的没转存消息的位置称为空暇消息

还有注意一点的就是。queue_buffer的queue_buffer消息一定要按4字节对齐的形式存储在queue_buffer的存储仓中,原因的话要详细看代码才干说明确

Queue_buffer消息的转存过程和queue和queue_size一样,仅仅是内核多了复制详细数据这一部的操作,至于在转存仓库的组织形式,都是按各自的消息结构体来组织。queue消息是指向消息的void指针,queue_size就是以消息指针和消息大小组成的queue_size结构体,那么到这里queue_buffer就是以消息长度+消息实际内容的形式。

代码仅仅说明queue_buffer建立。发送queue_buffer消息到queue_buffer的部分

1.queue_buffer的创建

RAW_U16 raw_queue_buffer_create(RAW_QUEUE_BUFFER *q_b, RAW_U8 *p_name, RAW_VOID *msg_buffer, MSG_SIZE_TYPE buffer_size, MSG_SIZE_TYPE max_msg_size)
{
MSG_SIZE_TYPE bufsz;
RAW_U8 queue_buffer_align_mask;
/* 检查创建消息buffer的边界条件 */
#if (RAW_QUEUE_BUFFER_FUNCTION_CHECK > 0)
if (q_b == 0) {
return RAW_NULL_OBJECT;
} if (msg_buffer == 0) {
return RAW_NULL_POINTER;
}
#endif
/* 消息buffer的大小必须满足4字节的整数倍 */
bufsz = ROUND_BUFFER_SIZE(buffer_size);
/* 消息buffer大小为0时,错误返回 */
if (bufsz == 0) {
return RAW_QUEUE_BUFFER_SIZE_0;
}
/* 消息buffer大小不满足4字节对齐时,错误返回 */
if (bufsz != buffer_size) {
return RAW_QUEUE_BUFFER_INVALID_SIZE;
} queue_buffer_align_mask = HEADERSZ - 1u;
/* 消息buffer的内部存储消息的仓库的地址相同也要满足4字节的整数倍对齐 */
if (((RAW_U32)msg_buffer & queue_buffer_align_mask)){
return RAW_INVALID_ALIGN;
} /* 初始化消息buffer的堵塞链表头 */
list_init(&q_b->common_block_obj.block_list); q_b->bufsz = bufsz;
q_b->frbufsz = bufsz;
q_b->buffer = msg_buffer;
q_b->maxmsz = max_msg_size;
q_b->head = 0;
q_b->tail = 0; q_b->common_block_obj.name = p_name;
q_b->common_block_obj.block_way = RAW_BLOCKED_WAY_PRIO;
q_b->common_block_obj.object_type = RAW_QUEUE_BUFFER_OBJ_TYPE; TRACE_QUEUE_BUFFER_CREATE(raw_task_active, q_b); return RAW_SUCCESS; }

2.发送queue_buffer消息

RAW_U16 raw_queue_buffer_end_post(RAW_QUEUE_BUFFER *q_b, RAW_VOID *p_void, MSG_SIZE_TYPE msg_size)
{
/* 发送queue buffer消息时的边界条件检查 */
#if (RAW_QUEUE_BUFFER_FUNCTION_CHECK > 0)
if (q_b == 0) {
return RAW_NULL_OBJECT;
} if (p_void == 0) {
return RAW_NULL_POINTER;
}
/* 发送queue buffer消息长度不能超过创建queue_buffer定义的最大消息长度 */
if (msg_size > q_b->maxmsz) {
return RAW_EXCEED_QUEUE_BUFFER_MSG_SIZE;
}
#endif /* 开启0中断特性后。不能在中断ISR中发送queue_buffer,而queue和queue_size能够,想想为什么??? */
#if (CONFIG_RAW_ZERO_INTERRUPT > 0)
if (raw_int_nesting) {
return RAW_NOT_CALLED_BY_ISR;
}
#endif return queue_buffer_post(q_b, p_void, msg_size, SEND_TO_END);
}

存储queue_buffer的核心代码

RAW_U16 queue_buffer_post(RAW_QUEUE_BUFFER *q_b, RAW_VOID *p_void, MSG_SIZE_TYPE msg_size, RAW_U8 opt_send_method)
{
LIST *block_list_head;
RAW_TASK_OBJ *task_ptr; RAW_SR_ALLOC(); RAW_CRITICAL_ENTER(); if (q_b->common_block_obj.object_type != RAW_QUEUE_BUFFER_OBJ_TYPE) { RAW_CRITICAL_EXIT();
return RAW_ERROR_OBJECT_TYPE;
} block_list_head = &q_b->common_block_obj.block_list; if (!is_queue_buffer_free(q_b, msg_size)) { RAW_CRITICAL_EXIT(); TRACE_QUEUE_BUFFER_MAX(raw_task_active, q_b, p_void, msg_size, opt_send_method); return RAW_QUEUE_BUFFER_FULL;
} /* 当queue_buffer内部存储仓未满时,就会将消息转存到存储仓里面。并且内部仅仅实现发送存储仓末尾的操作 */
if (is_list_empty(block_list_head)) { if (opt_send_method == SEND_TO_END) {
msg_to_end_buffer(q_b, p_void, msg_size);
} else {
/* 没有定义有除发送到存储仓末尾外的操作 */
} RAW_CRITICAL_EXIT(); TRACE_QUEUE_BUFFER_POST(raw_task_active, q_b, p_void, msg_size, opt_send_method); return RAW_SUCCESS;
}
/*
* 假设有任务堵塞在queue_buffer上等待消息,个人觉得以下这些操作是为了加快消息传递,
* 不由queue_buffer的内部存储仓转存数据内容。少了一个二次copy的过程
*
* 找到queue_buffer的堵塞链表的最高优先级任务,然后直接将消息内容和大小copy到任务控制块中,然后唤醒该任务
*/
task_ptr = list_entry(block_list_head->next, RAW_TASK_OBJ, task_list); raw_memcpy(task_ptr->msg, p_void, msg_size);
task_ptr->qb_msg_size = msg_size; raw_wake_object(task_ptr); RAW_CRITICAL_EXIT(); TRACE_QUEUE_BUFFER_WAKE_TASK(raw_task_active, list_entry(block_list_head->next, RAW_TASK_OBJ, task_list), p_void, msg_size, opt_send_method); raw_sched();
return RAW_SUCCESS;
}

Raw-OS源代码分析之消息系统-Queue_Buffer的更多相关文章

  1. Raw-OS源代码分析之消息系统-Queue_Size

    分析的内核版本号截止到2014-04-15.基于1.05正式版.blogs会及时跟进最新版本号的内核开发进度,若源代码凝视出现"???"字样,则是未深究理解部分. Raw-OS官方 ...

  2. Memcached源代码分析 - Memcached源代码分析之消息回应(3)

    文章列表: <Memcached源代码分析 - Memcached源代码分析之基于Libevent的网络模型(1)> <Memcached源代码分析 - Memcached源代码分析 ...

  3. 1.异步消息Jms及其JmsTemplate的源代码分析,消息代理ActiveMQ

    一. 介绍 借助Spring,有多种异步消息的可选方案,本章使用Jms.Jms的消息模型有两种,点对点消息模型(队列实现)和发布-订阅消息模型(主题). 图1.点对点消息模型(一对一) 图2.发布-订 ...

  4. 1.4. chromium源代码分析 - chromiumframe - 消息系列

    Message framework 是对消息循环的封装和扩展,Chromium在消息循环中增加处理内部任务的工作.将内部工作处理寄生在Windows的消息循环中,会有一个问题,就是没有Windows自 ...

  5. android 消息系统Handler、MessageQueue、Looper源代码学习

    android消息系统 总体框架如图所看到的 在安卓的消息系统中,每一个线程有一个Looper,Looper中有一个MessageQueue,Handler向这个队列中投递Message,Looper ...

  6. Android应用程序进程启动过程的源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址: http://blog.csdn.net/luoshengyang/article/details/6747696 Android 应用程序框架层创 ...

  7. Android系统进程Zygote启动过程的源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6768304 在Android系统中,所有的应用 ...

  8. RTMPdump(libRTMP) 源代码分析 9: 接收消息(Message)(接收视音频数据)

    ===================================================== RTMPdump(libRTMP) 源代码分析系列文章: RTMPdump 源代码分析 1: ...

  9. Android系统默认Home应用程序(Launcher)的启动过程源代码分析

    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还需要有一个 Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home ...

随机推荐

  1. C#读写Excel表格文件NPOI方式无需安装office .xls后缀没问题

    /// <summary> /// 读Excel /// </summary> /// <param name="fileName"></ ...

  2. 九度oj 题目1028:继续畅通工程

    题目描述:     省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用 ...

  3. BZOJ 3926 [Zjoi2015]诸神眷顾的幻想乡 ——广义后缀自动机

    神奇的性质,叶子节点不超过20个. 然后把这些节点提出来构成一颗新树,那么这些树恰好包含了所有的情况. 所以直接广义后缀自动机. 然后统计本质不同的字符串就很简单显然了. #include <c ...

  4. 刷题总结——系列维护(ssoi)

    题目: 题解: 题解如上图,至于计算大于s的数字的数量和小于s数字的和用权值线段树或者树状数组维护就行了···注意离散化 另外发现cout和puts比printf快好多····· 代码: #inclu ...

  5. 【bzoj1854】[Scoi2010]游戏 - 并查集

    lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备最多只能使 ...

  6. Virtual Box 安装过程(卸载Vmware后)

    VirtualBox安装前的操作:(或许某些操作不一定有用,但是我是这么做下来的,最后也安装成功了) 步骤一:停止之前安装的vmware的所有服务(如果之前没有安装过虚拟机软件,无需做此操作)VMwa ...

  7. Spring-IOC源码解读1-整体设计

    1. SpringIOC提供了一个基本的javabean容器,通过IOC模式管理依赖关系,并通过依赖注入和AOP增强了为javabean这样的pojo对象赋予事务管理,生命周期管理等基本功能.2. S ...

  8. 升级完Android Studio3.2后,打包release出现的错误

    升级完Android Studio2.3后,打包release出现的错误 Error:Execution failed for task ':qq:lintVitalRelease'.> Lin ...

  9. COdevs 1074 食物链

    1074 食物链 2001年NOI全国竞赛  时间限制: 3 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond 题目描述 Description 动物王国中有三类动物 A,B,C, ...

  10. 济南学习 Day 5 T2 am

    車(Rook) [题目描述] 众所周知,車是中国象棋最厉害的棋子之一,他能吃到同一行或者同一列的其他棋子.車显然不能和車在一打起来,于是rly有借来了许多许多車在棋盘上摆了起来...... 他想知道, ...