Chinaunix首页 | 论坛 | 博客
  • 博客访问: 90578
  • 博文数量: 16
  • 博客积分: 1113
  • 博客等级: 少尉
  • 技术积分: 170
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-31 13:36
文章分类

全部博文(16)

文章存档

2011年(4)

2010年(12)

分类: LINUX

2010-08-11 20:56:13

重头戏来了!copy_process() 函数完成父进程描述符中相关资源到子进程中的复制工作,并对关键资源进行了修改,以标识新生成的子进程!

 

由于此函数非常之长,在此就不列出完整源代码,只对关键部分进行分析!

 

Let’s go!

 

static task_t *copy_process(unsigned long clone_flags,unsigned long stack_start,

struct pt_regs *regs,

                 unsigned long stack_size,

                 int __user *parent_tidptr,

                 int __user *child_tidptr,

                 int pid)

 

首先对参数 clone_flags 的合理性进行验证!

 

p = dup_task_struct(current);

 

复制一份当前进程的描述符的拷贝!

 

static struct task_struct *dup_task_struct(struct task_struct *orig)

{

    struct task_struct *tsk;

    struct thread_info *ti;

 

    prepare_to_copy(orig);

    在当前进程使用FPU的情况下,保存当前进程的FPU上下文内容到进程的成员变量 thread_info

 

    tsk = alloc_task_struct();

申请sizeof(struct task_struct) 大小内存空间,用作新创建进程的进程描述符!

 

# define alloc_task_struct()    kmem_cache_alloc(task_struct_cachep,GFP_KERNEL)

 

task_struct_cachep 高速缓存描述符中分配一个对象!

fork_init() 函数中 已经创建好了task_struct 结构专用的缓冲队列!

 

    if (!tsk)

        return NULL;

 

    ti = alloc_thread_info(tsk);

为新创建的进程申请 thread_info 结构所需的内存空间!

 

#define alloc_thread_info(tsk)                  \

    ({                          \

        struct thread_info *ret;            \

                                \

        ret = kmalloc(THREAD_SIZE, GFP_KERNEL);     \

        if (ret)                    \

            memset(ret, 0, THREAD_SIZE);        \

        ret;                        \

    })

 

从普通缓存中申请thread_info 大小的内存空间,并清0

 

    if (!ti) {

        free_task_struct(tsk);

        return NULL;

    }

 

    *ti = *orig->thread_info;

    将当前进程的thread_info 结构中内容赋值给新创建的进程的thread_info结构中(进程1)

 

    *tsk = *orig;

同样道理赋值task_struct 结构

 

    tsk->thread_info = ti;

修改新创建进程进程描述符的thread_info字段,使其指向新创建的thread_info结构!

 

    ti->task = tsk;

同样道理修改thread_info结构的 task 字段使其指向 tss_struct 结构!

 

    /* One for us, one for whoever does the "release_task()" (usually parent) */

    atomic_set(&tsk->usage,2);

    设置新创建子进程的进程描述符的引用计数usage2。其中一个代表本进程对该进程描述符的引用计数;另一个是父进程的引用计数

 

    return tsk;

}

阅读(1281) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~