Редактирование: FreeBSD, 03 лекция (от 16 октября)
Материал из eSyr's wiki.
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 1: | Строка 1: | ||
- | Про синхронизацию | + | Про синхронизацию |
Большой класс, мы коснемся только поверхности, но это очень важный класс для програмирования ядра и вообще. | Большой класс, мы коснемся только поверхности, но это очень важный класс для програмирования ядра и вообще. | ||
- | + | Процесс описывается в ядре структурой PROC, структура PCB -- process control block. Сам процесс это совокупность всего, на что она ссылается. | |
- | + | 1. В первую очередь это конечно адресное пространство. В современных ос процессы это такие виртуальные машины, которые работают с непрерывным куском памяти и нисчего не знают о физической памяти, фрагментации и | |
+ | так далее.. | ||
- | + | 1. Указатель на вектор сисколлов. | |
- | + | ||
- | + | 1. На таблицу файловых дескрипторов. | |
- | + | ||
- | + | 1. credentials | |
- | + | ||
- | + | 1. resource limits | |
+ | |||
+ | 1. еще примерно килобайт данных. | ||
+ | |||
+ | 1. процесс сслыается на список тредов TAILQ_HEAD() p_threads | ||
QUEUE -- набор макросов для создания списков и очередей. man queue. | QUEUE -- набор макросов для создания списков и очередей. man queue. | ||
Строка 21: | Строка 26: | ||
У процесса может быть всего три состояния. | У процесса может быть всего три состояния. | ||
- | + | 1. PRS_NEW пока делается форк, пока копируются файловые таблицы, | |
- | + | ||
- | + | 1. PRS_NORMAL -- нормальное | |
+ | |||
+ | 1. PRS_ZOMBIE -- когда структ проц это единственное что осталось от процесса. Зомби образуются, потому что считается, чт ородитель заинтересован в сових потомках. Поэтому когда процесс умирает, от него остаются | ||
структура проц, по которой родитель может понять, вызвав wait, что случилось с ребенком. | структура проц, по которой родитель может понять, вызвав wait, что случилось с ребенком. | ||
Строка 30: | Строка 37: | ||
Тоже очень большая структура. | Тоже очень большая структура. | ||
- | + | 1. ссылка на процесс | |
- | + | ||
- | + | 1. ссылка на информацию шедулера. Не ембедится в саму струкуру, чтобы было проще писать планировщики. | |
- | + | ||
+ | 1. Thread control block | ||
+ | |||
+ | 1. несколько страниц, чтобы когда он входил в ядро у него был стек. | ||
Кому интересно реально оценить sys/sys/proc.h | Кому интересно реально оценить sys/sys/proc.h | ||
Строка 39: | Строка 49: | ||
Состояния | Состояния | ||
- | + | TDS_INACTIVE TDS CAN_RUN -- переходит в состояние рун TDS_RUNQ, готов к исполнению, но времени на него не хватает RUNNING выполняется на процессоре INHIBITED -- замедлен, по какой-то причине выполняться сейчас | |
- | + | не может. Причина по которой не может хранится в битовой маске td_inhibitors. Возможные причины | |
- | + | ||
- | + | TDI_SUSPENDED -- например, когда атачится дебагер и процесс приостановлен | |
- | + | ||
- | + | TDI_SLEEPING -- сам вызвал слип, или чего то ждет, например данных ио | |
- | + | ||
- | + | SWAPPEd | |
- | + | ||
- | + | LOCK | |
+ | |||
+ | IWAIT interrupt wait хочет уйти из процессора и не выполняться до тех по пока не придет ожидаемое им прерывание. | ||
Историческая вещь. про большое конкурирование двух моделей того, как писать многтредовые ос. | Историческая вещь. про большое конкурирование двух моделей того, как писать многтредовые ос. | ||
Строка 56: | Строка 68: | ||
При модели 1 к 1 на один новый тред возникает новая стуктура в ядре. | При модели 1 к 1 на один новый тред возникает новая стуктура в ядре. | ||
- | При модели | + | При модели м к н на одну структуру в ядре будет приходится несколько процессо в в юзерлэнде. Придумали это все давно. когда много процессорных машин еще не было, но оказалось что это имеет смысл. Переключение |
контекстов это очень дорого. | контекстов это очень дорого. | ||
Тредов в юзерлэнде создается намного больше, чем ядер у машины. Какие проблемы? Один из пачки тредов вызывает операцию, которая спит. Тогда ядро должно пнуть юзерлэнд, что мол единстввенный вход в ядро заснул. | Тредов в юзерлэнде создается намного больше, чем ядер у машины. Какие проблемы? Один из пачки тредов вызывает операцию, которая спит. Тогда ядро должно пнуть юзерлэнд, что мол единстввенный вход в ядро заснул. | ||
- | + | М к н намного сложнее, но все кинулись реализовывать именно его. | |
Солярис был первым, реализовал позикс тред на этой модели. Линукс тогда был в зачаточном состоянии. Всем казалось что надо догонять и перегонять солярис. | Солярис был первым, реализовал позикс тред на этой модели. Линукс тогда был в зачаточном состоянии. Всем казалось что надо догонять и перегонять солярис. | ||
Строка 76: | Строка 88: | ||
Кажется конец истории и м к н не сотсоялось. Но в 2009 виндоус предлагает новую опцию. User ModeScheduling. Это не позикс треды, но это новое апи, которое дает разработчику гораздо больше контроля. | Кажется конец истории и м к н не сотсоялось. Но в 2009 виндоус предлагает новую опцию. User ModeScheduling. Это не позикс треды, но это новое апи, которое дает разработчику гораздо больше контроля. | ||
- | |||
- | == 04.synchronisation == | ||
Data consistency problem | Data consistency problem | ||
- | Есть список. В нем надо поменять местами элементы. Очевидно, при этом некоторое время список находится в неконсистентном состоянии. Возникает необходимость совершить операцию так, чтобы в этот момент никто другой не вмешался в процесс. | + | Есть список. В нем надо поменять местами элементы. Очевидно, при этом некоторое время список находится в неконсистентном состоянии. Возникает необходимость совершить операцию так, чтобы в этот момент никто |
+ | другой не вмешался в процесс. | ||
- | Если бы у нас был один процессор, мы бы сделали критическую секцию, то есть промежуток, в котором процесс нельзя прерывать. Терминологическая проблема | + | Если бы у нас был один процессор, мы бы сделали критическую секцию, то есть промежуток, в котором процесс нельзя прерывать. Терминологическая проблема. Во многих книжек по юзерланд программированию критическую |
+ | секцию и мьютекс используют как синонимы. Но в ядерном программировании это не так. Критическая секция это регион кода, который выполняется непрерывно. | ||
Критические секции могут быть двух видов. | Критические секции могут быть двух видов. | ||
- | + | Жесткие с запретом прерываний. Но запрет прерываний это тяжелая операция. | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | Это просто флажок планировщику, что после преывания надо поставить обратно тот тред, который был. | + | Второй вариант. Тред помечает себя как вошедший критическую секцию, причем понятно, допустимы вложенные крит секции. Это просто флажок планировщику, что после преывания надо поставить обратно тот тред, который |
+ | был. | ||
curthread это очень важное слово в исходниках ядра -- макрос, который машинно зависимым способосм находит выполняющийся в данный момент процесс. | curthread это очень важное слово в исходниках ядра -- макрос, который машинно зависимым способосм находит выполняющийся в данный момент процесс. | ||
Строка 105: | Строка 109: | ||
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 инструкций. | ||
Если же с хозяином чего-то произошло. | Если же с хозяином чего-то произошло. | ||
Строка 216: | Строка 228: | ||
Отсебятина. | Отсебятина. | ||
http://my.safaribooksonline.com/book/operating-systems-and-server-administration/freebsd/9781457166716/4dot-thread-synchronization/id3175075 | http://my.safaribooksonline.com/book/operating-systems-and-server-administration/freebsd/9781457166716/4dot-thread-synchronization/id3175075 | ||
- | |||
- | {{FreeBSD}} | ||
- | {{Lecture-stub}} |