进程fork处理

来源:互联网 发布:沃尔玛的物流网络 编辑:程序博客网 时间:2024/05/28 01:34
进程或者线程创建do_fork
 
/* For compatibility with architectures that call do_fork directly rather than * using the syscall entry points below. */long do_fork(unsigned long clone_flags,       unsigned long stack_start,       unsigned long stack_size,       int __user *parent_tidptr,       int __user *child_tidptr){ return _do_fork(clone_flags, stack_start, stack_size,   parent_tidptr, child_tidptr, 0);}

/* *  Ok, this is the main fork-routine. * * It copies the process, and if successful kick-starts * it and waits for it to finish using the VM if required. */long _do_fork(unsigned long clone_flags,       unsigned long stack_start,       unsigned long stack_size,       int __user *parent_tidptr,       int __user *child_tidptr,       unsigned long tls){ struct task_struct *p; int trace = 0; long nr;

 /*  * Determine whether and which event to report to ptracer.  When  * called from kernel_thread or CLONE_UNTRACED is explicitly  * requested, no event is reported; otherwise, report if the event  * for the type of forking is enabled.  */ if (!(clone_flags & CLONE_UNTRACED)) {  if (clone_flags & CLONE_VFORK)   trace = PTRACE_EVENT_VFORK;  else if ((clone_flags & CSIGNAL) != SIGCHLD)   trace = PTRACE_EVENT_CLONE;  else   trace = PTRACE_EVENT_FORK;

  if (likely(!ptrace_event_enabled(current, trace)))   trace = 0; }

 p = copy_process(clone_flags, stack_start, stack_size,    child_tidptr, NULL, trace, tls, NUMA_NO_NODE); add_latent_entropy(); /*  * Do this prior waking up the new thread - the thread pointer  * might get invalid after that point, if the thread exits quickly.  */ if (!IS_ERR(p)) {  struct completion vfork;  struct pid *pid;

  trace_sched_process_fork(current, p);

  pid = get_task_pid(p, PIDTYPE_PID);  nr = pid_vnr(pid);

  if (clone_flags & CLONE_PARENT_SETTID)   put_user(nr, parent_tidptr);

  if (clone_flags & CLONE_VFORK) {   p->vfork_done = &vfork;   init_completion(&vfork);   get_task_struct(p);  }

  wake_up_new_task(p);

  /* forking complete and child started to run, tell ptracer */  if (unlikely(trace))   ptrace_event_pid(trace, pid);

  if (clone_flags & CLONE_VFORK) {   if (!wait_for_vfork_done(p, &vfork))    ptrace_event_pid(PTRACE_EVENT_VFORK_DONE, pid);  }

  put_pid(pid); } else {  nr = PTR_ERR(p); } return nr;}

 
0 0