Редактирование: FreeBSD, 03 лекция (от 16 октября)
Материал из eSyr's wiki.
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 1: | Строка 1: | ||
- | Про синхронизацию | + | Про синхронизацию |
Большой класс, мы коснемся только поверхности, но это очень важный класс для програмирования ядра и вообще. | Большой класс, мы коснемся только поверхности, но это очень важный класс для програмирования ядра и вообще. | ||
- | |||
- | == 03.processes&threads == | ||
Процесс описывается в ядре структурой struct proc. Сам процесс это совокупность всего, на что она ссылается. | Процесс описывается в ядре структурой struct proc. Сам процесс это совокупность всего, на что она ссылается. | ||
# В первую очередь это, конечно, адресное пространство. В современных ОС процессы - это такие виртуальные машины, которые работают с непрерывным куском памяти и нисчего не знают о физической памяти, фрагментации и так далее. | # В первую очередь это, конечно, адресное пространство. В современных ОС процессы - это такие виртуальные машины, которые работают с непрерывным куском памяти и нисчего не знают о физической памяти, фрагментации и так далее. | ||
+ | |||
# Указатель на вектор сисколлов. | # Указатель на вектор сисколлов. | ||
+ | |||
# На таблицу файловых дескрипторов. | # На таблицу файловых дескрипторов. | ||
+ | |||
# На список тредов TAILQ_HEAD() p_threads | # На список тредов TAILQ_HEAD() p_threads | ||
+ | |||
# credentials | # credentials | ||
+ | |||
# resource limits | # resource limits | ||
+ | |||
# еще примерно килобайт данных. | # еще примерно килобайт данных. | ||
Строка 22: | Строка 26: | ||
# PRS_NEW пока делается форк, пока копируются файловые таблицы, | # PRS_NEW пока делается форк, пока копируются файловые таблицы, | ||
+ | |||
# PRS_NORMAL -- нормальное | # PRS_NORMAL -- нормальное | ||
+ | |||
# PRS_ZOMBIE -- когда структ проц это единственное что осталось от процесса. Зомби образуются, потому что считается, чт ородитель заинтересован в сових потомках. Поэтому когда процесс умирает, от него остаются | # PRS_ZOMBIE -- когда структ проц это единственное что осталось от процесса. Зомби образуются, потому что считается, чт ородитель заинтересован в сових потомках. Поэтому когда процесс умирает, от него остаются | ||
структура проц, по которой родитель может понять, вызвав wait, что случилось с ребенком. | структура проц, по которой родитель может понять, вызвав wait, что случилось с ребенком. | ||
Строка 31: | Строка 37: | ||
# ссылка на процесс | # ссылка на процесс | ||
+ | |||
# ссылка на информацию шедулера. Не ембедится в саму струкуру, чтобы было проще писать планировщики. | # ссылка на информацию шедулера. Не ембедится в саму струкуру, чтобы было проще писать планировщики. | ||
+ | |||
# Thread control block - td_pcb | # Thread control block - td_pcb | ||
+ | |||
# несколько страниц, чтобы когда он входил в ядро у него был стек. | # несколько страниц, чтобы когда он входил в ядро у него был стек. | ||
Строка 76: | Строка 85: | ||
Кажется конец истории и м к н не сотсоялось. Но в 2009 виндоус предлагает новую опцию. User ModeScheduling. Это не позикс треды, но это новое апи, которое дает разработчику гораздо больше контроля. | Кажется конец истории и м к н не сотсоялось. Но в 2009 виндоус предлагает новую опцию. User ModeScheduling. Это не позикс треды, но это новое апи, которое дает разработчику гораздо больше контроля. | ||
- | |||
- | == 04.synchronisation == | ||
Data consistency problem | Data consistency problem | ||
- | Есть список. В нем надо поменять местами элементы. Очевидно, при этом некоторое время список находится в неконсистентном состоянии. Возникает необходимость совершить операцию так, чтобы в этот момент никто другой не вмешался в процесс. | + | Есть список. В нем надо поменять местами элементы. Очевидно, при этом некоторое время список находится в неконсистентном состоянии. Возникает необходимость совершить операцию так, чтобы в этот момент никто |
+ | другой не вмешался в процесс. | ||
- | Если бы у нас был один процессор, мы бы сделали критическую секцию, то есть промежуток, в котором процесс нельзя прерывать. Терминологическая проблема | + | Если бы у нас был один процессор, мы бы сделали критическую секцию, то есть промежуток, в котором процесс нельзя прерывать. Терминологическая проблема. Во многих книжек по юзерланд программированию критическую |
+ | секцию и мьютекс используют как синонимы. Но в ядерном программировании это не так. Критическая секция это регион кода, который выполняется непрерывно. | ||
Критические секции могут быть двух видов. | Критические секции могут быть двух видов. | ||
- | + | Жесткие с запретом прерываний. Но запрет прерываний это тяжелая операция. | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | Это просто флажок планировщику, что после преывания надо поставить обратно тот тред, который был. | + | Второй вариант. Тред помечает себя как вошедший критическую секцию, причем понятно, допустимы вложенные крит секции. Это просто флажок планировщику, что после преывания надо поставить обратно тот тред, который |
+ | был. | ||
curthread это очень важное слово в исходниках ядра -- макрос, который машинно зависимым способосм находит выполняющийся в данный момент процесс. | curthread это очень важное слово в исходниках ядра -- макрос, который машинно зависимым способосм находит выполняющийся в данный момент процесс. | ||
Строка 105: | Строка 106: | ||
void lock (lock_t l) | void lock (lock_t l) | ||
{ | { | ||
- | struct thread * | + | struct thread *TDS_INACTIVEtd = curthread; |
- | + | spin: | |
- | + | ||
if (atomic_cmpset(&l, NULL, td) == 0) | if (atomic_cmpset(&l, NULL, td) == 0) | ||
goto spin | goto spin | ||
- | + | } | |
- | lock | + | 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 бит. Эти биты будем использовать особым |
+ | образом. один бит будет означать, что мьютекс сободен. Еще один бит под рекурсию, Один под контест (кто-то еще хочет). И у нас куча свободных битов остается. | ||
lock_object -- имя лока, прочие свойства. | lock_object -- имя лока, прочие свойства. | ||
- | Блок | + | Блок схема мьютекса. |
- | Нам нужна очередь тредов, которая будет пропускать на лок по одному, по очереди. | + | Нам нужна очередь тредов, которая будет пропускать на лок по одному, по очереди. Наткунуться на закрытый мьютекс и сразу заснуть плохая идея, поэтому сразу возникла идея сделать адаптивный мьютекс, когда |
+ | сначала оно немножко покрутится, и только поняв что это надолго отложится. | ||
- | Контекст свитч стоит | + | Контекст свитч стоит порядко 100-200 инструкций, поэтому предположим, что нам имеет смысл покрутится 50-60 инструкций. Это было в фрибсд 5. |
- | Сейчас другой подход. В фрибсд 5 мьютексы были крупными, держались много времени. fine | + | Сейчас другой подход. В фрибсд 5 мьютексы были крупными, держались много времени. fine grained locking and coarse-grained locking. |
Файн это когда мы защищаем все меньшие и меньшие кусочки кода. Веротяность столкновения двух тредов падает, количество мьютексов растет. | Файн это когда мы защищаем все меньшие и меньшие кусочки кода. Веротяность столкновения двух тредов падает, количество мьютексов растет. | ||
- | Сейчас адаптивные мьютексы работают по другому. Они крутятся до тех пор, пока хозяин мьютекса (тот кто сейчас в нем крутится) не изменится сам или не изменит состояние. пока хозяин его держит будем крутится хоть бесконечно. В современной бсд это выгодней, чем отсчитывать 50 инструкций. | + | Сейчас адаптивные мьютексы работают по другому. Они крутятся до тех пор, пока хозяин мьютекса (тот кто сейчас в нем крутится) не изменится сам или не изменит состояние. пока хозяин его держит будем крутится |
+ | хоть бесконечно. В современной бсд это выгодней, чем отсчитывать 50 инструкций. | ||
Если же с хозяином чего-то произошло. | Если же с хозяином чего-то произошло. | ||