seL4操作系统基础05:event interface与seL4Notification connector
目录
1 示例程序分析
1.1 示例程序结构
1.2 CMakeLists.txt文件分析
1.3 component类型定义
1.3.1 event interface概述
1.3.2 event interface类型
1.3.3 event interface实例
1.4 hello-2.camkes分析
1.4.1 seL4Notification connector类型
1.4.2 seL4Notification connector实例
1.5 component源码分析
1.5.1 emitter component
1.5.2 consumer component
1.6 运行效果
2 编译生成文件分析
2.1 编译生成文件结构
2.2 emitter component编译生成文件分析
2.2.1 camkes-component-emitter.h
2.2.2 event_emits_seL4Notification_0.c
2.3 consumer component编译生成文件分析
2.3.1 camkes-component-consumer.h
2.3.2 event_consumes_seL4Notification_0.c
3 实验1:使用event interface通知多个component
3.1 实验目的
3.2 修改文件
3.3 运行效果
3.4 编译生成文件分析
3.4.1 编译生成文件结构
3.4.2 event_emits_seL4Notification_0.c
3.4.3 event_consumes_seL4Notification_0/1.c
4 实验2:使用event interface实现component间同步
4.1 实验目的
4.2 源码分析
4.2.1 component类型定义
4.2.1 系统定义
4.2.2 component源码
4.3 运行效果
4.4 编译生成文件分析
5 component内部的同步
5.1 同步原语
5.2 操作函数
5.3 编译生成文件分析
5.3.1 同步原语函数声明
5.3.2 同步原语函数定义
1 示例程序分析
1.1 示例程序结构
1. Emitter.camkes & emmitter.c
Emitter component的类型定义与实现,用于发送event
2. Consumer.camkes & consumer.c
Consumer component的类型定义与实现,用于接收event
3. CMakeList.txt
向系统描述本模块的构建方式
4. hello-2.camkes
描述本模块的组成方式
说明:本节实验代码通过如下命令提取,但仅使用其编译框架,代码重新编写
./init --tut hello-camkes-2 --solution
1.2 CMakeLists.txt文件分析
从CMakeList.txt中我们可以得知
1. 系统中包含Emitter和Consumer这2种component类型,并且指定了他们对应的源文件
2. 使用hello-2.camkes描述整个系统
1.3 component类型定义
1.3.1 event interface概述
1. event interface是一种异步通信机制,类似信号和中断
2. event interface也有2个固定方向的角色,
① Emitter:发送信号的component
② Consumer:接收并处理信号的component
1.3.2 event interface类型
event interface不需要额外的类型定义,直接使用emits & consumes关键字在component中定义interface实例即可
1.3.3 event interface实例
1. event interface的发送者使用emits关键字定义interface实例,示例代码中实例名为event_emits
2. event interface的接收者使用consumes关键字定义interface实例,示例代码中实例名为event_consumes
说明:event interface在2个component中的实例名同时也作为调用event相关函数的前缀,详见下文分析
1.4 hello-2.camkes分析
1.4.1 seL4Notification connector类型
seL4Noticification也是camkes提供的标准connector类型,由projects/camkes-tool/include/builtin/std_connector.camkes引入
1. from Event with 0 threads
① event发送端是event interface
② event发送端不需要分配线程
2. to Events
① event接收端是event interface
② event接收端需要分配线程,接收并处理event
说明1:seL4Noticification connector特性
① event发送端可以在任何时间以任何频率发送event
② event接收端可以以阻塞或非阻塞的方式等待event
③ 发送event是非阻塞的
说明2:seL4Noticification connector template模板文件
对于template文件,我们不做分析,还是直接分析编译后生成的C语言文件
① projects/camkes-tool/camkes/templates/seL4Noticification-from.template.c
② projects/camkes-tool/camkes/templates/seL4Notification-to.template.c
1.4.2 seL4Notification connector实例
1. connection实例定义在composition元素中,因为composition是包含component和connector实例的容器
2. connection实例连接了2个component实例中的interface实例
1.5 component源码分析
1.5.1 emitter component
① emmitter component持续调用event_emits_emit函数发送event
② event_emit函数名的构成方式为<interface name>_emit
1.5.2 consumer component
camkes中共有3种处理event的方式,
1. 注册回调函数
① 回调函数会在接收到event时被调用
② <interface name>_reg_callback函数用于注册event回调函数
2. 阻塞等待event(blocking wait)
① 阻塞等待函数会在接收到event时返回
② <interface name>_wait函数用于阻塞等待event
3. 轮询event(polling)
① 轮询函数用于查询当前是否接收到event
② <interface name>_poll函数用于轮询是否接收到event
说明1:上述3种方式均会消费掉一个接收到的event,其中callback的优先级最高。也就是说,如果一个component注册了event callback函数,同时又在阻塞等待event,当一个event到达时,将会首先调用callback
说明2:在event callback中再次注册callback
注册成功的event callback将在被调用的同时注销(deregistered),因此如果希望callback再次被调用,则需要在callback中重新注册
1.6 运行效果
从运行结果可见,callback回调函数的优先级确实比阻塞等待高
2 编译生成文件分析
2.1 编译生成文件结构
2.2 emitter component编译生成文件分析
2.2.1 camkes-component-emitter.h
我们这里也只分析新增的函数声明
1. event_emits_emit函数
① 这是event interface提供的发送event函数声明
② 该函数在event_emits_seL4Notification_0.c中实现
2. event_emits__init函数
① 这是event interface的初始化函数(interface name为event)
② 由于使用WEAK属性修饰,即弱函数,表示event__init函数可以不实现
③ 该函数没有被调用
说明:event_emits__init函数没有被调用和procedure interface的caller端是类似的,这端的interface均没有启动线程,在connector类型定义中均使用"with 0 threads"修饰
2.2.2 event_emits_seL4Notification_0.c
1. 该文件中只有event_emits_emit_underlying函数的实现,并不是emitter component中调用的event_emits_emit函数
2. event_emits_emit函数的实现在emitter component编译目录的camkes.c中,最终会调用event_emits_emit_underlying函数
3. event_emits_emit_underlying函数的操作是调用seL4_Signal系统调用发送信号
2.3 consumer component编译生成文件分析
2.3.1 camkes-component-consumer.h
1. event_consumes_wait函数
① 这是event interface提供的阻塞等待event函数声明
② 该函数在event_consumes_seL4Notification_0.c中实现
2. event_comsumes_poll函数
① 这是event interface提供的轮询event函数声明
② 该函数在event_consumes_seL4Notification_0.c中实现
3. event_consumes_reg_callback函数
① 这是event interface提供的注册event回调函数的函数声明
② 该函数在event_consumes_seL4Notification_0.c中实现
4. event_consumes_acknowledge函数
① 该函数在编译生成的文件中没有定义,经过上机验证,该函数在consumer component中也确实不能使用
② 该函数在通过event interface使用中断时会被实现并使用
5. event_consumes_handle函数
该函数与event_consumes_acknowledge函数一样,在当前的编译生成文件中没有定义,而是在通过event interface使用中断时会被实现并使用
6. event_consumes__init函数
① 这是event interface的初始化函数
② 该函数在camkes.c的post_main函数中被调用
2.3.2 event_consumes_seL4Notification_0.c
1. event_consumes__run是consumer component中接收并处理event的线程
说明1:由event_consumes__run的实现可见,如果注册了event回调函数,则直接调用该函数,不会释放信号量,因此wait和poll函数均不会获取到该event,也就实现了event回调函数的优先级高于wait和poll函数
说明2:如果注册了event回调函数,在使用时会同时将callback设置为NULL,也就是注销该回调函数。因此,在consumer component源码中,需要在回调函数中再次注册回调函数
2. event_consumes_poll函数通过非阻塞等待信号量的方式实现轮询event
3. event_consumes_wait函数通过阻塞等待信号量的方式实现阻塞等待event
4. event_consumes_reg_callback在注册event回调函数时,会优先处理已经pending的event
说明:信号量的实现
① 在event interface的实现中,多次使用了信号量操作,例如调用sync_bin_sem_bare_wait函数
② 上述信号量操作在projects/seL4_libs/libsel4sync库中实现
3 实验1:使用event interface通知多个component
3.1 实验目的
验证通过event interface是否可以通知多个component,观察建立的connection文件和实际运行效果
3.2 修改文件
文件:源码目录下hello-2.camkes
新增一个consumer2 component实例,并与emitter component实例建立连接,使用的connector与之前相同
3.3 运行效果
可见2个consumer component实例均接收到event,并且正确处理
3.4 编译生成文件分析
3.4.1 编译生成文件结构
可见在consumers component和consumers2 conponent实例中,均生成了connection文件
3.4.2 event_emits_seL4Notification_0.c
event_emits_emit_underlying函数会调用seL4_Signal系统调用,向2个component实例发送信号
3.4.3 event_consumes_seL4Notification_0/1.c
2个consumes component实例生成的connection文件中,只有一处不同,也就是component实例名不同
而二者调用seL4_Wait的参数是相同的
4 实验2:使用event interface实现component间同步
4.1 实验目的
通过event interface实现2个component之间的同步
说明:剧透一下,这里引入component间同步的主题,是因为下一节引入的dataport interface虽然可供不同的component操作同一片shared memory,但是对shared memory的操作需要同步
4.2 源码分析
4.2.1 component类型定义
从event interface的实例名可以很容易看出event的方向,
c2e:client emits --> echo consumes
e2c:echo emits --> client consumes
4.2.1 系统定义
系统中分别定义了2个component的实例,并且在这2个component之间建立了2条seL4Notification类型的connection
说明:关于event interface类型名的构成
① 可以任务emits <name>和consumes <name>就是event interface的类型名
② 对于emits & consumes修饰的一对event interface,需要类型名相同。例如在示例代码中,
client emits --> echo consumes的event interface,就都使用C2EEvent构成类型名
③ 可以使用相同的<name>字段都成interface类型名,如下图所示
因为我们只需要emits & consumes修饰的一对event interface类项名相同即可,至于event interface的连接方式,则是由connection实例定义
4.2.2 component源码
1. echo component没有定义control thread,所以我们使用event interface的初始化函数c2e__init来注册event回调函数
2. client component中使用阻塞等待的方式处理event
3. echo & client component通过2个event实现相互通知,进而实现component间的同步
4.3 运行效果
可见运行结果是符合预期的
4.4 编译生成文件分析
每个connection实例都会生成一个文件,内容与之前类似,此处不再赘述
5 component内部的同步
5.1 同步原语
上文提到了使用event interface实现component之间的同步,如果是在component内部,camkes提供了互斥锁、信号量和二值信号量3种同步原语
在component中可以按如下方式进行定义,
其中semaphore的默认值为1,binary_semaphore的默认值为0
说明:可以在configuration元素中设置semaphore和binary_semaphore的初始值,在设置时,使用<instance name>_value属性
其中binary_semaphore的初始值只能是0或1(这个很好理解)
5.2 操作函数
说明:camkes本身没有提供component间的锁机制,但是可以基于camkes框架实现lockserver,从而提供component间的锁功能
5.3 编译生成文件分析
我们在Client component类型中增加互斥锁、信号量和二值信号实例
5.3.1 同步原语函数声明
在编译生成的client目录下include/camkes-component-client.h文件中,会新增同步原语函数声明
5.3.2 同步原语函数定义
在编译生成的client目录下camkes.c文件中,会新增同步原语函数定义
说明1:同步原语template文件
同步原语的template文件为projects/camkes-tool/camkes/templates/component.common.c
可见生成同步原语的代码都是通过for循环遍历component类型中的相关实例定义,之后生成操作函数
补充:从同步原语的template文件可知,configuration中配置的信号量和二值信号量的初始值是以python中字典的键值对形式存储的。如果不进行配置,则是使用字典get方法的默认值
关于python字典的相关内容,可参考如下笔记的chapter 4
Python程序设计语言基础06(完):组合数据类型_麦小兜的博客-CSDN博客
说明2:同步原语初始化时机
如上文所述,在component类型中增加了同步原语实例定义后,会在camkes.c文件中生成相关操作函数,而其中的init函数的调用是在camkes的平台初始化函数中
说明3:同步原语操作的实现
实现同步原语使用的函数由projects/seL4_libs/libsel4sync库实现
我们来看一下如下几个函数的实现
① sync_mutex_init函数
② sync_sem_init函数
③ sync_bin_sem_init函数
seL4操作系统基础05:event interface与seL4Notification connector相关推荐
- seL4操作系统基础06:dataport interface与seL4SharedData connector
目录 1 示例程序分析 1.1 示例程序结构 1.2 CMakeList.txt文件分析 1.3 component类型定义 1.3.1 dataport interface概述 1.3.2 data ...
- seL4操作系统基础01:seL4 whitepaper概览
目录 Chapter 1:What Is SeL4 Chapter 2:SeL4 Is a Microkernel and Hypervisor, It Is Not an OS 2.1 微内核结构 ...
- seL4操作系统基础02:从Hello World开始
目录 1 实验环境部署 1.1 Ubuntu环境搭建 1.2 实验代码下载 1.3 实验代码使用方法 1.3.1 提取实验代码 1.3.2 编译实验代码 1.3.3 运行实验代码 2 Hello Wo ...
- 服务器开发系列(三)——Linux与Windows操作系统基础功能对比
系列文章目录 服务器开发系列(一)--计算机硬件 服务器开发系列(二)--Jetson Xavier NX 文章目录 系列文章目录 前言 一.操作系统概述 二.Linux和Windows的应用场景 三 ...
- 计算机和操作系统基础知识
-----------------------siwuxie095 计算机和操作系统基础知识 1.操作系统(Operating System,简称 OS),是管理计算机硬件与 软件资源的计算机程序,同 ...
- 计算机与操作系统基础小结
计算机基础概念 1946年二月美国,世界上第一台电子计算机ENIAC诞生,似乎从这一年开始世界便逐渐变得不一样了.随着半个世纪的时间,计算机技术蓬勃发展,推动人类进入信息社会. 计算机操作界面: ①图 ...
- 干货!操作系统基础知识汇总!转给要面试的同学吧
作者:Guide哥 来源:公众号 JavaGuide 很多读者抱怨计算操作系统的知识点比较繁杂,自己也没有多少耐心去看,但是面试的时候又经常会遇到.所以,我带着我整理好的操作系统的常见问题来啦!这篇文 ...
- 【重难点】【Java基础 05】说一说你平时遇到的异常、什么情景下会用到反射、反射的底层原理
[重难点][Java基础 05]说一说你平时遇到的异常.什么情景下会用到反射.反射的底层原理 文章目录 [重难点][Java基础 05]说一说你平时遇到的异常.什么情景下会用到反射.反射的底层原理 一 ...
- Linux_操作系统-基础操作-教学
Linux操作系统基础教程 前言.................................................................................... ...
最新文章
- 隐马尔可夫模型(Hidden Markov Model,HMM)是什么?隐马尔可夫模型(Hidden Markov Model,HMM)的三个基本问题又是什么?
- 深入理解java异常处理机制
- Selector SelectionKey
- ASP.NET MVC 简单的分页思想与实现
- python json unicode_python2下解决json的unicode编码问题
- 完美:C# Blazor中显示Markdown并添加代码高亮
- 集卡php源码,独角数卡自动发卡网PHP源码+教程:虚拟产品自助售卖
- 【51Nod - 1163】最高的奖励 (贪心+优先队列 或 妙用并查集)
- 遇到:ORA-27121: UNABLE TO DETERMINE SIZE OF SHAR...
- “让天下没有难开的店”,宣言来自无人车公司AutoX
- SQL函数学习 之 DENSE_RANK() OVER (PARTITION BY col2 ORDER BY col3 DESC) AS seq
- 【Python实例第1讲】交叉验证预测曲线的画法
- 概率论与数理统计 第四版 浙江大学 盛骤,谢式千,潘承毅 个人阅读笔记
- JAVA中LIST 和 MAP的区别
- 公司内网限制qq微信登陆--解决办法
- MATLAB读取10bit的raw格式图片代码
- Mac解决mysql stop报错问题:The /usr/local/mysql/data directory is not owned by the ‘mysql‘ or ‘_mysql‘
- 三天打鱼两天晒网--捕鱼小游戏
- 10个比Visio更好的流程图制作软件
- Android USB 主机模式
热门文章
- 元胞自动机交通流模型c++_MATLAB——含出入匝道的交织区快速路元胞自动机模型...
- java笔_JAVA笔试题(基础一)
- Python 包管理工具poetry配置国内PyPI镜像源
- php 正则匹配中文标点,JavaScript_js实现正则匹配中文标点符号的方法,本文实例讲述了js正则匹配中 - phpStudy...
- Oracle expdp和impdp
- vue ---- webpack - devServer节点
- 设置Cookie请求头报错(Refused to set unsafe header “Cookie“)
- Mysql合并两个sql结果
- rabbitmq页面出现/etc/rabbitmq/rabbitmq.config(not found)解决方法
- RedisTemplate存数据时指定过期时间