linux 2.6源代码情景分析笔记之进程4
来源:互联网 发布:苍穹变坐骑5-6进阶数据 编辑:程序博客网 时间:2024/04/27 23:32
散列(hash)函数并不总能确保pid与表索引一一对应。两个不同的pid散列到相同的表索引称为冲突(colliding),linux利用链表来处理冲突的pid,每一个表项是由冲突的进程描述符组成的双向链表。
pid散列表的数据结构解决了所有这些难题,他们可以为包含在一个散列表中的任何pid号定义进程链表。最主要的数据结构是四个pid结构的数组,它在进程描述符的pid字段中。
struct pid
{
/* Try to keep pid_chain in the same cacheline as nr for find_pid */
int nr;pid的数值
struct hlist_node pid_chain;/* list of pids with the same nr, only one of them is in the hash */链接散列链表的下一个和前一个元素
struct list_head pid_list;每个pid的进程链表头
};
基本运作:pid_hash中的四个基本类型表头找到tgid哈希表,然后找到对应表项再进一步找到进程描述符中的pid_chain字段,然后进一步找到process descriptor中的pid_chain表项,然后找到哈希表。
处理pid散列表的函数和宏:
#define do_each_task_pid(who, type, task) /
if ((task = find_task_by_pid_type(type, who))) { /
prefetch((task)->pids[type].pid_list.next); /
do {
#define while_each_task_pid(who, type, task) /
} while (task = pid_task((task)->pids[type].pid_list.next,/
type), /
prefetch((task)->pids[type].pid_list.next), /
hlist_unhashed(&(task)->pids[type].pid_chain)); /
} /
#endif
标记do-while循环的开始和结束,循环作用于在pid值等于nr的pid链表上,链表的类型由参数type给出,task参数指向当前被扫描的元素的进程描述符。
在type类型的散列表中查找pid等于nr的进程。该函数返回所匹配的进程描述符指针。
task_t *find_task_by_pid_type(int type, int nr)
{
struct pid *pid;
pid = find_pid(type, nr);
if (!pid)
return NULL;
return pid_task(&pid->pid_list, type);
}
struct pid * fastcall find_pid(enum pid_type type, int nr)
{
struct hlist_node *elem;
struct pid *pid;
hlist_for_each_entry(pid, elem,
&pid_hash[type][pid_hashfn(nr)], pid_chain) {
if (pid->nr == nr)
return pid;
}
return NULL;
}
#define pid_task(elem, type) list_entry(elem, struct task_struct, pids[type].pid_list)
把task指向的pid等于nr的进程描述符插入type类型的散列表中。如果一个pid等于nr的进程描述符已经在散列表中,这个函数就只把task插入已有的pid进程链表中。
int fastcall attach_pid(task_t *task, enum pid_type type, int nr)
{
struct pid *pid, *task_pid;
" ============================================================================
" Netrw Directory Listing (netrw v132)
" /home/mxy/linux11/arch
" Sorted by name
" Sort sequence: [//]$,/.h$,/.c$,/.cpp$,*,/.o$,/.obj$,/.info$,/.swp$,/.bak$,/~$
" Quick Help: <F1>:help -:go up dir D:delete R:rename s:sort-by x:exec
" ============================================================================
../
alpha/
arm/
arm26/
cris/
frv/
h8300/
i386/
ia64/
m32r/
m68k/
m68knommu/
mips/
parisc/
ppc/
ppc64/
s390/
sh/
sh64/
sparc/
sparc64/
um/
v850/
x86_64/
task_pid = &task->pids[type];
pid = find_pid(type, nr);
if (pid == NULL) {
hlist_add_head(&task_pid->pid_chain,
&pid_hash[type][pid_hashfn(nr)]);
INIT_LIST_HEAD(&task_pid->pid_list);
} else {
INIT_HLIST_NODE(&task_pid->pid_chain);
list_add_tail(&task_pid->pid_list, &pid->pid_list);
}
task_pid->nr = nr;
return 0;
}
从type类型的pid进程链表中删除task所指向的进程描述符。如果删除后pid进程链表没有变为空,则函数终止,否则该函数还要从type类型的散列表中删除进程描述符。最后如果pid值没有出现在任何其他的散列表中,为了这个值能够被反复使用,该函数还必须清除pid位图中的相应位。
void fastcall detach_pid(task_t *task, enum pid_type type)
{
int tmp, nr;
nr = __detach_pid(task, type);
if (!nr)
return;
for (tmp = PIDTYPE_MAX; --tmp >= 0; )
if (tmp != type && find_pid(tmp, nr))
return;
free_pidmap(nr);
}
static fastcall int __detach_pid(task_t *task, enum pid_type type)
{
struct pid *pid, *pid_next;
int nr = 0;
pid = &task->pids[type];
if (!hlist_unhashed(&pid->pid_chain)) {
hlist_del(&pid->pid_chain);
if (list_empty(&pid->pid_list))
nr = pid->nr;
else {
pid_next = list_entry(pid->pid_list.next,
struct pid, pid_list);
/* insert next pid from pid_list to hash */
hlist_add_head(&pid_next->pid_chain,
&pid_hash[type][pid_hashfn(pid_next->nr)]);
}
}
list_del(&pid->pid_list);
pid->nr = 0;
return nr;
}
- linux 2.6源代码情景分析笔记之进程4
- linux 2.6源代码情景分析笔记之进程1
- linux 2.6源代码情景分析笔记之进程2
- linux 2.6源代码情景分析笔记之进程3
- linux 2.6源代码情景分析笔记之进程5
- linux 2.6源代码情景分析笔记之进程6
- linux 2.6源代码情景分析笔记之进程7
- linux 2.6源代码情景分析笔记之进程8
- linux 2.6源代码情景分析笔记之进程9
- linux 2.6源代码情景分析笔记之进程10
- linux 2.6源代码情景分析笔记之进程11
- linux 2.6源代码情景分析笔记之系统启动1
- linux 2.6源代码情景分析笔记之系统启动2
- linux 2.6源代码情景分析笔记之系统启动
- linux 2.6源代码情景分析笔记之内存4
- linux 2.6源代码情景分析笔记之中断与异常4
- linux 2.6源代码情景分析笔记之内存1
- linux 2.6源代码情景分析笔记之内存2
- 移动通信信道中三种典型衰落
- 多径传输的特性
- linux 2.6源代码情景分析笔记之进程3
- 分集接收
- 微软免费杀毒软件Morro即将发布
- linux 2.6源代码情景分析笔记之进程4
- PHP 变量和常量的定义
- 访问PHP类中成员变量或方法
- 看了篇文章感觉很好
- linux 2.6源代码情景分析笔记之进程5
- DELL电脑安装Windows7
- xp无法访问网上邻居的解决办法
- 日志声明
- 网络校时 附Python源码及几个标准时间服务器