why sibling list is used to get the task_struct while fetching the children of a process
In order to organize data as linked list using struct list_head
you have to declare list root and declare list entry for linkage. Both root and child entries are the same type (struct list_head
). children
entry of struct task_struct
entry is a root
. sibling
entry of struct task_struct
is a list entry
. To see the differences, you have to read code, where children
and sibling
are used. Usage of list_for_each
for children
means what children
is a root
. Usage of list_entry
for sibling
means what sibling
is a list entry
.
You can read more about linux kernel lists here.
Question: What is the reason we are passing "sibling" here which eventually a different list with different offset?
Answer:
If the list was created this way:
list_add(&subtask->sibling, ¤t->children);
Than
list_for_each(list, ¤t->children)
Will initialize list pointers to sibling
, so you have to use subling
as parameter to list_entry. That's how linux kernel lists API designed.
But, If the list was created in another (wrong) way:
list_add(&subtask->children, ¤t->sibling);
Than you have to iterate the list this (wrong) way:
list_for_each(list, ¤t->sibling)
And now you have to use children
as parameter for list_entry
.
Hope, this helps.
Following is the pictorial representation that might help someone in future. The top box represents a parent, and the bottom two boxes are it's children
Here is a picture in addition to the previous answers. The same process can be both a parent and a child (as Parent1 on the picture), and we need to distinguish between these two roles.
Intuitively, if children
of Parent0 would point to children
of Parent1, then Parent0.children.next->next
(green circle on the picture), which is the same as Parent1.children.next
, would point to a child of Parent1 instead of a next child of Parent0.