In this post, we discuss the process through which a child process is created. This child process shares everything with the parent process including the open file descriptors, memory, the executable etc. If the process wants to load a new executable in the child process, then execve call has to be made. This will be discussed later.
A new process is created when a old process executes a fork(). The new process is an exact copy of the old process. (Who creates the first process? I am tempted to say god, but I would rather speak thruth. The first process is the init process which is literally created from scratch during booting).
There are many library functions which are used for forking (e.g, clone(), vfork() etc). These calls manage to call a system call (sys_fork) which in turn calls a function within the kernel, do_fork. do_fork is called along with a host of flags to indicate the characteristics required of the child process.
The do_fork starts off with getting a new PID. This is done using alloc_pidmap(). The alloc_map allocates a new PID after checking the pidmap_array (which is has a bit set for each PID). The search is started from last+1, and the PID is checked against the pidmap_array. The PID which is free is returned to the do_fork and last is also set to this value.
Under normal conditions, the do_fork copies the task_struct of the calling process to be used for the child process. The process is copied by the function copy_process(). The task_struct is created using sup_task_struct().
The dup_task_struct() gets memory for both task_struct and thread_info, copies the parents thread_info and task_struct into the newly created structures. Only the thread_info field in the new struct is referred to the new thread_info and the task_struct field in the new thread_info is referenced to new task_struct.
The copy process is more interesting:
- It first creates the task_struct for use by the new process. (This is done using dup_task_struct() ).
- Various fields like flags are copied from the old process structure.
- Scheduler related operations are done using sched_fork().
- copy_mm() copies the virtual memory for the new process. Copy_mm() just copies the oldmm (mm of curren tsk) into the new mm and returns.
The task is now ready for running.
The newly allocated task_struct is then scheduled in the run_queue but is not yet activated. The function returns to the caller which then decides to call the scheduler.
The wake_up_new_task() is called which adds the process descriptor to the runqueues so that the task can be scheduled.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment