Системное программирование. Ядро. Устройство. Планировщики процессов

Содержание

Слайд 2

Операционная система Прерывания Загрузчик ОС Ядро Linux Планировщик ОС Содержание занятия

Операционная система
Прерывания
Загрузчик ОС
Ядро Linux
Планировщик ОС

Содержание занятия

Слайд 3

ОС - диспетчер физических ресурсов Операционная система #0 Пространство пользователя Пространство

ОС - диспетчер физических ресурсов

Операционная система

#0

Пространство пользователя

Пространство ядра ОС

Ядро

Драйверы

Терминал

Загрузчик

Это операционная система

Почта

Плеер

Компилятор

Браузер

Это

НЕ операционная система

Системные
вызовы
read()
write()
open()
close()
fork()

Слайд 4

Прерывания (1/2) #0 Нажали кнопку Контроллер устройства инициировал сигнал Процессор получил

Прерывания (1/2)

#0

Нажали кнопку

Контроллер устройства инициировал сигнал

Процессор получил сигнал и прервал выполнение

задачи

Вызван обработчик в ядре

Обработчик знает номер прерывания, планирует дальнейшую обработку

Слайд 5

Прерывания (2/2) #0

Прерывания (2/2)

#0

Слайд 6

Кто запустил ядро? Загрузчик (1/3) #0

Кто запустил ядро?

Загрузчик (1/3)

#0

Слайд 7

Загрузчик Загрузчик (2/3) #0 Кто запустил загрузчик? Но откуда тогда BIOS?

Загрузчик

Загрузчик (2/3)

#0

Кто запустил загрузчик?

Но откуда тогда BIOS?

Боже, ну а ROM то

что такое?
Слайд 8

Загрузчик (3/3) #0

Загрузчик (3/3)

#0

Слайд 9

Вопрос (2 балла): Почему BIOS сам не запускает ядро? Загрузчик (3/3)

Вопрос (2 балла):
Почему BIOS сам не запускает ядро?

Загрузчик (3/3)

#0

Лампа на слайде

означает
вопрос за баллы

Он не знает, что такое файловая система, и не может найти ядро

Слайд 10

Процессы Ядро Linux #0 Время IPC Пользователи Аппаратура Файловая система Сеть Структуры данных Виртуализация

Процессы

Ядро Linux

#0

Время

IPC

Пользователи

Аппаратура

Файловая система

Сеть

Структуры данных

Виртуализация

Слайд 11

/** * 30.09.2018 * #include/linux/sched.h * 618 lines. */ struct task_struct

/**
* 30.09.2018
* #include/linux/sched.h
* 618 lines.
*/
struct task_struct {

struct thread_info thread_info;
long state;
void *stack;
atomic_t usage;
unsigned int cpu;
int prio;
struct mm_struct *mm;
int exit_state;
int exit_code;
int exit_signal;
pid_t pid;
struct task_struct *parent;
struct list_head children;
u64 start_time;
const struct cred *cred;
struct files_struct *files;
struct thread_struct thread;
};

Ядро Linux. Процессы (1/3)

#0
long state;
atomic_t usage;
unsigned int cpu;
int prio;

struct mm_struct *mm;
int exit_state;
int exit_code;
int exit_signal;

pid_t
getpid(void);
pid_t
getppid(void);

pid_t pid;
struct task_struct *parent;
struct list_head children;

$> cat /proc/sys/kernel/pid_max
32768

const struct cred *cred;
struct files_struct *files;

Слайд 12

Ядро Linux. Процессы (2/3) #0 Waiting an event The signal or event Wait an event

Ядро Linux. Процессы (2/3)

#0

Waiting an event

The signal or event

Wait an event

Слайд 13

Ядро Linux. Процессы (3/3) #0

Ядро Linux. Процессы (3/3)

#0

Слайд 14

Ядро Linux. Аппаратное обеспечение. #0

Ядро Linux. Аппаратное обеспечение.

#0

Слайд 15

Аппаратный источник времени Ядро Linux. Время (1/3) #0 Осциллятор Периодические и

Аппаратный источник времени

Ядро Linux. Время (1/3)

#0

Осциллятор

Периодические и разовые задачи

Осциллятор внутри

Обработанный кристалл

Дикий

кристалл

$> grep 'CONFIG_HZ=' /boot/config-$(uname -r)
CONFIG_HZ=250

Слишком высокий HZ

Слайд 16

Detected 2400.131 MHz processor. Calibrating delay loop... 4799.56 BogoMIPS Ядро Linux.

Detected 2400.131 MHz processor.
Calibrating delay loop... 4799.56 BogoMIPS

Ядро Linux. Время (2/3)

#0

Real

Time Clock
Слайд 17

Точность - пикосекунды ( 10−12) Ядро Linux. Время (3/3) #0 Атомные

Точность - пикосекунды ( 10−12)

Ядро Linux. Время (3/3)

#0

Атомные часы

Источник сигнала

PPS (Pulse

Per Second)
Слайд 18

/** * 30.09.2018 * 33 virtual functions, 149 lines. */ struct

/**
* 30.09.2018
* 33 virtual functions, 149 lines.
*/
struct file_operations

{
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*fsync) (struct file *, loff_t, loff_t, int datasync);
int (*flock) (struct file *, int, struct file_lock *);
long (*fallocate)(struct file *file, int mode, loff_t offset, loff_t len);
};
struct super_block {
struct file_system_type *s_type;
const struct super_operations *s_op;
int s_count;
struct list_head s_mounts;
};

Ядро Linux. Файловая система.

#0

Слайд 19

