Редактирование: FreeBSD, 03 лекция (от 16 октября)

Материал из eSyr's wiki.

Перейти к: навигация, поиск

Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.

Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.

Текущая версия Ваш текст
Строка 1: Строка 1:
-
Про синхронизацию.
+
Про синхронизацию
Большой класс, мы коснемся только поверхности, но это очень важный класс для програмирования ядра и вообще.
Большой класс, мы коснемся только поверхности, но это очень важный класс для програмирования ядра и вообще.
-
== 03.processes&threads ==
+
Процесс описывается в ядре структурой PROC, структура PCB -- process control block. Сам процесс это совокупность всего, на что она ссылается.
-
Процесс описывается в ядре структурой struct proc. Сам процесс это совокупность всего, на что она ссылается.
+
1. В первую очередь это конечно адресное пространство. В современных ос процессы это такие виртуальные машины, которые работают с непрерывным куском памяти и нисчего не знают о физической памяти, фрагментации и
 +
так далее..
-
# В первую очередь это, конечно, адресное пространство. В современных ОС процессы - это такие виртуальные машины, которые работают с непрерывным куском памяти и нисчего не знают о физической памяти, фрагментации и так далее.
+
1. Указатель на вектор сисколлов.
-
# Указатель на вектор сисколлов.
+
 
-
# На таблицу файловых дескрипторов.
+
1. На таблицу файловых дескрипторов.
-
# На список тредов TAILQ_HEAD() p_threads
+
 
-
# credentials
+
1. credentials
-
# resource limits
+
 
-
# еще примерно килобайт данных.
+
1. resource limits
 +
 
 +
1. еще примерно килобайт данных.
 +
 
 +
1. процесс сслыается на список тредов TAILQ_HEAD() p_threads
QUEUE -- набор макросов для создания списков и очередей. man queue.
QUEUE -- набор макросов для создания списков и очередей. man queue.
Строка 21: Строка 26:
У процесса может быть всего три состояния.
У процесса может быть всего три состояния.
-
# PRS_NEW пока делается форк, пока копируются файловые таблицы,
+
1. PRS_NEW пока делается форк, пока копируются файловые таблицы,
-
# PRS_NORMAL -- нормальное
+
 
-
# PRS_ZOMBIE -- когда структ проц это единственное что осталось от процесса. Зомби образуются, потому что считается, чт ородитель заинтересован в сових потомках. Поэтому когда процесс умирает, от него остаются
+
1. PRS_NORMAL -- нормальное
 +
 
 +
1. PRS_ZOMBIE -- когда структ проц это единственное что осталось от процесса. Зомби образуются, потому что считается, чт ородитель заинтересован в сових потомках. Поэтому когда процесс умирает, от него остаются
структура проц, по которой родитель может понять, вызвав wait, что случилось с ребенком.
структура проц, по которой родитель может понять, вызвав wait, что случилось с ребенком.
Строка 30: Строка 37:
Тоже очень большая структура.
Тоже очень большая структура.
-
# ссылка на процесс
+
1. ссылка на процесс
-
# ссылка на информацию шедулера. Не ембедится в саму струкуру, чтобы было проще писать планировщики.
+
 
-
# Thread control block - td_pcb
+
1. ссылка на информацию шедулера. Не ембедится в саму струкуру, чтобы было проще писать планировщики.
-
# несколько страниц, чтобы когда он входил в ядро у него был стек.
+
 
 +
1. Thread control block
 +
 
 +
1. несколько страниц, чтобы когда он входил в ядро у него был стек.
Кому интересно реально оценить sys/sys/proc.h
Кому интересно реально оценить sys/sys/proc.h
Строка 39: Строка 49:
Состояния
Состояния
-
# TDS_INACTIVE
+
TDS_INACTIVE TDS CAN_RUN -- переходит в состояние рун TDS_RUNQ, готов к исполнению, но времени на него не хватает RUNNING выполняется на процессоре INHIBITED -- замедлен, по какой-то причине выполняться сейчас
-
# TDS CAN_RUN -- переходит в состояние running
+
не может. Причина по которой не может хранится в битовой маске td_inhibitors. Возможные причины
-
# TDS_RUNQ, готов к исполнению, но времени на него не хватает
+
 
-
# TDS_RUNNING выполняется на процессоре
+
TDI_SUSPENDED -- например, когда атачится дебагер и процесс приостановлен
-
# TDS_INHIBITED -- замедлен, по какой-то причине выполняться сейчас не может. Причина по которой не может хранится в битовой маске td_inhibitors. Возможные причины:
+
 
-
## TDI_SUSPENDED -- например, когда атачится дебагер и процесс приостановлен
+
TDI_SLEEPING -- сам вызвал слип, или чего то ждет, например данных ио
-
## TDI_SLEEPING -- сам вызвал слип, или чего то ждет, например данных ио
+
 
-
## TDI_SWAPPED
+
SWAPPEd
-
## TDI_LOCK
+
 
