《TCP/IP详解 卷2:实现》 —2.5 简单的mbuf宏和函数
2.5 简单的mbuf宏和函数
有20多个宏和函数用来处理mbuf(分配一个mbuf,释放一个mbuf,等等)。让我们来查看几个宏与函数的源代码,看看它们是如何实现的。
有些操作既提供了宏也提供了函数。宏版本的名称是以M开头的大写字母名称,而函数是以m_开始的小写字母名称。两者的区别是一种典型的时间-空间互换。宏版本在每个被用到的地方都被C预处理器展开(要求更多的代码空间),但是它在执行时更快,因为它不需要执行函数调用(对于有些体系结构,这是费时的)。而对于函数版本,它在每个被调用的地方变成了一些指令(参数压栈,调用函数等),要求较少的代码空间,但会花费更多的执行时间。
2.5.1 m_get函数
让我们先看一下图2-11中分配mbuf的函数:m_get。这个函数仅仅就是宏MGET的展开。
图2-11 m_get函数:分配一个mbuf
注意,Net/3代码不使用ANSI C参数声明。但是,如果使用一个ANSI C编译器,所有Net/3系统头文件为所有的内核函数都提供了ANSI C函数原型。例如,<sys/mbuf.h>头文件中包含这样的行:
struct mbuf *m_get(int, int);
这些函数原型为所有内核函数的调用提供编译期间的参数与返回值的检查。
这个调用表明参数nowait的值为M_WAIT或M_DONTWAIT,它取决于在存储器不可用时是否要求等待。例如,当插口层请求分配一个mbuf来存储sendto系统调用(图1-6)的目标地址时,它指定M_WAIT,因为在此阻塞是没有问题的。但是当以太网设备驱动程序请求分配一个mbuf来存储一个接收的帧时(图1-10),它指定M_DONTWAIT,因为它是作为一个设备中断处理来执行的,不能进入睡眠状态来等待一个mbuf。在这种情况下,若存储器不可用,设备驱动程序丢弃这个帧比较好。
- 点赞
- 收藏
- 关注作者
评论(0)