穷究链表(十)

  今天来看看C实现的链表的经典,也就是linux内核中使用的链表形式。内核代码是在www.kernel.org/处下载的。这里选择了最新的源码包进行下载,为linux-2.6.31.1。其实链表作为最常用的数据结构,应该是变化不大的,虽然没有比较过,但是如果你下载2.4的内核代码,链表部分应该还是一样的。

  为了更好的分析代码,这里使用了source insight来辅助分析。主要分析两个文件:list.h和8250.c。

  其实linux作为一个大的系统,读它的确是比较困难的。但是如果说其中有什么特别高深的东西,也并不一定,都是一行一行写出来的,而其中的原理,在一般的OS书中也都涉及到了。更底层的东西,在CPU厂商的体系结构手册中,我们也基本不用关心。将其中抽出一部分来看看,还应该是不太难的。关键还是使用,以及考虑全面。

 

list.h (\linux-2.6.31.1\linux-2.6.31.1\include\linux\list.h)

8250.c (driver/serial/8250.c)

因为整个文件比较长,list.h中有list_head与hlist_head,一共有710行;而8250.c为串口驱动程序,一共有3249行。肯定是不可能像前面一样列出来。而且本人的水平也不可能将其讲解清楚,而且时间也不允许我现在慢慢折腾,做到了然于心

 

这里尽量将其情况大概描述一遍,等以后如果有项目做到相关,可以再理解添加。

list.h中使用了list_head来做一个“简单的双向链表的实现”,还有一个hlist_head,为“Double linked lists with a single pointer list head.”主要用于哈希表,前面一个有些了解,后面那个也是刚刚接触,所以这里后面这个就简单提一下,以免自己理解不深刻,误导大家。

而8250.c中就是使用这两个结构,主要使用函数为:

INIT_LIST_HEAD

list_add

list_del

list_empty

list_entry

hlist_del

hlist_add_head

hlist_entry

hlist_for_each

一目了然,带h头的为hlist专用,其他为list使用。

 

在list.h中可以注意到,所有的函数都是使用的static inline的,而其他则是使用宏。在内核中,为了效率,使用这些来减少函数调用的开销是必要的。

 

其实代码也比较简单,这里也就不讲了。主要有一个hack一点的地方

#define list_entry(ptr, type, member) \

    container_of(ptr, type, member)

这里调用的container_of为

/**

 * container_of - cast a member of a structure out to the containing structure

 * @ptr:    the pointer to the member.

 * @type:   the type of the container struct this is embedded in.

 * @member: the name of the member within the struct.

 *

 */

#define container_of(ptr, type, member) ({          \

    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \

    (type *)( (char *)__mptr - offsetof(type,member) );})

该宏可以在kernel.h中找到,算是比较hack一些的地方。

offsetof宏可以在stddef.h中找到:

#undef offsetof

#ifdef __compiler_offsetof

#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)

#else

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#endif

 

其他可以自己看看,也就是链表添加删除操作。

 

到这里为止,关于C的部分就结束了,下面就开始写C++如何制作链表程序,写得不好,大家见谅。最近事多心烦,不想在链表上花费太多时间了。赶紧结束,然后进入递归的部分。

posted on 2009-10-20 20:16  cnyao  阅读(383)  评论(0编辑  收藏  举报