Chapter 2: Process Management and Scheduling
associated invoked functions). For the sake of simplicity, I omitted these flags above. However, it should
be remembered that the differences between a classical process and a thread in the Linux kernel are
relatively fluid and both terms are often used as synonyms (threadis also frequently used to mean the
architecture-dependent part of a process as mentioned above). In this section, I concentrate on the flags
used by user thread libraries (above all, NPTL) to implement multithreading capabilities.
❑ CLONE_PARENT_SETTIDcopies the PID of the generated thread to a point in userspace specified in
theclonecall (parent_tidptr, the pointer is passed toclone)^12 :
kernel/fork.c
if (clone_flags & CLONE_PARENT_SETTID)
put_user(nr, parent_tidptr);
The copy operation is performed indo_forkbefore the task structure of the new thread is initial-
ized and before its data are created with thecopyoperations.
❑ CLONE_CHILD_SETTIDfirst causes a further userspace pointer (child_tidptr) passed tocloneto
be stored in the task structure of the new process.
kernel/fork.c
p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID)? child_tidptr : NULL;
Theschedule_tailfunction invoked when the new processis executed for the first time copies
the current PID to this address.
kernel/schedule.c
asmlinkage void schedule_tail(struct task_struct *prev)
{
...
if (current->set_child_tid)
put_user(task_pid_vnr(current), current->set_child_tid);
...
}
❑ CLONE_CHILD_CLEARTIDhas the initial effect incopy_processthat the userspace pointer
child_tidptris stored in the task structure — but this time in a different element.
kernel/fork.c
p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID)? child_tidptr: NULL;
When the process terminates,^13 0 is written to the address defined inclear_child_tid.^14
kernel/fork.c
void mm_release(struct task_struct *tsk, struct mm_struct *mm)
{
if (tsk->clear_child_tid
&& atomic_read(&mm->mm_users) > 1) {
u32 __user * tidptr = tsk->clear_child_tid;
tsk->clear_child_tid = NULL;
put_user(0, tidptr);
(^12) put_useris used to copy data between kernel address space and user address space as discussed in Chapter 4.
(^13) Or, more accurately, when it automatically frees its memory management data structures usingmm_releaseat process
termination.
(^14) The conditionmm->mm_users > 1means that the memory management data structure must be used by at least one other process
in the system. The current process is therefore a thread in the classical sense — it takes its address space from another process and
has just one control flow.