-
## TDI_IWAIT - interrupt wait, хочет уйти из процессора и не выполняться до тех по пока не придет ожидаемое им прерывание.
+
LOCK
 +
 
 +
IWAIT interrupt wait хочет уйти из процессора и не выполняться до тех по пока не придет ожидаемое им прерывание.
Историческая вещь. про большое конкурирование двух моделей того, как писать многтредовые ос.
Историческая вещь. про большое конкурирование двух моделей того, как писать многтредовые ос.
Строка 56: Строка 68:
При модели 1 к 1 на один новый тред возникает новая стуктура в ядре.
При модели 1 к 1 на один новый тред возникает новая стуктура в ядре.
-
При модели M к N на одну структуру в ядре будет приходится несколько процессо в в юзерлэнде. Придумали это все давно. когда многопроцессорных машин еще не было, но оказалось что это имеет смысл. Переключение
+
При модели м к н на одну структуру в ядре будет приходится несколько процессо в в юзерлэнде. Придумали это все давно. когда много процессорных машин еще не было, но оказалось что это имеет смысл. Переключение
контекстов это очень дорого.
контекстов это очень дорого.
Тредов в юзерлэнде создается намного больше, чем ядер у машины. Какие проблемы? Один из пачки тредов вызывает операцию, которая спит. Тогда ядро должно пнуть юзерлэнд, что мол единстввенный вход в ядро заснул.
Тредов в юзерлэнде создается намного больше, чем ядер у машины. Какие проблемы? Один из пачки тредов вызывает операцию, которая спит. Тогда ядро должно пнуть юзерлэнд, что мол единстввенный вход в ядро заснул.
-
M к N намного сложнее, но все кинулись реализовывать именно его.
+
М к н намного сложнее, но все кинулись реализовывать именно его.
Солярис был первым, реализовал позикс тред на этой модели. Линукс тогда был в зачаточном состоянии. Всем казалось что надо догонять и перегонять солярис.
Солярис был первым, реализовал позикс тред на этой модели. Линукс тогда был в зачаточном состоянии. Всем казалось что надо догонять и перегонять солярис.
Строка 76: Строка 88:
Кажется конец истории и м к н не сотсоялось. Но в 2009 виндоус предлагает новую опцию. User ModeScheduling. Это не позикс треды, но это новое апи, которое дает разработчику гораздо больше контроля.
Кажется конец истории и м к н не сотсоялось. Но в 2009 виндоус предлагает новую опцию. User ModeScheduling. Это не позикс треды, но это новое апи, которое дает разработчику гораздо больше контроля.
- 
-
== 04.synchronisation ==
 
Data consistency problem
Data consistency problem
-
Есть список. В нем надо поменять местами элементы. Очевидно, при этом некоторое время список находится в неконсистентном состоянии. Возникает необходимость совершить операцию так, чтобы в этот момент никто другой не вмешался в процесс.
+
Есть список. В нем надо поменять местами элементы. Очевидно, при этом некоторое время список находится в неконсистентном состоянии. Возникает необходимость совершить операцию так, чтобы в этот момент никто
 +
другой не вмешался в процесс.
-
Если бы у нас был один процессор, мы бы сделали критическую секцию, то есть промежуток, в котором процесс нельзя прерывать. Терминологическая проблема: во многих книжках по юзерланд программированию критическую секцию и мьютекс используют как синонимы. Но в ядерном программировании это не так, критическая секция это регион кода, который выполняется непрерывно.
+
Если бы у нас был один процессор, мы бы сделали критическую секцию, то есть промежуток, в котором процесс нельзя прерывать. Терминологическая проблема. Во многих книжек по юзерланд программированию критическую
 +
секцию и мьютекс используют как синонимы. Но в ядерном программировании это не так. Критическая секция это регион кода, который выполняется непрерывно.
Критические секции могут быть двух видов.
Критические секции могут быть двух видов.
-
Hard с запретом прерываний. Но запрет прерываний это тяжелая операция.
+
Жесткие с запретом прерываний. Но запрет прерываний это тяжелая операция.
-
Второй вариант - soft. Тред помечает себя как вошедшего в критическую секцию, причем понятно, допустимы вложенные критические секции.
+
-
void
+
Второй вариант. Тред помечает себя как вошедший критическую секцию, причем понятно, допустимы вложенные крит секции. Это просто флажок планировщику, что после преывания надо поставить обратно тот тред, который
-
critical_enter (void)
+
был.
-
{
+
-
struct thread ∗ td ;
+
-
td = curthread;
+
-
td −>td_critnest++;
+
-
}
+
-
 
+
-
Это просто флажок планировщику, что после преывания надо поставить обратно тот тред, который был. (critical(9))
+
curthread это очень важное слово в исходниках ядра -- макрос, который машинно зависимым способосм находит выполняющийся в данный момент процесс.
curthread это очень важное слово в исходниках ядра -- макрос, который машинно зависимым способосм находит выполняющийся в данный момент процесс.
Строка 105: Строка 109:
void lock (lock_t l)
void lock (lock_t l)
{
{
-
struct thread *td;
+
struct thread *TDS_INACTIVEtd = curthread;
-
td = curthread;
+
spin:
-
spin:
+
if (atomic_cmpset(&l, NULL, td) == 0)
if (atomic_cmpset(&l, NULL, td) == 0)
goto spin
goto spin
-
}
+
}
-
lock starvation -- представим что очень загруженный лок, за который постоянно дерется более одного процессора. Кто будет побеждать? вполне возможно. что тот, кто на материнской плате ближе к памяти. Это конечно чисто теоретическая ситуация, но она возможна.
+
lock startvation -- представим что очень загруженный лок, за который постоянно дерется более одного процессора. Кто будет побеждать? вполне возможно. что тот, кто на материнской плате ближе к памяти. Это
 +
конечно чисто теоретическая ситуация, но она возможна.
Хотелось бы поверх спинлока построить что-нибудь более сложное.
Хотелось бы поверх спинлока построить что-нибудь более сложное.
-
Как будет выглядеть mutex на фрибсд. Это будет ровно одно машинное слово.
+
Как будет выглядеть mutex на фрибсд.
 +
 
 +
Это будет ровно одно машинной слово.
 +
 
 +
struct mtx{
-
struct mtx {
 
struct lock_object lock_object;
struct lock_object lock_object;
 +
volatile uintptr_t mtx_lock;
volatile uintptr_t mtx_lock;
-
}
+
 +
}
-
В бсд треды аллоциируются из специального пула памяти. Особенность этого пула состоит в том, что эти указатели имеют особое выравнивание.и там оказываются свободны 10 бит. Эти биты будем использовать особым образом. один бит будет означать, что мьютекс сободен. Еще один бит под рекурсию, Один под контест (кто-то еще хочет). И у нас куча свободных битов остается.
+
В бсд треды аллоциируются из специального пула памяти. Особенность этого пула состоит в том, тчо эти указатели имеют особое выравнивание.и там оказываются свободны 10 бит. Эти биты будем использовать особым
 +
образом. один бит будет означать, что мьютекс сободен. Еще один бит под рекурсию, Один под контест (кто-то еще хочет). И у нас куча свободных битов остается.
lock_object -- имя лока, прочие свойства.
lock_object -- имя лока, прочие свойства.
-
Блок-схема мьютекса.
+
Блок схема мьютекса.
-
Нам нужна очередь тредов, которая будет пропускать на лок по одному, по очереди. Наткнуться на закрытый мьютекс и сразу заснуть плохая идея, поэтому сразу возникла идея сделать адаптивный мьютекс, когда сначала оно немножко покрутится, и только поняв что это надолго отложится.
+
Нам нужна очередь тредов, которая будет пропускать на лок по одному, по очереди. Наткунуться на закрытый мьютекс и сразу заснуть плохая идея, поэтому сразу возникла идея сделать адаптивный мьютекс, когда
 +
сначала оно немножко покрутится, и только поняв что это надолго отложится.
-
Контекст свитч стоит порядка 100-200 инструкций, поэтому предположим, что нам имеет смысл покрутится 50-60 инструкций. Это было в фрибсд 5.
+
Контекст свитч стоит порядко 100-200 инструкций, поэтому предположим, что нам имеет смысл покрутится 50-60 инструкций. Это было в фрибсд 5.
-
Сейчас другой подход. В фрибсд 5 мьютексы были крупными, держались много времени. fine-grained locking and coarse-grained locking.
+
Сейчас другой подход. В фрибсд 5 мьютексы были крупными, держались много времени. fine grained locking and coarse-grained locking.
Файн это когда мы защищаем все меньшие и меньшие кусочки кода. Веротяность столкновения двух тредов падает, количество мьютексов растет.
Файн это когда мы защищаем все меньшие и меньшие кусочки кода. Веротяность столкновения двух тредов падает, количество мьютексов растет.
-
Сейчас адаптивные мьютексы работают по другому. Они крутятся до тех пор, пока хозяин мьютекса (тот кто сейчас в нем крутится) не изменится сам или не изменит состояние. пока хозяин его держит будем крутится хоть бесконечно. В современной бсд это выгодней, чем отсчитывать 50 инструкций.
+
Сейчас адаптивные мьютексы работают по другому. Они крутятся до тех пор, пока хозяин мьютекса (тот кто сейчас в нем крутится) не изменится сам или не изменит состояние. пока хозяин его держит будем крутится
 +
хоть бесконечно. В современной бсд это выгодней, чем отсчитывать 50 инструкций.
Если же с хозяином чего-то произошло.
Если же с хозяином чего-то произошло.

Пожалуйста, обратите внимание, что все ваши добавления могут быть отредактированы или удалены другими участниками. Если вы не хотите, чтобы кто-либо изменял ваши тексты, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого (см. eSyr's_wiki:Авторское право).
НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!

Шаблоны, использованные на этой странице:

Личные инструменты
Разделы