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) 字符缓冲区的更多相关文章

  1. (莱昂氏unix源代码分析导读-50)LP11行式打印机

    by cszhao1980 LP11有两个设备寄存器:状态寄存器(lpsr)和数据缓冲寄存器(lpbuf),可通过以下结构进行访问: 8812: #define LPADDR 0177514 8823 ...

  2. struts2请求过程源代码分析

    struts2请求过程源代码分析 Struts2是Struts社区和WebWork社区的共同成果.我们甚至能够说,Struts2是WebWork的升级版.他採用的正是WebWork的核心,所以.Str ...

  3. 转:RTMPDump源代码分析

    0: 主要函数调用分析 rtmpdump 是一个用来处理 RTMP 流媒体的开源工具包,支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps://. ...

  4. hostapd源代码分析(二):hostapd的工作机制

    [转]hostapd源代码分析(二):hostapd的工作机制 原文链接:http://blog.csdn.net/qq_21949217/article/details/46004433 在我的上一 ...

  5. 【转载】linux环境下tcpdump源代码分析

    linux环境下tcpdump源代码分析 原文时间 2013-10-11 13:13:02  CSDN博客 原文链接  http://blog.csdn.net/han_dawei/article/d ...

  6. Hadoop源代码分析

    http://wenku.baidu.com/link?url=R-QoZXhc918qoO0BX6eXI9_uPU75whF62vFFUBIR-7c5XAYUVxDRX5Rs6QZR9hrBnUdM ...

  7. linux环境下tcpdump源代码分析

    Linux 环境下tcpdump 源代码分析 韩大卫@吉林师范大学 tcpdump.c 是tcpdump 工具的main.c, 本文旨对tcpdump的框架有简单了解,只展示linux平台使用的一部分 ...

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

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

  9. Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6664554 在上一文章Android系统匿名共 ...

随机推荐

  1. Linux(CentOS)系统下安装好apache(httpd)服务后,其他电脑无法访问的原因

    原文:Linux(CentOS)系统下安装好apache(httpd)服务后,其他电脑无法访问的原因 今天试了下在虚拟机上利用CentOS系统的yum命令安装好了httpd(apache2.4.6), ...

  2. Mule ESB-Content-Based Routing Tutorial(2)

    承接 Mule ESB-Content-Based Routing Tutorial(1) 五.执行应用程序  完毕创建,配置.并保存你的新的应用程序,您就能够在嵌入Mule的server上执行(包含 ...

  3. 贪心算法(Greedy Algorithm)最小生成树 克鲁斯卡尔算法(Kruskal's algorithm)

    克鲁斯卡尔算法(Kruskal's algorithm)它既是古典最低的一个简单的了解生成树算法. 这充分反映了这一点贪心算法的精髓.该方法可以通常的图被表示.图选择这里借用Wikipedia在.非常 ...

  4. oracle修改表空间

    1.其中表中查找该表空间不正确 select * from dba_tables where tablespace_name='TDB'; 2.将表空间在 TDB 中的移到表空间 TDB2009 中 ...

  5. 国外android开源站点

    http://android-arsenal.com/

  6. 【MySQL案件】mysql登录-S失败

    1.1.1. mysql登录mysql时间,-S参数失效 [环境的叙述性说明] mysql5.5.14 [问题叙述性说明] 配置多个实例 实例1 实例2 datadir /home/mysql_330 ...

  7. Swift语言指南(一)--语言基础之常量和变量

    原文:Swift语言指南(一)--语言基础之常量和变量 Swift 是开发 iOS 及 OS X 应用的一门新编程语言,然而,它的开发体验与 C 或 Objective-C 有很多相似之处. Swif ...

  8. TRIZ系列-创新原理-28-替代机械系统原理

    替代机械系统原理的详细描写叙述例如以下:1)用光.声.热.嗅觉系统替代机械系统:2)用电.磁或电磁场来与物体交互作用:3)用移动场替代精巧场,用随时间变化的场替代固定场,用结构化的场替代随机场:4)使 ...

  9. DataTable与实体类的转换

    多年前写的DataTable与实体类的转换,已放github 阅读目录 介绍 起因 代码 UnitTest GitHub 介绍 很多年前一直使用Ado.net,后来慢慢转型到其他的orm,在转型过程中 ...

  10. 我的MYSQL学习心得(八)

    原文:我的MYSQL学习心得(八) 我的MYSQL学习心得(八) 我的MYSQL学习心得(一) 我的MYSQL学习心得(二) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) 我的MYSQL ...