sched_setscheduler, sched_getscheduler — set and get scheduling algorithm/parameters
#include <sched.h>
int
sched_setscheduler( |
pid_t | pid, |
int | policy, | |
const struct sched_param * | param) ; |
int
sched_getscheduler( |
pid_t | pid) ; |
struct sched_param { ... int sched_priority; ... };
sched_setscheduler
() sets
both the scheduling policy and the associated parameters for
the process identified by pid
. If pid
equals zero, the scheduler
of the calling process will be set. The interpretation of the
parameter param
depends on the selected policy. Currently, the following
three scheduling policies are supported under Linux:
SCHED_FIFO
, SCHED_RR
, SCHED_OTHER
, and SCHED_BATCH
; their respective semantics are
described below.
sched_getscheduler
() queries
the scheduling policy currently applied to the process
identified by pid
. If
pid
equals zero, the
policy of the calling process will be retrieved.
The scheduler is the kernel part that decides which
runnable process will be executed by the CPU next. The
Linux scheduler offers three different scheduling policies,
one for normal processes and two for real-time
applications. A static priority value sched_priority
is assigned
to each process and this value can be changed only via
system calls. Conceptually, the scheduler maintains a list
of runnable processes for each possible sched_priority
value, and
sched_priority
can have a value in the range 0 to 99. In order to
determine the process that runs next, the Linux scheduler
looks for the nonempty list with the highest static
priority and takes the process at the head of this list.
The scheduling policy determines for each process, where it
will be inserted into the list of processes with equal
static priority and how it will move inside this list.
SCHED_OTHER
is the default
universal time-sharing scheduler policy used by most
processes. SCHED_BATCH
is
intended for "batch" style execution of processes.
SCHED_FIFO
and SCHED_RR
are intended for special
time-critical applications that need precise control over
the way in which runnable processes are selected for
execution.
Processes scheduled with SCHED_OTHER
or SCHED_BATCH
must be assigned the static
priority 0. Processes scheduled under SCHED_FIFO
or SCHED_RR
can have a static priority in
the range 1 to 99. The system calls sched_get_priority_min(2)
and sched_get_priority_max(2)
can be used to find out the valid priority range for a
scheduling policy in a portable way on all POSIX.1-2001
conforming systems.
All scheduling is preemptive: If a process with a higher static priority gets ready to run, the calling process will be preempted and returned into its wait list. The scheduling policy only determines the ordering within the list of runnable processes with equal static priority.
SCHED_FIFO
can only be
used with static priorities higher than 0, which means that
when a SCHED_FIFO
processes
becomes runnable, it will always immediately preempt any
currently running SCHED_OTHER
or SCHED_BATCH
process.
SCHED_FIFO
is a simple
scheduling algorithm without time slicing. For processes
scheduled under the SCHED_FIFO
policy, the following rules
are applied: A SCHED_FIFO
process that has been preempted by another process of
higher priority will stay at the head of the list for its
priority and will resume execution as soon as all processes
of higher priority are blocked again. When a SCHED_FIFO
process becomes runnable, it
will be inserted at the end of the list for its priority. 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.) A process calling sched_yield(2) will be
put at the end of the list. No other events will move a
process scheduled under the SCHED_FIFO
policy in the wait 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).
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. The length of the time quantum can be retrieved
using sched_rr_get_interval(2).
SCHED_OTHER
can only be
used at static priority 0. SCHED_OTHER
is the standard Linux
time-sharing scheduler that is intended for all processes
that do not require special static priority real-time
mechanisms. The process to run is chosen from the static
priority 0 list based on a dynamic priority that is
determined only inside this list. The dynamic priority is
based on the nice level (set by nice(2) or setpriority(2)) and
increased for each time quantum the process is ready to
run, but denied to run by the scheduler. This ensures fair
progress among all SCHED_OTHER
processes.
(Since Linux 2.6.16.) SCHED_BATCH
can only be used at static
priority 0. This policy is similar to SCHED_OTHER
, except that this policy will
cause the scheduler to always assume that the process is
CPU-intensive. Consequently, the scheduler will apply a
small scheduling penalty so that this process is mildly
disfavored in scheduling decisions. This policy is useful
for workloads that are non-interactive, but do not want to
lower their nice value, and for workloads that want a
deterministic scheduling policy without interactivity
causing extra preemptions (between the workload's
tasks).
In Linux kernels before 2.6.12, only privileged
(CAP_SYS_NICE
) processes can
set a nonzero static priority. The only change that an
unprivileged process can make is to set the SCHED_OTHER
policy, and this can only be
done if the effective user ID of the caller of sched_setscheduler
() matches the real or
effective user ID of the target process (i.e., the process
specified by pid
)
whose policy is being changed.
Since Linux 2.6.12, the RLIMIT_RTPRIO
resource limit defines a
ceiling on an unprivileged process's priority for the
SCHED_RR
and SCHED_FIFO
policies. If an unprivileged
process has a nonzero RLIMIT_RTPRIO
soft limit, then it can
change its scheduling policy and priority, subject to the
restriction that the priority cannot be set to a value
higher than the RLIMIT_RTPRIO
soft limit. If the RLIMIT_RTPRIO
soft limit is 0, then the
only permitted change is to lower the priority. Subject to
the same rules, another unprivileged process can also make
these changes, as long as the effective user ID of the
process making the change matches the real or effective
user ID of the target process. See getrlimit(2) for further
information on RLIMIT_RTPRIO
.
Privileged (CAP_SYS_NICE
)
processes ignore this limit; as with older kernels, they
can make arbitrary changes to scheduling policy and
priority.
A blocked high priority process waiting for the I/O has a certain response time before it is scheduled again. The device driver writer can greatly reduce this response time by using a "slow interrupt" interrupt handler.
Child processes inherit the scheduling algorithm and parameters across a fork(2). The scheduling algorithm and parameters are preserved across execve(2).
Memory locking is usually needed for real-time processes to avoid paging delays, this can be done with mlock(2) or mlockall(2).
As a non-blocking end-less loop in a process scheduled
under SCHED_FIFO
or
SCHED_RR
will block all
processes with lower priority forever, a software developer
should always keep available on the console a shell
scheduled under a higher static priority than the tested
application. This will allow an emergency kill of tested
real-time applications that do not block or terminate as
expected.
POSIX systems on which sched_setscheduler
() and sched_getscheduler
() are available define
_POSIX_PRIORITY_SCHEDULING
in
<
unistd.h
>
On success, sched_setscheduler
() returns zero. On
success, sched_getscheduler
()
returns the policy for the process (a non-negative integer).
On error, −1 is returned, and errno
is set appropriately.
The scheduling policy
is not one of the
recognized policies, or the parameter param
does not make sense
for the policy
.
The calling process does not have appropriate privileges.
The process whose ID is pid
could not be
found.
POSIX.1 does not detail the permissions that an
unprivileged process requires in order to call sched_setscheduler
(), and details vary
across systems. For example, the Solaris 7 manual page says
that the real or effective user ID of the calling process
must match the real user ID or the save set-user-ID of the
target process.
Originally, Standard Linux was intended as a general-purpose operating system being able to handle background processes, interactive applications, and less demanding real-time applications (applications that need to usually meet timing deadlines). Although the Linux kernel 2.6 allowed for kernel preemption and the newly introduced O(1) scheduler ensures that the time needed to schedule is fixed and deterministic irrespective of the number of active tasks, true real-time computing was not possible up to kernel version 2.6.17.
From kernel version 2.6.18 onwards, however, Linux is gradually becoming equipped with real-time capabilities, most of which are derived from the former realtime-preempt patches developed by Ingo Molnar, Thomas Gleixner and others. Until the patches have been completely merged into the mainline kernel (this is expected to be around kernel version 2.6.24 or 2.6.25), the realtime-preempt patches must be installed to achieve the best realtime performance. These patches are named:
patch-kernelversion
-rtpatchversion
and can be downloaded from http://people.redhat.com/mingo/realtime-preempt/.
Without the patches and prior to their full inclusion
into the mainline kernel, the kernel configuration offers
only the three preemption classes CONFIG_PREEMPT_NONE
, CONFIG_PREEMPT_VOLUNTARY
, and
CONFIG_PREEMPT_DESKTOP
which
respectively provide no, some, and considerable reduction
of the worst-case scheduling latency.
With the patches applied or after their full inclusion
into the mainline kernel, the additional configuration item
CONFIG_PREEMPT_RT
becomes
available. If this is selected, Linux is transformed into a
regular real-time operating system. The FIFO and RR
scheduling policies that can be selected using sched_setscheduler
() are then used to run
a process with true real-time priority and a minimum
worst-case scheduling latency.
POSIX says that on success, sched_setscheduler
() should return the
previous scheduling policy. Linux sched_setscheduler
() does not conform to
this requirement, since it always returns 0 on success.
getpriority(2), mlock(2), mlockall(2), munlock(2), munlockall(2), nice(2), sched_get_priority_max(2), sched_get_priority_min(2), sched_getaffinity(2), sched_getparam(2), sched_rr_get_interval(2), sched_setaffinity(2), sched_setparam(2), sched_yield(2), setpriority(2), capabilities(7)
Programming for the real world − POSIX.4 by Bill O. Gallmeister, O'Reilly & Associates, Inc., ISBN 1-56592-074-0
This page is part of release 2.79 of the Linux man-pages
project. A
description of the project, and information about reporting
bugs, can be found at
http://www.kernel.org/doc/man-pages/.
Copyright (C) Tom Bjorkholm, Markus Kuhn & David A. Wheeler 1996-1999 and Copyright (C) 2007 Carsten Emde <Carsten.Emdeosadl.org> This is free documentation; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU General Public License's references to "object code" and "executables" are to be interpreted as the output of any document formatting or typesetting system, including intermediate and printed output. This manual is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this manual; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. 1996-04-01 Tom Bjorkholm <tombmydata.se> First version written 1996-04-10 Markus Kuhn <mskuhncip.informatik.uni-erlangen.de> revision 1999-08-18 David A. Wheeler <dwheelerida.org> added Note. Modified, 25 Jun 2002, Michael Kerrisk <mtk.manpagesgmail.com> Corrected description of queue placement by sched_setparam() and sched_setscheduler() A couple of grammar clean-ups Modified 2004-05-27 by Michael Kerrisk <mtk.manpagesgmail.com> 2005-03-23, mtk, Added description of SCHED_BATCH. 2007-07-10, Carsten Emde <Carsten.Emdeosadl.org> Add text on real-time features that are currently being added to the mainline kernel. |