Мьютексы, семафоры Ядро Linux. IPC #0 Разделяемая память Pipe Доменные сокеты Очереди сообщений

Мьютексы, семафоры

Ядро Linux. IPC

#0

Разделяемая память

Pipe

Доменные сокеты

Очереди сообщений

Слайд 20

Ядро Linux. Сеть. #0

Ядро Linux. Сеть.

#0

Слайд 21

/** * 30.09.2018. * 39 lines. */ struct cred { kuid_t

/**
* 30.09.2018.
* 39 lines.
*/
struct cred {
kuid_t uid;

/* real UID of the task */
kgid_t gid; /* real GID of the task */
kuid_t suid; /* saved UID of the task */
kgid_t sgid; /* saved GID of the task */
kuid_t euid; /* effective UID of the task */
kgid_t egid; /* effective GID of the task */
struct user_struct *user; /* real user ID subscription */
};

Ядро Linux. Пользователи.

#0

Слайд 22

Список Ядро Linux. Структуры данных. #0 Красно-черное дерево struct list_head {

Список

Ядро Linux. Структуры данных.

#0

Красно-черное дерево

struct list_head {
struct list_head *next, *prev;
};

struct

rb_node {
unsigned long __rb_parent_color;
struct rb_node *rb_right;
struct rb_node *rb_left;
};
struct rb_root {
struct rb_node *rb_node;
};

struct my_struct {
struct my_struct *prev;
struct my_struct *next;
int a;
int b;
const char *c;
};

struct my_struct {
struct my_struct *prev;
struct my_struct *next;
int a;
int b;
const char *c;
};
struct my_struct ms1, ms2;
INIT_LIST_HEAD(&ms1);
list_add(&ms1, &ms2);

struct rb_root tree = RB_ROOT;
struct my_struct {
struct rb_node node;
int a;
int b;
const char *c;
};
struct my_struct ms1, ms2;
rb_insert_color(&tree, &ms1);
rb_insert_color(&tree, &ms2);

Слайд 23

Кооперативная многозадачность voluntary yield Ядро Linux. Планировщик (1/8) #0 Вытесняющая многозадачность mandatory preemtion

Кооперативная многозадачность
voluntary yield

Ядро Linux. Планировщик (1/8)

#0

Вытесняющая многозадачность
mandatory preemtion

Слайд 24

dump scheduler Ядро Linux. Планировщик (2/8)я #0 O(1) scheduler Completely Fair Scheduler

dump scheduler

Ядро Linux. Планировщик (2/8)я

#0

O(1) scheduler

Completely Fair Scheduler

Слайд 25

Вопрос (2 балла): Какие есть два типа многозадачности? Ядро Linux. Планировщик (3/8) #0 Кооперативная и вытесняющая

Вопрос (2 балла):
Какие есть два типа многозадачности?

Ядро Linux. Планировщик (3/8)

#0

Кооперативная

и вытесняющая
Слайд 26

nice -- execute a utility with an altered scheduling priority renice

nice -- execute a utility with an altered scheduling priority
renice --

alter priority of running processes
chrt -- manipulate the real-time attributes of a process

Ядро Linux. Планировщик (4/8)

#0

int
getpriority(int which, id_t who);
int
setpriority(int which, id_t who, int prio);
int
nice(int inc);

$> ps -el
UID PID PRI NI TTY CMD
0 1 37 0 ?? /sbin/launchd

real-time
приоритет

nice

Timeslice / quantum

запуск

прерывание

Слайд 27

Пример Ядро Linux. Планировщик (5/8) #0 Приоритет Приоритет Низкая интерактивность Быстрая

Пример

Ядро Linux. Планировщик (5/8)

#0

Приоритет

Приоритет

Низкая интерактивность

Быстрая реакция

Быстрее закончится

Потери кешей,
позже кончится

Задача: конвертация видео

Задача:

шахматы с ИИ
Слайд 28

Квант времени в Linux - относительная величина Ядро Linux. Планировщик (6/8)

Квант времени в Linux - относительная величина

Ядро Linux. Планировщик (6/8)

#0

Процесс может

не использовать квант целиком
Слайд 29

Идеальный планировщик N - число процессов, идеальное деление процессора - 1/N

Идеальный планировщик
N - число процессов,
идеальное деление процессора - 1/N -> 0,

бесконечно частое переключение
Complete Fair Scheduler

Ядро Linux. Планировщик (7/8)

#0

/**
* 30.09.2018.
* 36 lines.
*/
struct sched_entity {
struct load_weight load;
unsigned long runnable_weight;
struct rb_node run_node;
struct list_head group_node;
u64 exec_start;
u64 sum_exec_runtime;
u64 vruntime;
u64 nr_migrations;
struct sched_entity *parent;
};

struct load_weight load;
unsigned long runnable_weight;

u64 exec_start;
u64 sum_exec_runtime;
u64 vruntime;

struct rb_node run_node;

Слайд 30

Ядро Linux. Планировщик (8/8) #0

Ядро Linux. Планировщик (8/8)

#0

Слайд 31

Сортировка слиянием через корутины Баллов за задание Срок сдачи - 15

Сортировка слиянием через корутины

Баллов за задание

Срок сдачи
- 15 баллов: после каждой

выполненной строки выполняется переключение.
- 20 баллов: каждой из N корутин выдается по T / N миллисекунд, где T - target latency, подаваемое на вход. После каждой
строки проверять, что у процесса кончилось время. Если да, то переключать.
- 25 баллов: тоже, что на 15, но чтение с диска должно быть асинхронным. См aio_read.

Задание №1

#0

25

25.03.21

Слайд 32