- Main Page
- Related Pages
- Data Structures

- Data Structure Index
- Class Hierarchy
- Data Fields
#include < sched.h >

Detailed Description
Definition at line 1190 of file sched.h .
Field Documentation
Definition at line 1255 of file sched.h .
Definition at line 1386 of file sched.h .
Definition at line 1374 of file sched.h .
Definition at line 1440 of file sched.h .
Definition at line 1430 of file sched.h .
Definition at line 1363 of file sched.h .
Definition at line 1298 of file sched.h .
Definition at line 1316 of file sched.h .
Definition at line 1337 of file sched.h .
Definition at line 1330 of file sched.h .
Definition at line 1232 of file sched.h .
Definition at line 1329 of file sched.h .
Definition at line 1335 of file sched.h .
Definition at line 1514 of file sched.h .
Definition at line 1269 of file sched.h .
Definition at line 1503 of file sched.h .
Definition at line 1264 of file sched.h .
Definition at line 1263 of file sched.h .
Definition at line 1356 of file sched.h .
Definition at line 1194 of file sched.h .
Definition at line 1225 of file sched.h .
Definition at line 1354 of file sched.h .
Definition at line 1300 of file sched.h .
Definition at line 1319 of file sched.h .
Definition at line 1270 of file sched.h .
Definition at line 1272 of file sched.h .
Definition at line 1442 of file sched.h .
Definition at line 1446 of file sched.h .
Definition at line 1266 of file sched.h .
Definition at line 1427 of file sched.h .
Definition at line 1445 of file sched.h .
Definition at line 1342 of file sched.h .
Definition at line 1327 of file sched.h .
Definition at line 1323 of file sched.h .
Definition at line 1275 of file sched.h .
Definition at line 1203 of file sched.h .
Definition at line 1369 of file sched.h .
Definition at line 1370 of file sched.h .
Definition at line 1371 of file sched.h .
Definition at line 1231 of file sched.h .
Definition at line 1501 of file sched.h .
Definition at line 1502 of file sched.h .
Definition at line 1358 of file sched.h .
Definition at line 1201 of file sched.h .
Definition at line 1294 of file sched.h .
Definition at line 1382 of file sched.h .
Definition at line 1265 of file sched.h .
Definition at line 1365 of file sched.h .
Definition at line 1268 of file sched.h .
Definition at line 1389 of file sched.h .
Definition at line 1281 of file sched.h .
Definition at line 1311 of file sched.h .
Definition at line 1230 of file sched.h .
Definition at line 1321 of file sched.h .
Definition at line 1195 of file sched.h .
Definition at line 1308 of file sched.h .
Definition at line 1444 of file sched.h .
Definition at line 1307 of file sched.h .
Definition at line 1482 of file sched.h .
Definition at line 1333 of file sched.h .
Definition at line 1293 of file sched.h .
Definition at line 1325 of file sched.h .
Definition at line 1438 of file sched.h .
Definition at line 1207 of file sched.h .
Definition at line 1204 of file sched.h .
Definition at line 1368 of file sched.h .
Definition at line 1367 of file sched.h .
Definition at line 1364 of file sched.h .
Definition at line 1205 of file sched.h .
Definition at line 1279 of file sched.h .
Definition at line 1278 of file sched.h .
Definition at line 1206 of file sched.h .
Definition at line 1379 of file sched.h .
Definition at line 1383 of file sched.h .
Definition at line 1315 of file sched.h .
Definition at line 1299 of file sched.h .
Definition at line 1361 of file sched.h .
Definition at line 1360 of file sched.h .
Definition at line 1487 of file sched.h .
Definition at line 1192 of file sched.h .
Definition at line 1324 of file sched.h .
Definition at line 1191 of file sched.h .
Definition at line 1318 of file sched.h .
Definition at line 1489 of file sched.h .
Definition at line 1372 of file sched.h .
Definition at line 1250 of file sched.h .
Definition at line 1282 of file sched.h .
Definition at line 1352 of file sched.h .
Definition at line 1312 of file sched.h .
Definition at line 1513 of file sched.h .
Definition at line 1193 of file sched.h .
Definition at line 1314 of file sched.h .
- include/linux/ sched.h

