Linux内核Hash Table结构及神奇的container_of宏

Linux内核Hash Table结构

近期在学习linux内核netfilter框架中有关conntrack和分片重组相关的代码过程中,顺便学习到了内核中hash表的结构。在此记录一下。
内核中hash表的定义:

		struct  hlist_head{
				struct hlist_node *first;
		}
		
		struct  hlist_node {
		        struct hlist_node *next,**pprev;
		} 
  1. hlist_head表示哈希表的头结点。哈希表中每一个entry(list_entry)所对应的都是一个链表(hlist).hlist_head结构体只有一个域,即first。First指针指向该hlist链表的第一个结点。
  2. hlist_node结构体有两个域,next和pprev。
    (1)next指向下个hlist_node结点,倘若该结点是链表的最后一个节点,next则指向NULL
    (2)pprev是一个二级指针,它指向前一个节点的next指针。

更详细的内核Hash Table相关的

注意:hlist_node hash表节点的结构体中只有其他节点的指针信息,即只有表本身所需的结构,没有额外空间存储Value信息。那么使用hash记录信息是,信息存储到哪了呢?或者说找到了hash节点,又怎么能找到相关联的信息呢?
内核提供了container_of宏来解决上面提出的疑问。具体实现是:hash节点(hlist_node)可作为另一结构体A的成员,A中的其他成员用于存储必要的信息。通过Hash表查询到hlist_node的地址后,container_of宏可以通过hlist_node的地址得到其父结构体A的地址。

container_of宏

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) ({				\
	void *__mptr = (void *)(ptr);					\
	BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) &&	\
			 !__same_type(*(ptr), void),			\
			 "pointer type mismatch in container_of()");	\
	((type *)(__mptr - offsetof(type, member))); })

猜你喜欢

转载自blog.csdn.net/eyz12315/article/details/86592528