OSDev

для всех
Текущее время: 19 окт 2018, 00:57

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.
Автор Сообщение
СообщениеДобавлено: 06 сен 2010, 21:35 

Зарегистрирован: 18 апр 2010, 15:59
Сообщения: 155
Все прерывания в системе можно разделить на синхронные (исключения и системные вызовы) и асинхронные (аппаратные прерывания). Первые связаны с контекстом задачи, которая выполнялась в момент возникновения прерывания, вторые не связаны с этим контекстом. Естественным образом возникает мысль о разделении стека ядра на стек прерываний и стеки задач. Первый нужен в одном экземпляре и используется для обслуживания аппаратных прерываний. Каждая задача в системе снабжается своим экземпляром стека ядра используемым для обслуживания исключений и системных вызовов. Достоинства такого подхода заключаются в уменьшении расхода памяти на стек ядра и упрощение доказательства гарантий в отсутствии переполнения стека ядра при наличии горизонтальной и вертикальной реентерабельности. Однако я столкнулся с проблемой необходимости нарушения реентарабельности ядра, что автоматически загоняет первый гвоздь в свойство предсказуемости так необходимую для ОСРВ. Корень проблемы заключается в том, что х86-архитектура предлагает аппаратную поддержку для задачных стеков ядра, но не имеет никакой поддержки стека ядра прерываний (не говоря уже о том, что нужно приложить определенные усилия чтобы определить природу прерывания). Соответственно, при появлении любого прерывания происходит переключение на сегмент стека ядра и указатель вершины стека определенные в TSS выполняющейся задачи. Атомарное же переключение на другой стек невозможно без запрещения прерываний, так как данное переключение требует четырех шагов: сохранение текущего указателя на вершину стека, выставление нового селектора сегмента стека, выставление нового указателя на вершину стека и изменение счетчика вложенности. Как минимум 2 и 3 шаг должны производиться атомарно, дабы не нарушить целостность контекста (учитывая, что между этими шагами может произойти более приоритетное прерывание). Атомарность же можно обеспечить только явным запретом прерываний, что не есть гуд для реентерабельности.

Что вы думаете по этому поводу? Может кто-нибудь уже игрался с разделением стеков ядра? Стоит ли игра свеч? И насколько сильно разделение стеков ударит по реентерабельности? Может кто-нибудь знает какие-то алгоритмы/методики решения этой проблемы на х86 системах? Было бы интересно услышать мнения опытных людей.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 сен 2010, 10:48 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1197
В 64-разрядной архитектуре предусмотрена аппаратная поддержка стеков прерываний. В 32-разрядной архитектуре есть возможность выполнять обработку прерываний в отдельных задачах.

У меня 32-разрядная ОС (причем не РВ), обработчики аппаратных прерываний не могут прерываться более приоритетными. Стек ядра имеет размер 12 кб минус T(hread)S(tructure)_SIZE (около 600 байт). Ядро при обработке системных вызовов контролирует текущую глубину стека. Также имеются два системных вызова - один возвращает текущую глубину относительно дна стека, другой - относительно верхней границы стековой области, резервируемой для обработки прерываний (отрицательное значение говорит о том, что мы уже сильно рискуем) - сейчас величина этой границы равна 1 кб.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 сен 2010, 12:13 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1346
Откуда: Зеленоград
ИМХО, множество стеков лишь усложняет жизнь, ну а предсказуемость достигается иными методами.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 сен 2010, 12:19 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1065
Откуда: Балаково
ZarathustrA, про переключение стека не совсем так. При возникновении прерывания стек переключается не всегда, а только если уровень кодового сегмента для прерывания выше, чем у текущего кода. Тоесть в ядре этого не произойдёт никогда. В общем, вложенные прерывания происходящие в ядре, выполняются в едином стеке вложенно. В точности, как в реальном режиме в ДОС. А когда переключение стека всё-таки возникает (из пользовательского сегмента), то переключение стека происходит атомарно.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 сен 2010, 13:31 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1197
chizh, переключаться на стек прерываний можно из основного стека ядра в обобщенном обработчике прерываний.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 сен 2010, 18:16 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1065
Откуда: Балаково
phantom-84 писал(а):
переключаться на стек прерываний можно из основного стека ядра в обобщенном обработчике прерываний.

Если обработчики прерываний сделаны на уровне ядра, то не вижу смысла переключать стек, т.к. код пользовательского уровня не получит управления до завершения обработки всех прерываний. Только если предполагается квантование прерываний в перемешку с приложениями, то стеки нужны отдельные. А так - нет.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 сен 2010, 20:49 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1197
Вообще основная проблема - это переполнение стека ядра и возникающие в контексте ядра прерывания, способные привести к его переполнению. Если обработчик прерывания будет выполнять работу, используя свой стек, то это уменьшит нагрузку на основной стек и тем самым снизит вероятность его переполнения. Лично для себя я не виду в этом ничего хорошего кроме возможности немного сэкономить память, но вот если говорить о возможности прерывания одного обработчика прерывания другим, то здесь есть о чем поразмыслить.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 сен 2010, 21:09 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1346
Откуда: Зеленоград
На самом деле при грамотном проектировании и реализации (и исправном оборудовании, есно) стек не переполнится, причём его объём может быть очень небольшим. Прерывания ведь не случаются абсолютно произвольно и ни с того ни с сего, а значит, можно посчитать, какой объём стека в каком случае нужен, и определить максимально потребный объём.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 сен 2010, 23:29 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1065
Откуда: Балаково
phantom-84 писал(а):
Вообще основная проблема - это переполнение стека ядра и возникающие в контексте ядра прерывания, способные привести к его переполнению.

Можно с приходом каждого прерывания проверять оставшееся место в стеке, и по необходимости увеличивать его. Отдельно или не отдельно от ядра - не важно, кому как удобней.

SII писал(а):
определить максимально потребный объём.

Да, можно умножать размер стека на количество пришедших прерываний. Но думаю, что будет излишнее раздувание объёма, и много неиспользованной памяти.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 08 сен 2010, 13:29 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1197
SII, у меня так и есть. Просто в силу того, что прерывания могут обрабатываться только поочередно, я резервирую в стеке ядра только одну область для обработки прерываний.

chizh, часто стеки ядра имеют фиксированный размер. Например, у меня на каждый стек ядра отводится 16 кб, причем в первые 4 кб память ни при каких условиях не отображается.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB