《TCP/IP详解 卷2:实现》 —2.5.2 MGET宏
2.5.2 MGET宏
图2-12所示的是MGET宏。调用MGET来分配存储sendto系统调用(图1-6)的目标地址的mbuf如下所示:
MGET(m, M_WAIT, MT_SONAME);
if (m == NULL)
return(ENOBUFS);
图2-12 MGET宏
虽然调用指定了M_WAIT,但返回值仍然要检查,因为,如图2-13所示,等待一个mbuf并不保证它是可用的。
154-157 MGET一开始调用内核宏MALLOC,它是通用内核存储器分配器。数组mbtypes把mbuf的MT_xxx值转换成相应的M_xxx值(图2-10)。若存储器被分配,成员m_type被设置为参数中的值。
158 用于跟踪每种mbuf类型统计的内核结构加1(mbstat)。当执行这句时,宏MBUFLOCK把它作为参数来改变处理器优先级(图1-13),然后把优先级恢复为原值。这防止在执行语句mbstat.m_ mtypes[type]++;时被网络设备中断,因为mbuf可能在内核中的各层中被分配。考虑这样一个系统,它用三步来实现C中的一个++运算:(1)把当前值装入一个寄存器;(2)寄存器加1;(3)把寄存器值存入存储器。假设计数器值为77并且MGET在插口层执行。假设执行了步骤1和2(寄存器值为78),并且一个设备中断发生。若设备驱动也执行MGET来获得同种类型的mbuf,在存储器中取值(77),加1(78),并存回存储器。当被中断执行的MGET的步骤3继续执行时,它将寄存器的值(78)存入存储器。但是计数器应为79,而不是78,这样计数器就被破坏了。
159-160 两个mbuf指针m_next和m_nextpkt被设置为空指针。若必要,由调用者把这个mbuf加入一个链或队列。
161-162 最后,数据指针被设置为指向108字节的mbuf缓存的起始,而标志被设置为0。
163-164 若内核的存储器分配调用失败,调用m_retry(图2-13)。第一个参数是M_WAIT或M_DONTWAIT。
- 点赞
- 收藏
- 关注作者
评论(0)