Chinaunix首页 | 论坛 | 博客
  • 博客访问: 541734
  • 博文数量: 140
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 650
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-11 19:00
文章存档

2015年(5)

2014年(135)

分类: LINUX

2014-03-05 20:54:23

一:kb_reserve函数会在缓冲区的头部预留一些空间,通常允许插入一个抱头,或者强迫数据对其某个边界。static inline voidskb_reserve(structsk_buff*skb,int len)
{
skb->data +=len;
skb->tail +=len;
}
二:函数skb_push会把一个数据块添加到缓冲区的开端,函数的代码为:
static inline unsigned char *__skb_push(struct sk_buff *skb,unsigned int len)
{
skb->data-=len;//将data向低地址移动
skb->len +=len;//重新分配缓冲区的长度
return skb->data;
}
三;函数skb_put这和skb_push函数的功能相反,是将数据块添加到缓冲区的末端
static inline unsigned shar *__skb_put(struct sk_buff *skb,unsigned int len)
{
unsigned char *tmp =skb_tail_pointer(skb);//得到数据块的长度
skb_linear_assert(skb);//改变相应的域,具体的我也不知道????
skb->tail +=len;//将tail指针移动len个单位
skb->len +=len;//len真加len个单位
return tmp;
}
static inline unsigned char *skb_tail_point(const struct sk_buff *skb)
{
return skb->head + skb->tail;//得到数据块的长度;
}
#define skb_LINEAR_ASSERT(skb) BUG_ON(skb_is_nonlinear(skb));
static inline int skb_is_nonlinear(const struct sk_buff *skb)
{
return skb->data_len;//返回数据块的长度
}
四:原子操作:
就是该操作绝不会在执行完毕前被任何其他任务或事件打断,也就说,它的最小的执行单位,不可能有比它更小的执行单位,因此这里的原子实际是使用了物理学里的物质微粒的概念。
原子操作需要硬件的支持,因此是架构相关的,其API和原子类型的定义都定义在内核源码树的include/asm/atomic.h文件中,它们都使用汇编语言实现,因为C语言并不能实现这样的操作。

原子操作主要用于实现资源计数,很多引用计数(refcnt)就是通过原子操作实现的,
typedef struct 
{
volatile int counter;
}atomic_t;
volatile修饰字段告诉gcc不要对该类型的数据做优化处理,对它的访问都是对内存的访问,而不是对寄存器的访问.
原子操作通常用于实现资源的引用计数,在TCP/IP协议栈的IP碎片处理中,就使用了引用计数,碎片队列结构struct ipq描述了一个IP碎片,字段refcnt就是引用计数器,它的类型为atomic_t,当创建IP碎片时(在函数ip_frag_create中),使用atomic_set函数把它设置为1,当引用该IP碎片时,就使用函数atomic_inc把引用计数加1。
阅读(626) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~