SCHED_FIFO and SCHED_RR are both meant for real-time uses. I am aware that SCHED_RR can be preempted by time slicing. But say if I have one thread set to SCHED_FIFO, and another set to SCHED_RR, if both threads are ready to run, are they scheduled purely by priority? What if they have same priority?
Conceptually, there is a list of runnable processes associated with each static priority level. These lists can contain both SCHED_FIFO and SCHED_RR processes - the two scheduling policies share the same set of static priorities.
When selecting a process to run, the scheduler takes the process at the head of the non-empty list with the highest static priority, regardless of the scheduling policy of that process.
The scheduling policies affect how the processes move within those lists. For SCHED_FIFO, once a process reaches the head of the list for a given priority it will stay there until it blocks or yields. For SCHED_RR, a runnable process that has exceeded its maximum time quantum will be moved to the end of the list for its static priority.
Related
I'm currently learning pthreads and am struggling to understand the relationship between thread priority and policy. What I know so far:
The thread priority is an integer that indicates priority. The higher this number, the higher priority the thread is treated by the OS.
The thread policy determines how the thread is executed among processes with the shared priority number. SCHED_RR and SCHED_FIFO are real-time policies that continuously execute unless an explicit "sleep" command is issued. Thus a programmer must very carefully write code when using these policies. SCHED_OTHER is a round robin policy that is not executed in real-time.
However, let's say I have the following scenarios (assume each thread does not use a "sleep" command).
Thread 1: priority = 0, policy = SCHED_OTHER
Thread 2: priority = 1, policy = SCHED_OTHER
// would thread 1 run at all?
Thread 1: priority = 0, policy = SCHED_RR
Thread 2: priority = 1, policy = SCHED_RR
// would thread 1 run at all?
I'm confused as to whether or not the the thread policy affects the thread priority, or if the thread priority always trumps the policy.
Edit: Found a web page that cleared up most of my confusion: https://computing.llnl.gov/tutorials/pthreads/man/sched_setscheduler.txt
Documentation for SCHED_RR says that it is the same as SCHED_FIFO except in certain cases when two or more threads have the same static priority.
Documentation for SCHED_FIFO makes it clear that if a thread with higher static priority is ready-to-run but not running, and if one or more threads with lower static priority are running, then one of the lower priority threads will be preempted in favor of the higher priority thread.
would thread 1 run at all [in the SCHED_RR case]?
That depends. What is thread 0 doing? How many CPUs does the system have? If those were the only two threads on a system that had only one CPU, then thread 1 would be allowed to run whenever thread 0 did not want to run.
Generally speaking, when you use static priorities, you want the highest priority threads to do the least amount of work. A high priority thread should spend most of its time waiting for some event. Then when the event happens, the thread should promptly acknowledge it, and then possibly signal a lower-priority thread if some kind of follow-up computation is required.
would thread 1 run at all [in the SCHED_OTHER case]?
As mentioned in my comment, if you're talking about static priorities (i.e., as set by the sched_setattr() system call, then the question is meaningless because threads that are scheduled under the SCHED_OTHER policy are all required to have the same static priority--zero.
Do two SCHED_FIFO tasks with equal priority get processing time within each period in Linux, granted neither of the tasks finish before the period ends?
Linux documentation says SCHED_FIFO processes can get preempted only by processes with higher priority, but my understanding is that CFS operates on a higher layer, and assigns timeslots to each of the two tasks within each period.
Linux documentation says SCHED_FIFO processes can get preempted only by processes with higher priority
This is correct, in addition to this, they can also be preempted if you set RLIMIT_RTTIME (getrlimit(2)) and that limit is reached.
The only other reasons why another SCHED_FIFO process (with the same priority) can be scheduled is if the first sleeps or if it voluntary yields (voluntary preemption).
CFS has nothing to do with SCHED_FIFO, it only takes care of SCHED_NORMAL, SCHED_BATCH and SCHED_IDLE.
I have read here about situations where a scheduler is called. But what happens when a high priority task comes?
High priority tasks are scheduled more often than low priority tasks but when a high priority task comes it still has to wait until the quantum of the running task is over.
Priority changes and is adjusted based on past CPU usage.
The longer version
In Linux, process priority is dynamic. The scheduler keeps track of what processes are doing and adjusts their priorities periodically; in this way, processes that have been denied the use of the CPU for a long time interval are boosted by dynamically increasing their priority. Correspondingly, processes running for a long time are penalized by decreasing their priority.
Scheduler maintains a set of all tasks that are ready to run in the system. In a multi-priority system, the task set usually supports the notion of priority. When a high priority task arrives in the system, it is put into the set of tasks sorted by priority.
There are certain points in the kernel where we check if a better process is available to run, compared to the currently running process. This can happen when the time slice expires OR when the ISR is done OR when a lock is unlocked, etc. Look for calls to switch() OR _switch() or something similar...this is the routine that checks the set of tasks and determines if the current task is the highest prio.
If the current task is not the highest prio task, then the current task is switched out and the highest prio task is obtained from the task set and scheduled to run.
Can someone explain the differences between SCHED_OTHER, SCHED_FIFO and SCHED_RR?
Thanks
SCHED_FIFO and SCHED_RR are so called "real-time" policies. They implement the fixed-priority real-time scheduling specified by the POSIX standard. Tasks with these policies preempt every other task, which can thus easily go into starvation (if they don't release the CPU).
The difference between SCHED_FIFO and SCHED_RR is that among tasks with the same priority, SCHED_RR performs a round-robin with a certain timeslice; SCHED_FIFO, instead, needs the task to explicitly yield the processor.
SCHED_OTHER is the common round-robin time-sharing scheduling policy that schedules a task for a certain timeslice depending on the other tasks running in the system.
Update: since Linux 3.14, there is an additional policy called SCHED_DEADLINE. This policy implements the Constant Bandwidth Server (CBS) algorithm on top of Earliest Deadline First queues. Each task under this policy is assigned a deadline, and the earliest-deadline task is executed. The best resource describing this algorithm is Deadline scheduling in the Linux kernel.
Update 2: since Linux 4.13, SCHED_DEADLINE has replaced CBS with the Greedy Reclamation of Unused Bandwidth (GRUB) algorithm.
Here is the differences between SCHED_OTHER, SCHED_FIFO and SCHED_RR based on Linux Manual (http://man7.org/linux/man-pages/man7/sched.7.html)
SCHED_FIFO: First in-first out scheduling
SCHED_FIFO can be used only with static priorities higher than 0, which means that when a SCHED_FIFO threads becomes runnable, it
will always immediately preempt any currently running SCHED_OTHER,
SCHED_BATCH, or SCHED_IDLE thread. SCHED_FIFO is a simple scheduling
algorithm without time slicing.
SCHED_RR: Round-robin scheduling
SCHED_RR is a simple enhancement of SCHED_FIFO. Everything described above for SCHED_FIFO also applies to SCHED_RR, except that
each thread is allowed to run only for a maximum time quantum. If a
SCHED_RR thread has been running for a time period equal to or longer
than the time quantum, it will be put at the end of the list for its
priority.
SCHED_OTHER: Default Linux time-sharing scheduling
SCHED_OTHER can be used at only static priority 0 (i.e., threads under real-time policies always have priority over SCHED_OTHER
processes. SCHED_OTHER is the standard Linux time-sharing scheduler
that is intended for all threads that do not require the special
real-time mechanisms.
This morning I read about Linux real time scheduling. As per the book 'Linux system programming by Robert Love', there are two main scheduling there. One is SCHED_FIFO, fifo and the second is SCHED_RR, the round robin. And I understood how a fifo and a rr algorithm works. But as we have the system call,
sched_setscheduler (pid_t pid, int policy, const struct sched_parem *sp)
we can explicitly set the scheduling policy for our process. So in some case, two process running by root, can have different scheduling policy. As one process having SCHED_FIFO and another having SCHED_RR and with same priority. In that case, which process will be selected first? the FIFO classed process or the RR classed process? Why?
Consider this case. There are three process A,B,C. All are having same priority. A and B are RR classed processes and C is FIFO classed one. A and B are runnable (so both are running alternatively in some time intervel). And currently A is running. Now C becomes runnable. In this case, whether
1. A will preempt for C, or
2. A will run until its timeslice goes zero and let C run. Or
3. A will run until its timeslice goes zero and let B run.
a) here after B runs till its timeslice becomes zero and let C run or
b) after B runs till its timeslice becomes zero and let A run again (then C will starve untill A and B finishes)
In realtime scheduling, FIFO and RR do not have exactly the same meaning they have in non-realtime scheduling. Processes are always selected in a FIFO- manner, however, the time quantum for SCHED_FIFO is not limited unlike the time quantum for SCHED_RR.
SCHED_FIFO processes do not preempt SCHED_RR processes of the same priority.
sched_setscheduler(2) - Linux man page
...
"A process's scheduling policy determines where it will be inserted into the list of processes with equal static priority and how it will move inside this list. All scheduling is preemptive: if a process with a higher static priority becomes ready to run, the currently running process will be preempted and returned to the wait list for its static priority level. The scheduling policy only determines the ordering within the list of runnable processes with equal static priority."
...
"A SCHED_FIFO process runs until either it is blocked by an I/O request, it is preempted by a higher priority process, or it calls sched_yield(2)."
...
"When a SCHED_FIFO process becomes runnable, it will be inserted at the end of the list for its priority."
...
"SCHED_RR: Round Robin scheduling
SCHED_RR is a simple enhancement of SCHED_FIFO. Everything described above for SCHED_FIFO also applies to SCHED_RR, except that each process is only allowed to run for a maximum time quantum. If a SCHED_RR process has been running for a time period equal to or longer than the time quantum, it will be put at the end of the list for its priority. A SCHED_RR process that has been preempted by a higher priority process and subsequently resumes execution as a running process will complete the unexpired portion of its round robin time quantum."
man sched_setscheduler explains these scheduling policies in detail.
In this particular case because the two real-time processes have the same priority none of them will preempt the other. A SCHED_FIFO process runs until it blocks itself, SCHED_RR process runs until it blocks itself or its time quantum expires.
According to the man page, I think 1 is the answer. A, B are RR policy, C is FIFO policy. Since RR is also an enhancement FIFO, all of them are FIFO class.
Since all of them have the same priority, and man page say " A call to sched_setscheduler() or sched_setparam(2) will put the SCHED_FIFO (or SCHED_RR) process identified by pid at the start of the list if it was runnable. As a consequence, it may preempt the currently running process if it has the same priority. (POSIX.1-2001 specifies that the process should go to the end of the list.)"
Once calling sched_setscheduler to set the policy of C as FIFO, C will preempt A.
My understanding of the two different classes is that a process SCHED_FIFO is never pre-empted by the kernel. Even if another "SCHED_FIFO" class process is waiting its turn...
While SCHED_RR policy shares the cpu ressources a little bit more. The scheduler will let the SCHED_RR process run for a quanta of time, then pre-empt it only to let turn another SCHED_RR process. That is exactly Round Robin.
SCHED_FIFO is "stronger" in the sense that if a SCHED_FIFO process never yield() to the kernel or invoke a system call on a single core device, then all your other Real time processes may never run.