初始化
struct hlist_head {
struct hlist_node *first;
};
static struct hlist_head *pid_hash;
static unsigned int pidhash_shift = 4;
void __init pidhash_init(void)
{
int i, pidhash_size;
pid_hash = alloc_large_system_hash("PID", sizeof(*pid_hash), 0, 18,
HASH_EARLY | HASH_SMALL,
&pidhash_shift, NULL, 4096);
pidhash_size = 1 << pidhash_shift;
for (i = 0; i < pidhash_size; i++)
INIT_HLIST_HEAD(&pid_hash[i]);
}
操作之添加元素
void attach_pid(struct task_struct *task, enum pid_type type,
struct pid *pid)
{
struct pid_link *link;
link = &task->pids[type];
link->pid = pid;
hlist_add_head_rcu(&link->node, &pid->tasks[type]);
=>static inline void hlist_add_head_rcu(struct hlist_node *n,
struct hlist_head *h)
{
struct hlist_node *first = h->first;
n->next = first;
n->pprev = &h->first;
rcu_assign_pointer(h->first, n);
if (first)
first->pprev = &n->next;
}
}
根据进程号搜索进程
struct task_struct *find_task_by_vpid(pid_t vnr)
{
return find_task_by_pid_ns(vnr, task_active_pid_ns(current));
=>struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
{
return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
=>struct pid *find_pid_ns(int nr, struct pid_namespace *ns)
{
struct hlist_node *elem;
struct upid *pnr;
hlist_for_each_entry_rcu(pnr, elem,
&pid_hash[pid_hashfn(nr, ns)], pid_chain)
if (pnr->nr == nr && pnr->ns == ns)
return container_of(pnr, struct pid,
numbers[ns->level]);
=>#define pid_hashfn(nr, ns) hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift) // 2.6.34版本用哈希表, 4.16.3版本用基树了
return NULL;
}
}
}
Linux内核 hlist_head/hlist_node结构解析
https://www.cnblogs.com/vinozly/p/5707166.html
Linux 内核 hlist 详解
https://blog.csdn.net/hs794502825/article/details/24597773/
Linux内核中哈希链表hlist_head
https://blog.csdn.net/hhhhhyyyyy8/article/details/102642220
Linux内核中的PID散列表实例
http://blog.chinaunix.net/uid-24227137-id-3630753.html