Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the Linux kernel use circular doubly linked lists to store the lists of processes?

The Linux kernel stores the lists of processes in a circular doubly linked lists, called the task list. What is the reason behind it? Why was circular doubly linked lists used? What is the advantage of using this data structure? What were the creators trying to achieve by using this data structure?

like image 917
Shanif Ansari Avatar asked Sep 06 '17 15:09

Shanif Ansari


People also ask

Why does the Linux kernel use linked lists?

Whenever someone needs a list in the Linux kernel they rely on this implementation to strung up any data structure they have. With very little modifications (removing hardware prefetching of list items) we can also use this list in our applications.

Why would you use a circular linked list?

Circular linked lists (singly or doubly) are useful for applications that need to visit each node equally and the lists could grow. If the size of the list if fixed, it is much more efficient (speed and memory) to use circular queue.

What is the advantage of using circular doubly linked list over doubly linked list?

Advantages of Circular Doubly Linked List: List can be traversed from both directions i.e. from head to tail or from tail to head. Ease of data manipulation. Jumping from head to tail or vice versa takes O(1) time.

What is a good reason to use doubly linked lists?

The most common reason to use a doubly linked list is because it is easier to implement than a singly linked list. While the code for the doubly linked implementation is a little longer than for the singly linked version, it tends to be a bit more “obvious” in its intention, and so easier to implement and debug.


2 Answers

The reason to have a list of objects (such as processes) some form is that sometimes the kernel needs to enumerate all these objects, i.e. to go through each of them in turn. This means there must be a way to find all the objects of this type. If objects can be created and removed one at a time then a linked list is the simplest solution.

The list needs to be doubly linked in order to support removing an object. When removing an object, the code needs to update all the pointers that point to this object. Therefore the object needs to contain a pointer to all the other objects that point to it (or at least there needs to be a chain of pointers starting at the object itself). With a singly-linked list, to remove B from A→B→C, there's no way to discover the A whose pointer needs to be updated, short of going through all objects until the right one is found. With a doubly-linked list, to remove B from A↔B↔C, you follow the pointer from B to A and change A's pointer to B to point to C instead, and likewise with C.

like image 84
Gilles 'SO- stop being evil' Avatar answered Sep 22 '22 14:09

Gilles 'SO- stop being evil'


Flexibility, so if you know for example what you're searching for is probably behind you you can use the list_for_each_entry_reverse macro instead of the usual forward one.

"you use linked lists when iterating over the whole list is important and the dynamic addition and removal of elements is required ... Using this type of linked list provides the greatest flexibility"

and no duplication of code

"In the old days, there were multiple implementations of linked lists in the kernel. A single, powerful linked list implementation was needed to remove duplicate code. During the 2.1 kernel development series, the official kernel linked-list implementation was introduced."

Source: Robert Love. "Linux Kernel Development" (3rd Edition). p.87-94

like image 32
thrig Avatar answered Sep 24 '22 14:09

thrig