You are using an outdated browser. Please upgrade your browser to improve your experience and security.
Linux Audio
Check our new training course
Embedded Linux Audio
Elixir Cross Referencer
Defined in 5 files as a struct:, referenced in 1431 files:.
- View page source
Processes ¶
View slides
Lecture objectives ¶
- Process and threads
- Context switching
- Blocking and waking up
- Process context
Processes and threads ¶
A process is an operating system abstraction that groups together multiple resources:
All this information is grouped in the Process Control Group (PCB). In Linux this is struct task_struct .
Overview of process resources ¶
A summary of the resources a process has can be obtain from the /proc/<pid> directory, where <pid> is the process id for the process we want to look at.
struct task_struct ¶
Lets take a close look at struct task_struct . For that we could just look at the source code, but here we will use a tool called pahole (part of the dwarves install package) in order to get some insights about this structure:
As you can see it is a pretty large data structure: almost 8KB in size and 155 fields.
Inspecting task_struct ¶
The following screencast is going to demonstrate how we can inspect the process control block ( struct task_struct ) by connecting the debugger to the running virtual machine. We are going to use a helper gdb command lx-ps to list the processes and the address of the task_struct for each process.
Quiz: Inspect a task to determine opened files ¶
Use the debugger to inspect the process named syslogd.
- What command should we use to list the opened file descriptors?
- How many file descriptors are opened?
- What command should we use the determine the file name for opened file descriptor 3?
- What is the filename for file descriptor 3?
A thread is the basic unit that the kernel process scheduler uses to allow applications to run the CPU. A thread has the following characteristics:
- Each thread has its own stack and together with the register values it determines the thread execution state
- A thread runs in the context of a process and all threads in the same process share the resources
- The kernel schedules threads not processes and user-level threads (e.g. fibers, coroutines, etc.) are not visible at the kernel level
The typical thread implementation is one where the threads is implemented as a separate data structure which is then linked to the process data structure. For example, the Windows kernel uses such an implementation:

Linux uses a different implementation for threads. The basic unit is called a task (hence the struct task_struct ) and it is used for both tasks and processes. Instead of embedding resources in the task structure it has pointers to these resources.
Thus, if two threads are the same process will point to the same resource structure instance. If two threads are in different processes they will point to different resource structure instances.

The clone system call ¶
In Linux a new thread or process is create with the clone() system call. Both the fork() system call and the pthread_create() function uses the clone() implementation.
It allows the caller to decide what resources should be shared with the parent and which should be copied or isolated:
- CLONE_FILES - shares the file descriptor table with the parent
- CLONE_VM - shares the address space with the parent
- CLONE_FS - shares the filesystem information (root directory, current directory) with the parent
- CLONE_NEWNS - does not share the mount namespace with the parent
- CLONE_NEWIPC - does not share the IPC namespace (System V IPC objects, POSIX message queues) with the parent
- CLONE_NEWNET - does not share the networking namespaces (network interfaces, routing table) with the parent
For example, if CLONE_FILES | CLONE_VM | CLONE_FS is used by the caller than effectively a new thread is created. If these flags are not used than a new process is created.
Namespaces and "containers" ¶
"Containers" are a form of lightweight virtual machines that share the same kernel instance, as opposed to normal virtualization where a hypervisor runs multiple VMs, each with its one kernel instance.
Examples of container technologies are LXC - that allows running lightweight "VM" and docker - a specialized container for running a single application.
Containers are built on top of a few kernel features, one of which is namespaces. They allow isolation of different resources that would otherwise be globally visible. For example, without containers, all processes would be visible in /proc. With containers, processes in one container will not be visible (in /proc or be killable) to other containers.
To achieve this partitioning, the struct nsproxy structure is used to group types of resources that we want to partition. It currently supports IPC, networking, cgroup, mount, networking, PID, time namespaces. For example, instead of having a global list for networking interfaces, the list is part of a struct net . The system initializes with a default namespace ( init_net ) and by default all processes will share this namespace. When a new namespace is created a new net namespace is created and then new processes can point to that new namespace instead of the default one.

Accessing the current process ¶
Accessing the current process is a frequent operation:
- opening a file needs access to struct task_struct 's file field
- mapping a new file needs access to struct task_struct 's mm field
- Over 90% of the system calls needs to access the current process structure so it needs to be fast
- The current macro is available to access to current process's struct task_struct
In order to support fast access in multi processor configurations a per CPU variable is used to store and retrieve the pointer to the current struct task_struct :

Previously the following sequence was used as the implementation for the current macro:
Quiz: previous implementation for current (x86) ¶
What is the size of struct thread_info ?
Which of the following are potential valid sizes for struct thread_info : 4095, 4096, 4097?
Context switching ¶
The following diagram shows an overview of the Linux kernel context switch process:

Note that before a context switch can occur we must do a kernel transition, either with a system call or with an interrupt. At that point the user space registers are saved on the kernel stack. At some point the schedule() function will be called which can decide that a context switch must occur from T0 to T1 (e.g. because the current thread is blocking waiting for an I/O operation to complete or because it's allocated time slice has expired).
At that point context_switch() will perform architecture specific operations and will switch the address space if needed:
Then it will call the architecture specific switch_to implementation to switch the registers state and kernel stack. Note that registers are saved on stack and that the stack pointer is saved in the task structure:
You can notice that the instruction pointer is not explicitly saved. It is not needed because:
a task will always resume in this function the schedule() ( context_switch() is always inlined) caller's return address is saved on the kernel stack a jmp is used to execute __switch_to() which is a function and when it returns it will pop the original (next task) return address from the stack
The following screencast uses the debugger to setup a breaking in __switch_to_asm and examine the stack during the context switch:
Quiz: context switch ¶
We are executing a context switch. Select all of the statements that are true.
- the ESP register is saved in the task structure
- the EIP register is saved in the task structure
- general registers are saved in the task structure
- the ESP register is saved on the stack
- the EIP register is saved on the stack
- general registers are saved on the stack
Blocking and waking up tasks ¶
Task states ¶.
The following diagram shows to the task (threads) states and the possible transitions between them:

Blocking the current thread ¶
Blocking the current thread is an important operation we need to perform to implement efficient task scheduling - we want to run other threads while I/O operations complete.
In order to accomplish this the following operations take place:
- Set the current thread state to TASK_UINTERRUPTIBLE or TASK_INTERRUPTIBLE
- Add the task to a waiting queue
- Call the scheduler which will pick up a new task from the READY queue
- Do the context switch to the new task
Below are some snippets for the wait_event implementation. Note that the waiting queue is a list with some extra information like a pointer to the task struct.
Also note that a lot of effort is put into making sure no deadlock can occur between wait_event and wake_up : the task is added to the list before checking condition , signals are checked before calling schedule() .
Waking up a task ¶
We can wake-up tasks by using the wake_up primitive. The following high level operations are performed to wake up a task:
- Select a task from the waiting queue
- Set the task state to TASK_READY
- Insert the task into the scheduler's READY queue
- On SMP system this is a complex operation: each processor has its own queue, queues need to be balanced, CPUs needs to be signaled
Preempting tasks ¶
Up until this point we look at how context switches occurs voluntary between threads. Next we will look at how preemption is handled. We will start wight the simpler case where the kernel is configured as non preemptive and then we will move to the preemptive kernel case.
Non preemptive kernel ¶
- At every tick the kernel checks to see if the current process has its time slice consumed
- If that happens a flag is set in interrupt context
- Before returning to userspace the kernel checks this flag and calls schedule() if needed
- In this case tasks are not preempted while running in kernel mode (e.g. system call) so there are no synchronization issues
Preemptive kernel ¶
In this case the current task can be preempted even if we are running in kernel mode and executing a system call. This requires using a special synchronization primitives: preempt_disable and preempt_enable .
In order to simplify handling for preemptive kernels and since synchronization primitives are needed for the SMP case anyway, preemption is disabled automatically when a spinlock is used.
As before, if we run into a condition that requires the preemption of the current task (its time slices has expired) a flag is set. This flag is checked whenever the preemption is reactivated, e.g. when exiting a critical section through a spin_unlock() and if needed the scheduler is called to select a new task.
Process context ¶
Now that we have examined the implementation of processes and threads (tasks), how context switching occurs, how we can block, wake-up and preempt tasks, we can finally define what the process context is what are its properties:
The kernel is executing in process context when it is running a system call.
In process context there is a well defined context and we can access the current process data with current
In process context we can sleep (wait on a condition).
In process context we can access the user-space (unless we are running in a kernel thread context).
Kernel threads ¶
Sometimes the kernel core or device drivers need to perform blocking operations and thus they need to run in process context.
Kernel threads are used exactly for this and are a special class of tasks that don't "userspace" resources (e.g. no address space or opened files).
The following screencast takes a closer look at kernel threads:
Using gdb scripts for kernel inspection ¶
The Linux kernel comes with a predefined set of gdb extra commands we can use to inspect the kernel during debugging. They will automatically be loaded as long gdbinit is properly setup
All of the kernel specific commands are prefixed with lx-. You can use TAB in gdb to list all of them:
The implementation of the commands can be found at script/gdb/linux . Lets take a closer look at the lx-ps implementation:

IMAGES
VIDEO
COMMENTS
Chrome OS Linux is a free and open-source operating system developed by Google. It is based on the popular Linux kernel and is designed to be lightweight, secure, and easy to use. Before you can install Chrome OS Linux, there are a few thin...
Chrome OS is a lightweight operating system designed by Google for use on Chromebooks. It is based on the Linux kernel and uses the Google Chrome web browser as its main user interface. While Chrome OS is a great operating system for basic ...
Python is one of the most popular programming languages in the world. It is used for a variety of tasks, from web development to data science. If you’re looking to get started with Python on Linux, this step-by-step guide will help you get ...
#include <sched.h>. Data Fields. volatile long · state · void *, stack · atomic_t · usage. unsigned int · flags. unsigned int · ptrace · int · on_rq.
Elixir Cross Referencer - Explore source code in your browser - Particularly useful for the Linux kernel and other low-level projects in C/C++ (bootloaders, C
kernel lock) из
Yes, the task_struct structure contains all the information about a process. You can obtain a pointer to the structure that describes the
By the way, “task_struct” is the PCB in Linux (it is also the TCB, meaning the Thread Control Block). As an example, a diagram that shows two
Linux uses a different implementation for threads. The basic unit is called a task (hence the struct task_struct ) and it is used for both tasks and processes.
Это ядерный стек. Каждый пользовательский поток имеет два стека: ядерный и пользовательский. При системном вызове происходит прерывание и
Каждый процесс под Linux динамически распределяет структуру struct task_struct . Максимальное число процессов, которые могут быть созданы под Linux
... kernel-thread */ struct exec_domain *exec_domain; volatile long need_resched; unsigned long ptrace; int lock_depth; /* Lock depth */ /* * offset 32 begins
"Linux Kernel Development", by Robert Love (Appendix A); http://www.
2.1 Task Structure and Process Table. Every process under Linux is dynamically allocated a struct task_struct structure. The maximum number of processes which