异想天开

What's the true meaning of light, Could you tell me why

linux源码情景分析阅读笔记1

日期:2014-03-29 17:44:01
  
最后更新日期:2015-07-14 22:08:25
好记性不如烂笔头,将这些东西记录下来,然后放空大脑,对于我而言,这样就更容易接受其他东西。笔记大概分为两种:1.条理性的笔记,注重体系以及脉络,忽略些细节或少量细节;2.细节笔记,这类笔记类似于资料保存在硬盘中一样,讲究完整性,以备cache不命中时候反刍。本系列属于第一种,工作之后,一来知识要灵活运用,细节是慢慢积累下来的,二则感觉时间并不是很充裕。将笔记整理到博客上,有个好处是,当你记笔记之前,你就知道了,这些可以放到博客上面提升逼格,那么将促进你更仔细的看书,记笔记。所以得出结论:用博客来笔记真是不错!
1.一些概念:
重入(reentrant):
重入的概念,与多线程里面访问公共的数据结构类似。内核中有可重入函数以及非可重入函数的概念,可重入函数就是仅修改局部变量的函数,而非重入函数则是可以修改全局数据结构函数。 内核控制路径(kernel control path):
一个程序的运行涉及到内核态以及用户态的转化,仅当发生了系统调用或中断时候,才进入内核态。内核控制路径,就是在系统调用或中断的时候,发生的调用序列。
2.内核中的链表数据结构
链表大概类似这样:
struct list_head {
struct list_head *pre;
struct list_head *nexe;
};
某个结构需要用到双向链表时,
struct foo {
...
struct list_head lru;
...
}bar;
通过链表指针在宿主结构的偏移来得出宿主结构的地址:假设知道双向链表的某个节点指针为ptr,那么宿主结构的地址可以这样计算:
[code lang="cpp"]
(struct foo*)((char*)ptr-(unsigned long)&(struct foo*)0->lru)
[/code]
另外一个小细节时,使用这种双向链表时,要求有个独守的链表头,这个点在这里没有上下文。
3.嵌入汇编
不如直接来一段:
[code lang="cpp"]
static __inline__ void atomic_add(int i, atomic_t *v)
{
__asm__ __volatile__(
LOCK "addl %1,%0"
:"=m" (v->counter)
:"ir" (i), "m" (v->counter));
}
[/code]
这个是从《linux源码情景分析》摘抄出来的。说到这个汇编,不得不有一点,我必须汗的,就是我知道A&T语法与intel语法的操作数的顺序是反的,具体哪个在左,哪个在右,每次都得从百度才知道。从上可以大概看出,gnu嵌入汇编的格式,“指令部分:输出部分:输入部分:修改部分”,同样是用冒号是分隔符。"=m",等号表示这是输出部分,区分输入部分,m表示是内存,%0表示输出以及输入中的第一个变量,在上例就是v->counter,“ir”表示是输入部分,immediate为直接操作数,同时后面没有加等号的m,表示是个输入的内存操作数,还是v->counter。为什么用汇编,上例告诉我们了一个原因:原子自增操作,要锁总线的(多核的体系结构下)。gcc直接产生的代码达不到这个效果。