前面的copy_process调用了一个dup_task_struct来复制一个task_struct,一下是该函数的主要工作:
1)为task_struct开辟内存
- tsk = alloc_task_struct_node(node);
2)为thread_info开辟内存
- ti = alloc_thread_info_node(tsk, node);
3) 复制父进程的task_struct信息到新的task_struct里
- err = arch_dup_task_struct(tsk, orig);
以下是arch_dup_task_struct的不同实现
- int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
- {
- *dst = *src;
- if (src->thread.xstate) {
- dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
- GFP_KERNEL);
- if (!dst->thread.xstate)
- return -ENOMEM;
- memcpy(dst->thread.xstate, src->thread.xstate, xstate_size);
- }
- return 0;
- }
- int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
- {
- int ret;
- *dst = *src;
- if (fpu_allocated(&src->thread.fpu)) {
- memset(&dst->thread.fpu, 0, sizeof(dst->thread.fpu));
- ret = fpu_alloc(&dst->thread.fpu);
- if (ret)
- return ret;
- fpu_copy(&dst->thread.fpu, &src->thread.fpu);
- }
- return 0;
- }
可以看到,两个函数里都有相同的一段 *dst = *src;这就是把复制父进程的task_struct到新进程的task_struct里。
这里主要完成orig到tsk复制的工作,然后再进行一些体系相关的工作
4)prop_local_init_single 这个暂时还没弄明白
5)setup_thread_stack 设置线程栈
这里面也有很多体系相关的东西,以下是主要的代码,首先把当前的thread_info设置成和父进程一样的,
然后,再把thread_info里的task设置成新生产的task_struct结构
- #define setup_thread_stack(p, org) \
- *task_thread_info(p) = *task_thread_info(org); \
- task_thread_info(p)->task = (p);
6)设置栈底魔数
- stackend = end_of_stack(tsk);
- *stackend = STACK_END_MAGIC; /* for overflow detection */
end_of_stack(tsk)用来获取tsk的栈底,然后将栈底的内容设置为STACK_END_MAGIC,用来标识栈底,防止栈被过度使用导致溢出。
阅读(3215) | 评论(0) | 转发(1) |