(莱昂氏unix源代码分析导读-49) 字符缓冲区
by cszhao1980
同块设备一样,对字符设备的输入输出也是通过缓冲区来进行的。使用缓冲区有个额外
的好处,即以缓冲区为界,函数可分为高低两个层次。低层函数负责与实际设备交互,
而高层函数只与缓冲区打交道,只对缓冲区存取数据,这样可以蔽掉掉底层的许多细节。
对于字符缓冲区,有两个最重要结构,即cblock和clist。前者是缓冲区本身,后者则用作
字符链表(队列)的头结点。莱昂在第23章中详细介绍了这两个struct,并对字符链表的
增删操作作了详细的分析,请您务必仔细阅读第23章的说明。
系统共有NCLIST个缓冲区资源:
8146: struct cblock cfree[NCLIST]
空闲的缓冲区都被链接在cfreelist链表中。
Cinit函数使用头插法建立cfreelist链表,该函数比较令人费解的是第8240行的for循环——该条
语句的作用是,使每个实际使用的缓冲区的起始地址都能够被8整除。莱昂其实已经说明了这
样做的原因,即这样设置之后,可以通过地址模除8的方式来判断clist的头尾指针是否移出了
一个缓冲区边界。
getc和putc函数分别用来从缓冲区链表中get和put char。奇怪的是,unix v6选择使用汇编来实现
这两个函数——也许是出于性能的考虑吧。
getc函数有一个参数,即缓冲区链表的头结点地址。
(1)第936行将first ptr放入r2;
(2) 937行:如果头结点的first ptr为NULL(表示缓冲区已空),则跳到Label 9,返回-1;
(3) 938行:取first ptr指向的一个byte,放入r0(作为返回值);
注意,这里使用的movb指令以byte为单位进行操作,r2会后移1个byte,而不是word。
(4) 940行:将first ptr后移一个byte。
接下来的处理分为3种情况:
i.缓冲区链表已空;
此时,无需后续处理,直接从Label“3:”处返回即可。
ii.first ptr移出了当前缓冲区边界;
iii.first ptr仍在当前缓冲区内;
这两种情况需要后续处理,即调整first ptr,并释放用完的缓冲区。
putc函数有两个参数:
(1) 要放入缓冲区链表的char;
(2) 缓冲区链表头结点地址。
同getc不同,该函数在当前缓冲区链表满时,需要申请空闲缓冲区——当无空闲缓冲区可
用时,操作会失败,会通过Label 9返回非0数据。函数有几个重要的判断:
(1) 976: 当前缓冲链表是否为空(只有头结点);
(2) 978: 系统中是否还有空闲缓冲区;
(3) 984: 当前缓冲区是否已经写满
【注】:从putc函数可知,clist的last ptr指向的其实并不是缓冲链表内最后一个char,而是该
char的下一个byte。如果没有跨越缓冲区边界,则此byte可用于存放下一个char,否则,表示
缓冲链表已满,需要新申请一个缓冲区。
博客地址:http://blog.csdn.net/cszhao1980
博客专栏地址:http://blog.csdn.net/column/details/lions-unix.html
(莱昂氏unix源代码分析导读-49) 字符缓冲区的更多相关文章
- (莱昂氏unix源代码分析导读-50)LP11行式打印机
by cszhao1980 LP11有两个设备寄存器:状态寄存器(lpsr)和数据缓冲寄存器(lpbuf),可通过以下结构进行访问: 8812: #define LPADDR 0177514 8823 ...
- struts2请求过程源代码分析
struts2请求过程源代码分析 Struts2是Struts社区和WebWork社区的共同成果.我们甚至能够说,Struts2是WebWork的升级版.他採用的正是WebWork的核心,所以.Str ...
- 转:RTMPDump源代码分析
0: 主要函数调用分析 rtmpdump 是一个用来处理 RTMP 流媒体的开源工具包,支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps://. ...
- hostapd源代码分析(二):hostapd的工作机制
[转]hostapd源代码分析(二):hostapd的工作机制 原文链接:http://blog.csdn.net/qq_21949217/article/details/46004433 在我的上一 ...
- 【转载】linux环境下tcpdump源代码分析
linux环境下tcpdump源代码分析 原文时间 2013-10-11 13:13:02 CSDN博客 原文链接 http://blog.csdn.net/han_dawei/article/d ...
- Hadoop源代码分析
http://wenku.baidu.com/link?url=R-QoZXhc918qoO0BX6eXI9_uPU75whF62vFFUBIR-7c5XAYUVxDRX5Rs6QZR9hrBnUdM ...
- linux环境下tcpdump源代码分析
Linux 环境下tcpdump 源代码分析 韩大卫@吉林师范大学 tcpdump.c 是tcpdump 工具的main.c, 本文旨对tcpdump的框架有简单了解,只展示linux平台使用的一部分 ...
- Android系统进程Zygote启动过程的源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6768304 在Android系统中,所有的应用 ...
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6664554 在上一文章Android系统匿名共 ...
随机推荐
- 可视化配置以及Net应用MemCache在win7
MemCache在win7上的可视化配置以及Net应用 惯例科普:MemCache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以 ...
- sharepoint 2013 配件控制FileUpload如何检查是否图像的方法
它记录的附件控制FileUpload如何检查是否图像的方法: function checkImg() { var fileObj =document.getElementById('<%=Fil ...
- 读取xml文件"分析 EntityName 时出错"的解决方案
在涉及到xml与xslt编程的过程中,经常会碰到"分析 EntityName 时出错"的提示,这个不是程序错误,是因为xml文件中使用了一些特殊符号导致的. XML 节点中不 ...
- javascript系列之DOM(一)
原文:javascript系列之DOM(一) DOM(document object moudle),文档对象模型.它是一个中立于语言的应用程序接口(API),允许程序访问并修改文档的结构,内容和样式 ...
- c++的string容器
c++相比c的一个好处就是实现了很多的容器和泛型算法,使得程序员的工作得到了很大的化简.其中一个很有用的泛型容器就是string.string是一个类,是一个在STL里边实现好了的类,由于他的很多功能 ...
- 经典算法题每日演练——第八题 AC自动机
原文:经典算法题每日演练--第八题 AC自动机 上一篇我们说了单模式匹配算法KMP,现在我们有需求了,我要检查一篇文章中是否有某些敏感词,这其实就是多模式匹配的问题. 当然你也可以用KMP算法求出,那 ...
- 乐视TV2015校园招聘A第二个大的发行量(of中国Academy科学大学站)
标题叙述性说明:鉴于阵列A,尺寸n,数组元素1至n数字.但是一些数字多次出现.有些数字不出现.请设计算法和程序,统计数据不会出现什么.什么号码多次出现.在O(n)时间复杂度,O(1)在完成它的空间复杂 ...
- python_基础学习_03_正则替换文本(re.sub)
python的正则表达式模块是re,替换相关的方法是sub. 例如我们要做如下的替换将所有的 替换为空格,可以通过下面代码实现: import re input = 'hello world' #第一 ...
- POJ 1006 Biorhythms 中国的法律来解决剩余的正式
这个问题以前用模拟的方法来解决亚军,正如溶液是一个通用的解决方案. 这里使用数学方法:剩下的孙子法(当然,被称为中国剩余法).由于建议的孙子.所以也承认外国的孙子是数学家. 参考数论建议大家学习的专业 ...
- swift 注意事项 (十六) —— 可选链
可选链(Optional Chaining) 我们都知道"可选型"是什么.那么可选链又是什么,举个样例解释一下: struct MyName{ var name } st ...