Prerequisite – CPU Scheduling
Completely fair Scheduler (CFS) and Brain Fuck Scheduler (BFS) are two different process schedulers currently used in Linux.
Process Scheduling –
As any program is loaded as process in RAM and then CPU executes the process according to the priority of the process.
1. Completely fair Scheduler (CFS) :
- It is based on Rotating Staircase Deadline Scheduler (RSDL).
- It is the default scheduling process since version 2.6.23.
- Elegant handling of I/O and CPU bound process.
As the name suggests it fairly or equally divides the CPU time among all the processes.Before understanding the CFS let’s look at the Ideal Fair Scheduling (IFS) of N processes. If there are N processes in the ready queue then each process receives (100/N)% of CPU time according to IFS.
Lets take four process and their burst time as shown below waiting in the ready queue for the execution.
|Process||Burst Time (in ms)|
Take a time quantum of say 4ms. Initially, there is four processes waiting in the ready queue to be executed and according to Ideal fair scheduling, each process gets equally fair time for it’s execution (Time quantum/N).
So 4/4=1 each process gets 1ms to execute in first quantum. After the completion of six quantum process B and D are completely executed and remaining are A and C, which are already executed for 6ms and their remaining time is A=4ms and C=8ms).
In the seventh quantum of time A and C will execute (4/2=2ms as there are only two process remaining). This is ideal fair scheduling in which each process gets equally share of time quantum no matter what priority it is of.
Below is table description of the IFS.
Q:represent time quantum which is 4ms.
CFS is similar as ideal-based scheduling instead it priorities each process according to their virtual runnable time.
Idea behind CFS –
- Each runnable process have a virtual time associated with it in PCB (process control block).
- Whenever a context switch happens(or at every scheduling point) then current running process virtual time is increased by virtualruntime_currprocess+=T.
where T is time for which it is executed recently.
- Runtime for the process therefore monotonically increases.
So initially every process have some starting virtual time (you can google how initially virtual run time is calculated).
CFS is quite simple algorithm for the process scheduling and it is implemented using RED BLACK Trees and not queues.
So all the process which are on main memory are inserted into Red Black trees and whenever a new process comes it is inserted into the tree. As we know that Red Black trees are self Balancing binary Search trees.
In C++, we can use maps in STL as they are implemented using red black trees.
Now whenever there is context switch occurs –
- The virtual time for the current process which was executing is updated as explained above.
- The new process is decided which has lowest virtual time and that we know that is left most node of Red Black tree.
- If the current process still has some burst time then it is inserted into the Red Black tree.
So this way each process gets fair time for the execution as after every context switch the virtual time of a process increases and thus priority shuffles.
Time Complexity analysis of the CFS –
- Insertion in red black trees takes O(logn).
- Finding the node with lowest virtual time is O(1) as we can maintain a pointer.(In maps we can use auto it=map.begin()).
So overall time complexity is O(logn)
Here Red black tree is once created and then we have a Red black tree of N process So the scheduling time complexity is O(logn).
There is also one advantage of using RED Black Trees that is if a process is I/O bound then its virtual time is going to be very less and it appears as the leftmost node in the Red black tree so executed first. So CFS easily figure out the process which are I/O bound and which are CPU bound and it gives higher priority to I/O bound process so avoiding the starvation.
2. Brain Fuck Scheduler (BFS) :
Unlike the CFS scheduler, BFS is O(n) scheduler which uses doubly linked list which is treated like a queue.
So selection of the new process at time of context switch can go O(n) in the worst case and insertion of the process is O(1) as the queue is used.
A global run-queue is used so that all the CPU has access to it. During context switch the queue is scanned until a best process is found with the highest priority and then executed. Priority is decided based on the virtual deadline formula for every process and executed accordingly.
It is not used in Linux anymore due to Context switch overhead and also O(n) time complexity.