linux内核中的几种链表


参考

双向循环链表 list_head

  • 相关文件:
    include/linux/list.h

  • 数据结构:

struct list_head {
	struct list_head *next, *prev;
};
  • 接口
static inline void INIT_LIST_HEAD(struct list_head *list);
static inline void list_add(struct list_head *new, struct list_head *head);
static inline void list_del(struct list_head *entry);

哈希链表 hlist

  • 相关文件:
    include/linux/list.h
    include/linux/hashtable.h

  • 数据结构

struct hlist_head {
	struct hlist_node *first;
};

struct hlist_node {
	struct hlist_node *next, **pprev;
};
  • 接口
static inline void hlist_del(struct hlist_node *n);
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h);
hlist_for_each_entry(pos, head, member)
  • 参考
    Linux 内核 hlist 详解
    linux内核分析--内核中使用的数据结构之哈希表hlist(三)

  • 应用

kernel/cgroup/cgroup.c
/*
 * hash table for cgroup groups. This improves the performance to find
 * an existing css_set. This hash doesn't (currently) take into
 * account cgroups in empty hierarchies.
 */
#define CSS_SET_HASH_BITS	7
static DEFINE_HASHTABLE(css_set_table, CSS_SET_HASH_BITS);

key = css_set_hash(cset->subsys);
hash_add(css_set_table, &cset->hlist, key);

降序优先排序的双向链表 plist

  • 相关文件
    include/linux/plist.h
    lib/plist.c

  • 数据结构

struct plist_head {
	struct list_head node_list;
};

struct plist_node {
	int			prio;
	struct list_head	prio_list;
	struct list_head	node_list;
};
  • 接口
static inline void plist_head_init(struct plist_head *head);
static inline void plist_node_init(struct plist_node *node, int prio);
void plist_add(struct plist_node *node, struct plist_head *head);
void plist_del(struct plist_node *node, struct plist_head *head);
  • 参考:
    Linux中的Plist -- 降序优先排序的双向链表

  • 应用

mm/swapfile.c
/*
 * all active swap_info_structs
 * protected with swap_lock, and ordered by priority.
 */
PLIST_HEAD(swap_active_head);

static void setup_swap_info(struct swap_info_struct *p, int prio,
			    unsigned char *swap_map,
			    struct swap_cluster_info *cluster_info)
{
	int i;

	if (prio >= 0)
		p->prio = prio;
	else
		p->prio = --least_priority;
	/*
	 * the plist prio is negated because plist ordering is
	 * low-to-high, while swap ordering is high-to-low
	 */
	p->list.prio = -p->prio;
	for_each_node(i) {
		if (p->prio >= 0)
			p->avail_lists[i].prio = -p->prio;
		else {
			if (swap_node(p) == i)
				p->avail_lists[i].prio = 1;
			else
				p->avail_lists[i].prio = -p->prio;
		}
	}
	p->swap_map = swap_map;
	p->cluster_info = cluster_info;
}

static void _enable_swap_info(struct swap_info_struct *p)
{
	p->flags |= SWP_WRITEOK | SWP_VALID;
	atomic_long_add(p->pages, &nr_swap_pages);
	total_swap_pages += p->pages;
	plist_add(&p->list, &swap_active_head);
	add_to_avail_list(p);
}

相关