Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Параметры оценки архитектуры ОС
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы
TMX
Хочу обзор сделать, по существующим на рынке ОС для мк.
Не просто краткую аннотацию, такие уже есть,
например:
http://www.realtime-info.be/encyc/buyersgu...tos/Dir228.html
http://www.dspconsulting.com/rtos.html
(это просто первые в моем URL-album)
, а хочу обзирать именно конкретные подходы к построению архитектур.

Предлагаю сокращенный набор параметров для оценки архитектуры:
(их больше, просто, чтобы показать принципы)

-. Многозадачность (есть, нет, кооперативная, вытесняющая, набор примитивов для cycl.exec и т.д.)
-. Приоритеты задач (стат, динам, несравниваемые и др.)
-. Особенности переключения задач (контекст, стеки и т.д.)
-. Реализация планировщика.
-. Реализация диспетчера.
-. Оценка преимуществ и недостатков методов планирования/диспетчеризации для конкретных задач.
-. Предотвращение инверсии приоритетов (есть, нет, методы)
-. Реализация искл. доступа к ресурсам.
-. Контроль задач (события, таймеры и др.)
-. Запуск системных и доп. процессов (методы для таймеров, ISR и т.д.)
-. Реализация HAL.
-. API - предоставляемые возможности.
-. Доп. средства (GUI, TCP/IP и т.д.)
-. Общая оценка.

Результаты желаю выложить в интернет.
Примерная производительность - 4 ОС/мес, если не попрет.
Предлагаю это из шкурных соображений:
1. закончились новые идеи, а спросить не у кого.
2. последняя моя ОС получилась хороша, но вдруг изобрел велосипед?

Поэтому объявление:
Приму в дар исходники коммерческих ОС для исследовательских целей, (это не пиратство, это промышленный шпионаж).
Особо интересуют:
-. Integrity - как реализовано переключение задач без выкл. прерываний,
-. PORTOS - реализация приоритетных функций,
-. smx - реализация связных стеков задач
-. все остальные.
AlexandrY
Меня бы интересовали другие параметры.
Более жизненные так сказать.

По приоритетности:
1. Доставаемость исходников
2. Независимость от компилятора
3. Портируемость и документированность
4. Минимальное время реакции на конкретных примерах
5. Объем потребляемых ресурсов
6. Известность и широта применяемости.

А остальное дело наживное. И HAL и планировщик и примочки всякие пишем по своему усмотрению.
TMX
Цитата(AlexandrY @ Feb 21 2005, 13:22)
Меня бы интересовали другие параметры.
Более жизненные так сказать.

По приоритетности:
1. Доставаемость исходников
2. Независимость от компилятора
3. Портируемость и документированность
4. Минимальное время реакции на конкретных примерах
5. Объем потребляемых ресурсов
6. Известность и широта применяемости.

А остальное дело наживное. И HAL и планировщик и примочки всякие пишем по своему усмотрению.
*


Ну я вроде объяснил, зачем я это собираюсь делать - идеи хочу новые посмотреть.
Если вы можете написать элементы, то зачем вам тогда приобретать ОС - пишите свою по своему усмотрению.
xyzzy
Цитата(TMX @ Feb 21 2005, 01:46)
-. Многозадачность (есть, нет, кооперативная, вытесняющая, набор примитивов для cycl.exec и т.д.)
*


Как насчет многопроцессорности? SMP, NSMP, NUMA, etc..
Еще интересный фактор - меж-процессное взаимодействие (включая методы синхронизации, в том числе распределенные.)

--zzyxy
TMX
Цитата(xyzzy @ Apr 11 2005, 07:53)
Цитата(TMX @ Feb 21 2005, 01:46)
-. Многозадачность (есть, нет, кооперативная, вытесняющая, набор примитивов для cycl.exec и т.д.)
*


Как насчет многопроцессорности? SMP, NSMP, NUMA, etc..
Еще интересный фактор - меж-процессное взаимодействие (включая методы синхронизации, в том числе распределенные.)

--zzyxy
*



Не, я в межпроцессорном взаимодействии не компетентен. А методы синхронизации и в однопроцессорных системах не оптимальны - например:
Если есть счетный семафор на ресурс (например блоки памяти) - часто используется при формировании сетевых сообщений, например, при реализации OSEK/NMI, при этом используется Priority Ceiling, как рекомендуется в том же OSEK/VDX. И что получается? - сообщение, захватившее ресурс, автоматически становится наиболее приоритетным, а остальные ждут его, т.е. реально используется всего один ресурс. Если сделать Priority Inheritance, то при N ресурсах высокоприоритетное сообщение будет ждать всех низкоприоритетных в худшем случае. Эта проблема, на мой взгляд, интересна для обсуждения, если ставить задачу действительно разработать систему жесткого реального времени (т.е. предсказуемую).
А многопроцессорные системы слишком сложны для моего мозга.
RVlad
>... Эта проблема, на мой взгляд, интересна для обсуждения, если ставить >задачу действительно разработать систему жесткого реального времени (т.е. >предсказуемую).А многопроцессорные системы слишком сложны для моего >мозга.

Чтобы сделать "предсказуемую" систему жесткого RT вам в случае однопроцессорной конфигурации необходимо просчитать все возможные комбинации состояний ваших задач с учетом статических и динамических приоритетов, блокировки ресурсов, блокировки каналов обмена, переключения контекста и пр. Другими словами для задач реальной сложности обеспечить жесткий RT на однопроцессорной конфигурации практически невозможно. Я уже не говоря про обработку сбоев, отказов и реализацию м-мов контрольных точек. В соостветствующей литературе ральные конфигурации обычно включали несколько процессорных эл-тов с теми или иными средствами аппаратного мажорирования. Так что придеться изучать многопроцессорные системы.
TMX
Цитата(RVlad @ Apr 12 2005, 19:02)
Чтобы сделать "предсказуемую" систему жесткого RT вам в случае однопроцессорной конфигурации необходимо просчитать все возможные комбинации состояний  ваших задач с учетом статических и динамических приоритетов, блокировки ресурсов, блокировки каналов обмена, переключения контекста и пр. Другими словами для задач реальной сложности обеспечить жесткий RT на однопроцессорной конфигурации практически невозможно. Я уже не говоря про обработку сбоев, отказов и реализацию м-мов контрольных точек.  В соостветствующей литературе ральные конфигурации обычно включали несколько процессорных эл-тов с теми или иными средствами аппаратного мажорирования. Так что придеться изучать многопроцессорные системы.
*


Вот-вот, я и Вас не понимаю :-). То что, все просчитать нельзя (т.е. NP-трудность), насколько я знаю, известно давно (Мок, 1984). Поэтому были предложены определенные ограничения (обзор Одсли, 1992) Зачем динамические приоритеты считать, если их не делать?
Предсказуемость, с моей точки зрения, это возможность расчета времени реакции на событие. Ну и как переключение контекста влияет на предсказуемость? В uCOS II, например переключение контекста очень быстрое, ну и что - она не предсказуема, поскольку м.б. инверсия приоритетов.
О многопроцессорных системах я читал (например, статьи Тинделла об организации обмена в таких системах), но эта область с практической точки зрения меня не интересует - просто не имею достаточной подготовки и нет реальных задач.
А ОС, как средство управлять разделяемыми ресурсами по каким-то законам, позволяющим сделать расчет времени - достойная на мой взгляд задача.
Насчет контроля сбоев ничего сказать не могу.
Мне кажется, что расчеты для многопроцессорных систем гораздо сложнее.
RVlad
Я думаю , что в значительной степени то - о чем мы говорим - это вопрос терминологический.
- Если говорить в терминах определений RTOS - то существует точка зрения, готорая гласит - RTOS - система ориентированная на конкретное приложение:=> если для приложения можно выполнить некоторые определнные требования real-time-a , то и система на основе которой построено это приложение является RTOS. Соответственно различные коммерческие RTOS и делаются для того , чтобы улучшить показатели (и расширить сферу применимости данной OS как RTime).
- Другой вопрос, что при проектировании достаточно сложных RT приложений значительно легче разбить его на несколько слабосвязанных задач (если это получаеться) и разместить их на отдельных процессорах. Уменьшение сложности проектирования достигаеться из -за того , что вместо одно большого графа - получаются неслько графов меньшего размера , ну и соответственно ...В этом варианте и требования к OS .для реализации этих подзадач - соответственно снижаются(латентность, мертвое время и пр...).
- А вот если не получаеться слабосвязанных задач - то это проблема не RTOS а проблема алгоритма и/или архитектуры вычислений. RTOS здесь уже совсем не поможет.. Тут начинаются всякие MIMD &SIMD и прочие Data flow навороты.
Вот тогда при построении DFSG задачи на таких распределенных вычислителях вопрос real-time определяется латентностью переключения этого графа из одного сотояния в другое и соответственно латентностью конвейера данных, обрабатывающих то или иное событие от его появления до выработки решения (результата).
Т.о. сначала спецификация на RT приложение - потом выбор архитектуры - а затем уже (если можно и нужно ) спецификация на RTOS. Таак мне кааажется..
Ну а всякие FPGA+(NIOS+command extensions)+Linux и дают эту возможность ..реализовывать целевую архитектуру приложения. smile.gif
TMX
Вы правы, я тоже стараюсь разбить систему на несколько задач с четкими интерфейсами и явно выделенными состояниями.
После этого уже не имеет принципиального значения, выполняются ли они на нескольких процессорах или на одном с разделением времени между задачами. А общие ресурсы могут быть и на многопроцессорной системе.
При таком подходе вполне достаточно модели с циклическим исполнением - она легко поддается расчетам. Недостаток - необходимо разбивать задачи на состояния с жесткими временными рамками, это иногда приводит к значительным затратам времени при внесении изменений. Кроме того, обращение к общим ресурсам представляет некоторую проблему.
Для управления ресурсами ОС не обязательна - есть циклические буферы, буферы читатель/писатель, флаги, наконец. Удобно оформить все это в некоторые библиотеки со стандартным интерфейсом и пользоваться (я так и делаю).
Анализ ОС меня - гимнастика для ума, мне любопытны подходы и филисофия создания именно ОСРВ - потому что существуют жесткие рамки, это заставляет изобретать новые идеи, например, несравниваемые приоритеты (Babaoglu,1990) или протоколы захвата/освобождения ресурсов.
Когда мне нужно было написать ОС - я это сделал (для Fujitsu), и могу рассматривать эти проблемы с позиции реализации (в сущности, на мой взгляд, все сводится к алгоритмам обработки динамических очередей).
Сейчас я реализую одну свою идею (несложную) насчет оптимизации времени обработки семафоров и выбираю алгоритм захвата ресурсов.
Поэтому я рассматриваю то, что может мне пригодиться или улучшить мое понимание проблемы - это, в общем-то, не широкие рамки.
RVlad
Мнея эта тема интересует в том числе и прагматической точки зрения.
В данный момент я работаю с разработкой приложения на WinCE. Говорить про недостатки я не буду ... не продуктивно. Но проблема состоит в следующем.Есть два треда - один занимает примерно 10-15% временной диаграммы процесора. Другой, для которого необходимо выдерживать жесткие врменные соотношения . может занимать либо 10, либо 20 либо 50% временной диаграммы(замеры делались на автономном прогоне). Так вот если в 1 и 2 случае все примерно неплохо -- т.е. 1тр + 2тр = сумм загрузка, в случае когда второй тред занимает 50% результат плачевный --
вместо 15+50 = 65 процентов я могу получить и 75 и 85 процентов загрузки.
Пытаюсь разобраться , откуда это вылезает ..то ли GUI , то ли драйвера WiFi??
Может что нибудь посоветуете??
TMX
Цитата(RVlad @ Apr 15 2005, 14:11)
Мнея эта тема интересует в том числе и прагматической точки зрения.
В данный момент я работаю с разработкой  приложения на WinCE.
Пытаюсь разобраться , откуда это вылезает ..то ли GUI , то ли драйвера WiFi??
Может что нибудь посоветуете??
*


К сожалению, под WinCE не работал - я занимаюсь более легкими ОС типа FreeRTOS, uCOS и т.п.
Такое бывает, если запрещать обработку системных запросов - они накапливаются а затем система может тратить время на обработку соответствующих очередей - корректное исключение элементов.
Если же у вас этого нет, то я не знаю.
merk0
***Мнея эта тема интересует в том числе и прагматической точки зрения.
В данный момент я работаю с разработкой приложения на WinCE.
Пытаюсь разобраться , откуда это вылезает ..то ли GUI , то ли драйвера WiFi??***

С этой системой я не работал...но.
Из теоретических соображений...если этот проблемный тред медленно вычерпывает из системы какие-то данные, например приходящие по прерываниям, то возможны какие-то переполнения очередей или что-то еще... оси могут вести себя довольно странно в "точках" где внутрь системы "проникают" данные извне.
Можно поэкспериментировать. Если то, что я говорю верно, то разбиение такого треда на два - вычерпывателя данных и их обработчика - проблему может решить.

***-. Многозадачность (есть, нет, кооперативная, вытесняющая, набор примитивов для cycl.exec и т.д.)
-. Приоритеты задач (стат, динам, несравниваемые и др.)
-. Особенности переключения задач (контекст, стеки и т.д.)
-. Реализация планировщика.
-. Реализация диспетчера.
-. Оценка преимуществ и недостатков методов планирования/диспетчеризации для конкретных задач.
-. Предотвращение инверсии приоритетов (есть, нет, методы)
-. Реализация искл. доступа к ресурсам.
-. Контроль задач (события, таймеры и др.)
-. Запуск системных и доп. процессов (методы для таймеров, ISR и т.д.)
-. Реализация HAL.
-. API - предоставляемые возможности.
-. Доп. средства (GUI, TCP/IP и т.д.)
-. Общая оценка.***

Вообще-то я занимался разработкой ртос. Но ваши вопросы как то уж очень широко поставлены.
Это называется курс лекций по теме - разработка и архитектура ртос...
Как все это обсуждать в форуме?
Или вы хотите сформулировать пособие по разработке ртос для всех желающих...а оно надо? добром не кончится если все желающие станут писать ртосы. По пособиям.

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

Мое мнение в результате опыта разработки
Хорошая ртос это
1. реализованная на C++
2. четкий и компактный HAL
3. Нечто вроде микроядра с релизацией подкачки компонент ядра и других компонент оси
4. Многозадачность вытесняющая, с динамическими приоритетами
5. Синхронная - листенеры(хуки) и асинхронная активация(события) кода
6. Разделение ресурсов методом вроде синхронизирующих механизмов java. Вообще вычислительная модель java - видится как минимальная но полная. То есть ее и надо посмотреть в первую очередь.
7. Хорошая защита системы от "лома". То есть разделение прав доступа задач и тредов к программным и физическим обьектам.

8. Проблемы устойсчивости - то есть упавшая задача не должна обрушить систему целиком. Вопросы утилизации ресурсов занятых упавшей задачей и все такое.

9. Реализация "стандартных" протоколов и драйверов, вроде компортов, тср/ip и проч

... разумеется тут писать можно много и долго..это я бессистемно написал первое что приходит в голову, ...по опыту работы.

Вообщем тема слишком большая...замечу что просто исследование чужих исходников - часто просто потеря времени. Вы не заметите узких мест только по тексту и "поймете" работу такого софта очень приблизительно.

Вообще архитектуру ртос надо анализировать и формулировать на уровне системного анализа и математики кое какой...а как там пишут ртос отдельные авторы... все равно что изучать архитектуру зданий по конструкции избушек в деревне.
TMX
Спасибо за развернутый топик.
Пожалуйста, прочтите это сообщение хотя бы до вопросов, оно многословное, просто потому, что поговорить не с кем.
Я в этой области не профессионал (разрабатываю ОС не за деньги), просто как-то попалась в руки книжка 1984г. издания Кейслер "Разработка ОС для малых ЭВМ", а я как раз изучал м/к Fujitsu и увидел, что параметры малых ЭВМ 70-х соответствуют одному камню, а воротили на них серьезные задачи. Ну я взял библиотеке книжки Шоу, Дейтела, скачал книжки Лябрусса, несколько исходников и написал на их основе ядро ОС, заточенное под F2MC, реализующее всего несколько функций: создание, запуск, приостановку и остановку задачи, захват и освобождение счетного семафора.
При разработке ставил следующие требования:
1. Минимальное время запрещения прерывания системными задачами.
2. Минимальное использование ОЗУ
3. Возможность освобождения семафора из-под прерывания.
4. Минимальное время вызова задачи, висящей на семафоре при возникновении события.
5. Возможность round-robin.
6. Динамические приоритеты.

Результат:
1. Макс. время запрещения прерываний - 30 тактов (<2мкс на 16 МГц)
2. Использование ОЗУ - 52 байта на задачу + стек задачи.
3. есть, прерывание может возникнуть даже во время обработки системной очереди на выполнение, освободить семафор, т.е. взять задачу из очереди на ресурс и поставить в очередь на выполнение, при макс. приоритете новая задача запустится первой.
4. Макс. время запуска ок. 5мкс.
5,6 - есть.
Требует ок. 15% проц. времени при 25 задачах.
Отдельный системный стек.

Конечно, система не идеальна (строго говоря, и не ОСРВ, впрочем, как и uCOS)
1. Ограниченное количество задач (до 29) - просто в ядре м/к имеется 32 банка РОН (все равно расчитывалась на внутр. ОЗУ, а его объем в Fuji мал: обычно 2-4 кБ).
2. Нет контроля за инверсией приоритетов и взаимной блокировкой (и вообще не ясно, как это сделать малой кровью при динамических приоритетах).
3. Нет встроенных сервисов типа таймеров, очередей и т.д. (можно реализовать семафором и спец задачей на очереди) - просто руки не дошли.
4. Очередь семафоров сделана по принципу FIFO - чтобы занимала меньше времени на обработку.

В процессе работы появились некоторые вопросы:
1. Как запускать обработчики таймеров в системе с фиксированным количеством задач? Знаю несколько решений, однако не знаю, какое наилучшее.
2. Какой набор примитивов ядра достаточен?

Поскольку эту задачу я делаю на досуге, в фоновом режиме, есть время почитать о разных методах и подходах к анализу моделей (математика кое-какая) и реализации. Попробовать разные решения - у всех свое хобби: кто-то модели самолетов делает, кто-то в машине копается, я вот про ОС статьи читаю.

Сейчас появилось много микроконтроллеров с ядром ARM7, поэтому я начал писать ОС, заточенную чисто под них.
Требования:
1. Минимальное время запрещения прерывания.
2. Минимальное использование памяти ОЗУ (должна работать с 20-ю задачами на ADuC 7020 - 8 кБ).
3. Жесткое реальное время - можно рассчитать время реакции (может быть и большИм, главное - предсказуемым).

Сразу воникли вопросы по архитектуре и реализации:
1. Основной вопрос по реализации: Как вызывать диспетчер? В Fuji я использовал для этого специальное отложенное программное прерывание с наименьшим приоритетом: т.е., например, в обработчике прерывания освобождался ресурс, задача из очереди на семафор ставилась в очередь на выполнение и выставлялся флаг отложенного прерывания. При выходе из обработчика система сразу заходила в обработчик этого отложенного прерывания т.е. диспетчер. Также флаг мог выставляться из-под прерывания 1 мс таймера с наивысшим приоритетом.
Как сделать это на ARM непонятно: использовать инстр. SWI? - она не отложенная, использовать программное выставление одной из линий прерывания - вообще ерунда какая-то.
Может сделать диспетчер не в обработчике прерываний, а задачей с макс. приоритетом? Это заметно увеличит время его запуска, что важно в обработчиках прерываний. Есть какие-либо советы на этот счет?

2. Сейчас я реализовал следующий алгоритм приоритетов, считаю идею красивой: приоритеты могут иметь значение от -8.192 до +8.192, в порядке уменьшения. Отр. приоритеты - статические, положительные приоритеты - динамические, уменьшаются до -1 и останавливаются. 0 - отдельно, мин.приоритет вообще(статический). Т.о. в системе может быть полностью с динамич. или полностью стат. приоритетами, или и теми и др. (например, одни - для драйверов, другие - для задач пользователя). Какие недостатки? Следует ли повышать динам. приоритет задачи, если она стоит в очереди к ресурсу? Как лучше организовать увеличение динам. приоритета - при каждом запуске диспетчера или по таймеру? (сейчас сделано по таймеру, типа, для deadline monotonic analisys).

3. Захват и освобождение ресурса сделаны по следующему принципу: сортировка очереди происходит при постановке ресурса в очередь, поскольку опыт показал, что возможность освобождения ресурса из-под прерывания очень удобна, поэтому там все должно быть уже отсортировано и время минимально. Для этого реализованный алгоритм сортировки подразумевает, что очередь может изменяться в момент сортировки: например, сработало прерывание и освободило этот ресурс. Или сработало прерывание, освоб. др. ресурс -> запустилась ожидающая его задача с более высоким приоритетом, и захватила рассматриваемый ресурс (или встала в сортируемую очередь к нему). Где можно почитать о подобных методах? Обычные алгоритмы сортировки подразумевают, что очередь статична.

4. Следует ли создавать для системных процессов и драйверов отдельную очередь на выполнение для уменьшения времени отклика?

5. Минимальный набор примитивов для микроядра? (в т.ч. посмотрю Java)

6. Алгоритм запуска системных обработчиков, если задачи исполняются из ПЗУ? т.е. новую задачу создавать нельзя. Пример: обработчик таймера - досчитывает в прерывании, выкидывается на выполнение, а куда? Большинство решений предполагает системный процесс с макс. приоритетом, который стоит на семафоре к очереди ф-ий обр. вызовов: как только появляется новая ф-я он ее вызывает и выполняет. Недостаток - кол-во параллельно выполняемых ф-ий равно кол-ву зарезервированных сист. процессов. Невозможно менять приоритет обработчика таймера (всегда макс.). Хотя было бы удобно, чтобы обработчик таймера наследовал приоритет запустившего процесса.
В некоторых системах, насколько я знаю в WinCE, СМХ есть HLL - hardware link layer - фактически, в ф-ии обработки прерывания разрешаются прерывания, при этом нет повторной входимости и т.п.
В PORTOS идея в том, что существует очередь т.н. приоритетных функций, наследующих приоритет, которая является чем-то вроде отдельной вытесняющей не round-robin ОС на системном обработчике (склоняюсь к этому решению). Может посоветуете что-нибудь получше?

7. В литературе обычно рассматриваются протоколы захвата/освобождения ресурсов для единственного ресурса. Какие использовать в других случаях, например, управления памятью?

8. В своих статьях специалисты ф. GreenHill пишут, что в их ОС прерывания в системных процессах не запрещаются никогда. Как это реализовано?

Цитата(merk0 @ May 6 2005, 17:45)
Мое мнение в результате опыта разработки
Хорошая ртос это
1. реализованная на C++
2. четкий и компактный HAL
3. Нечто вроде микроядра с релизацией подкачки компонент ядра и других компонент оси
4. Многозадачность вытесняющая, с динамическими приоритетами
5. Синхронная - листенеры(хуки) и асинхронная активация(события) кода
6. Разделение ресурсов методом вроде синхронизирующих механизмов java. Вообще вычислительная модель java - видится как минимальная но полная. То есть ее и надо посмотреть в первую очередь.
7. Хорошая защита системы от "лома". То есть разделение прав доступа задач и тредов к программным и физическим обьектам.

8. Проблемы устойсчивости - то есть упавшая задача не должна обрушить систему целиком. Вопросы утилизации ресурсов занятых упавшей задачей и все такое.

9. Реализация "стандартных" протоколов и драйверов, вроде компортов, тср/ip и проч

*


ответы по пунктам для микроконтроллеров:
1. Часто среды разработки для микроконтроллеров не поддерживают С++.
2. согласен, осталось выбрать соотв. набор функций.
3. Вещь полезная, но в случае м/к лучше организовать бутлоадер с выходом в сетевой протокол и грузить все ОС и приложения в сборе - при работе из ПЗУ все равно динамически подгружать/выгружать толком не получится.
4. Вытесняющая - совершенно верно, причем вытеснение происходит по событию, а не по таймеру, динамические приоритеты - вещь трудно прогнозируемая, они требуют значительных ресурсов на реализацию протоколов захвата/освобождения ресурсов, впрочем, см. выше.
5. Само собой.
6. Спасибо за наводку - посмотрю.
7. Механизмы контроля памяти без MMU требуют больших накладных расходов и специализированных средств разработки приложений. Вопрос важный, но я пока не знаю, как его красиво решить. Сейчас я сосредоточился на примитивах для ядра.
8. Это вытекает из предыдущего пункта.
9. важно, но не главное для архитектуры.

Цитата
Вообщем тема слишком большая...замечу что просто исследование чужих исходников - часто просто потеря времени. Вы не заметите узких мест только по тексту и "поймете" работу такого софта очень приблизительно.

А часто и нет. Мне часто достаточно идею понять.

Цитата
Вообще архитектуру ртос надо анализировать и формулировать на уровне системного анализа и математики кое какой...а как там пишут ртос отдельные авторы... все равно что изучать архитектуру зданий по конструкции избушек в деревне.

Если провести эту аналогию дальше, то я пытаюсь строить коттедж, а не аквапарк ;-)
Насчет изучения - вы, наверное, никогда не занимались архитектурой жилых помещений.
Изучение избушек полезно:
во-перых, можно изучать традиции зодчества в данном регионе - можно по теор. правилам спроектировать очень неудобное здание.
во-вторых, можно посмотреть реализацию некоторых идей, встречаются очень красивые решения.
в-третьих, называть Integrity или eCOS или PORTOS избушками некорректно.
в-четвертых, все избушки в основе имеют какой-то план.
в-пятых, если избушка была неудобна - пристройки сразу бросаются в глаза.
в-шестых, прогулки на свежем воздухе вообще полезны :-)
merk0
Поскольку у вас вопросов много..я отвечу пока только на один. Возможно он изменит ваши взгляды на систему.

...У вас какой-то сложный взгляд на мир вычислений.
Предлагаю модель - проще не придумаешь
1. Есть треды как независимые единицы исполнения.
2. Есть разделяемые тредами обьекты - например какие- то данные. Такие данные защищаются явными или скрытыми механизмами разделения доступа. Они защищают только от проникновения тредов и больше ни от чего.
3. Есть События - этакие "письма" пересылаемые внутри системы между обьектами. События могут быть адресными и широковещательными или групповыми.
4. Есть Источники Событий - то, что может посылать события.
5. Треды могут вставать в ожидание событий. Треды также могут быть источниками событий. Треды дождавшиеся События, активизируются только решедулером.

Все!
Модель системы готова.

Это примерно модель java.
Все остальные модели являются ее клонами или раширениями. Разумеется когда мы говорим о многозадачности.

Далее, то что вы называете - таймерами, если я правильно вас понял - это просто Источники Событий некого рода.
То что вы называете прерываниями - тоже источники событий.

Чтобы написать( как вы спрашиваете ) ядро без запрета прерываний - нужно просто прерывания оформить в стиле источников событий. То есть физический источник события просто вкидывает Событие в некий буфер, и обозначает ассоциированную процедуру обработки или тред ожидающий события как Активный. А решедулер, затем запускает эти помеченные как активные, обьекты(треды). Это самыми общими словами. ТО есть запрет прерываний тут происходит только на этапе вбрасывания события в буфер и выборки его тредом из буфера. Чтобы источник событий и приемник - не столкнулись.

Иного способа написать ядро без запретов прерываний - нет.

Ваше требование - юзать обьекты ядра из прерываний - тут же делают невозможным написать ядро без запрета прерываний.

И вы повторяете эту распространенную ошибку.
Приведет она вот к чему.
Если в реализации ядра вы станете запрещать прерывания, то даже регулярные треды общаясь между собой через функции ядра, будут запрещать их. При активной работе пользовательских программ окажется что прерывания часто запрещены и ваша система откажется принимать данные с портов(например), просто при активной работе прикладных тредов. То есть прикладные задачи блокируют ввод-вывод.
Вот такие дела.

Итак - казалось вы хотели быстрой реакции.. а получили - никакую реакцию и пропуски событий.
TMX
Цитата(merk0 @ May 7 2005, 23:52)
Это примерно модель java.
Все остальные модели являются ее клонами или раширениями. Разумеется когда мы говорим о многозадачности.

Я наоборот считал, что мое представление одно из простейших. Сложности возникают при реализации.
Насчет модели описанной вами модели java - все нормально, пока нет необходимости обеспечить гарантированное время отклика. Дело в том, что в прикладных задачах, над которыми я работаю, очень размытая граница между драйверами и пользовательскими процессами, скорее даже полноценных пользовательских процессов почти нет. Поэтому у меня сложилась модель ОС для управления работой драйверов, по-моему, она не противоречит модели java.

Цитата
Ваше требование - юзать обьекты ядра из прерываний - тут же делают невозможным написать ядро без запрета прерываний.

Просто при построении модели я хотел сделать предсказуемое время реакции пользовательского уровня ОС на хардварное событие. Варианты формирования и обработки событий на более высоких уровнях требуют дополнительных расходов ресурсов.

Цитата
Итак - казалось вы хотели быстрой реакции.. а получили - никакую реакцию и пропуски событий.
*

Во-первых, приоритет прерываний выше приоритета пользовательских процессов и ядра, т.е. при разрешенных прерываниях они всегда вытесняют текущий процесс за известное время.
Во-вторых, если в запрещать прерывания на жестко ограниченные периоды времени, то время задержки прерывания можно рассчитать - пусть оно ненулевое, но известное (т.е., например, в диспетчере: при сортировке очереди на выполнение прерывания запрещаются не на все время сортировки (которое зависит от размера очереди и поэтому не предсказуемо), а периодами - на время анализа очередного элемента (которое известно), в случае возникновения прерывания диспетчер вытесняется, обработчик прерывания может добавить к сортируемой очереди процесс, который тоже будет отсортирован).
TMX
Цитата(merk0 @ May 7 2005, 23:52)
Далее, то что вы называете - таймерами, если я правильно вас понял - это просто Источники Событий некого рода.
То что вы называете прерываниями - тоже источники событий.

Чтобы написать( как вы спрашиваете ) ядро без запрета прерываний - нужно просто прерывания оформить в стиле источников событий. То есть физический источник события просто вкидывает Событие в некий буфер, и обозначает ассоциированную процедуру обработки или тред ожидающий события как Активный. А решедулер, затем запускает эти помеченные как активные, обьекты(треды). Это самыми общими словами. ТО есть запрет прерываний тут происходит только на этапе вбрасывания события в буфер и выборки его тредом из буфера. Чтобы источник событий и приемник - не столкнулись.

Иного способа написать ядро без запретов прерываний - нет.

Таймеры отличаются тем, что события в них инициализируются пользовательскими процессами, имеющими различные приоритеты и в произвольном порядке. Таким образом, допустим, мы используем некий буфер для Событий. Если физический источник События - прерывание или процесс, то мы можем выделить каждому источнику отдельный буфер и обрабатывать поступившие туда события по принципу FIFO. Если источник событий - таймер, то мы должны обеспечить сортировку Событий либо при помещении в буфер, либо при изъятии из него, это гораздо сложнее и требует запрещения прерываний на время сортировки. Существует вариант динамического выделения отдельного буфера размером один элемент каждому событию таймера (поскольку нам неизвестно их число) - тоже неясная задача.
merk0
***но известное (т.е., например, в диспетчере: при сортировке очереди на выполнение прерывания запрещаются не на все время сортировки (которое зависит от размера очереди и поэтому не предсказуемо), а периодами - на время анализа очередного элемента (которое известно)***

Проблемы будут.
Например если список линейный, то если в данный момент(когда прерывания запрещены) поле next у текущего элемента имеет одно значение, то если вы прерывания разрешили, а потом опять запретили...поле next может быть уже совсем другим. а самого элемента this - может уже и не быть в очереди. Кто то его вытащил.
То есть кто-то может вам просто "оборвать" список. Это будет трудноуловимой ошибкой, поскольку получится при коллизии доступа к текущему или следующему элемента списка.

То есть если вы работаете с элементом - монопольно, вы не имеете права брать next от текущего элемента, запоминать и использовать его в следующем "такте" монопольной работы.
Если же вы будете думать что текущий в "такте" монопольной работы - действительно в списке(поскольку в предыдущем такте он там был!) - вас ударит с другого конца. Если его уже вытащили оттуда, его поле - next - будет nil.
Как будем выкручиваться?
merk0
Если таймеры у вас в системе "жесткие", что обычно бывает в ртоc, то они реализуются так.
На аппаратном таймере сидит процедура, что запускает таймерные хуки(функции определяемые пользователем) по списку "взведенных" таймеров. Такие хуки запускаются синхронно, то есть прямо фактически из прерывания, правда перед запуском хуков прерывания от аппаратного таймера разрешаются.
Хуки не могут пытаться втстать в ожидание, поскольку синхронный код, запускаемый из прерывания не может это делать - система рухнет. Но для особо привязанных ко времени приложений, типа лампочкой попикать или в порт байты кидать - такое - работает хорошо и быстро.

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

Вообще вариантов реализации таймеров и их разновидностей много.

Это я сказал как оно реализовано в ядре. Для пользователя же, это может быть оформлено, как специальный источник событий. Если пользователь хочет просто получать евент или мессагу в очередь мессаг треда, он попросит EventSource кидать событие в очередь, если захочет написать хук - сделает соотв Listener, и прицепит его к данному EventSource. В первом случае он будет реагировать на event асинхронно, во втором - синхронно.
TMX
Цитата(merk0 @ May 11 2005, 15:04)
Проблемы будут.
Например если список линейный, то если в данный момент(когда прерывания запрещены) поле next у текущего элемента имеет одно значение, то если вы прерывания разрешили, а потом опять запретили...поле next может быть уже совсем другим. а самого элемента this - может уже и не быть в очереди. Кто то его вытащил.
То есть кто-то может вам просто "оборвать" список. Это будет трудноуловимой ошибкой, поскольку получится при коллизии доступа к текущему или следующему элемента списка.
********************
Как будем выкручиваться?
*


Так и я спрашивал о методах работы с "динамическими" очередями (вопр.№3)! Пока приходится изобретать самому. В ОС для Fuji я решил эту проблему для диспетчера - он работает с динамической очередью, в которую обработчики прерываний могут асинхронно добавлять элементы. В ОС над которой я работаю сейчас я эту проблему решил для задачи захвата ресурсов - в очередь могут добавляться элементы и из очереди могут удаляться элементы.
TMX
Цитата(merk0 @ May 11 2005, 15:23)
Если таймеры у вас в системе "жесткие", что обычно бывает в ртоc, то они реализуются так.
На аппаратном таймере сидит процедура, что запускает таймерные хуки(функции определяемые пользователем) по списку "взведенных" таймеров. Такие хуки запускаются синхронно, то есть прямо фактически из прерывания, правда перед запуском хуков прерывания от аппаратного таймера разрешаются.
Хуки не могут пытаться втстать в ожидание, поскольку синхронный код, запускаемый из прерывания не может это делать - система рухнет. Но для особо привязанных ко времени приложений, типа лампочкой попикать или в порт байты кидать - такое - работает хорошо и быстро.

я об этом методе говорил в своем обширном топике - это когда обработчик таймера переходит на т.н. уровень HLL (hardware link layer). Меня не устраивает.
Цитата
Мягкие таймеры, для задач, когда отклонение на квант работы одного треда не играет роли - например что-то выводить на экранчик периодически юзеру...активируются из системного треда - опросчика таймеров. Он себе крутится пока очередь таймеров не пуста и спит, когда пуста.

Основной вопрос - как управлять приоритетом этого треда? Хотелось бы чтобы его текущий приоритет был равен приоритету запустившего таймер процесса. Конечно можно делать отдельный тред на каждый таймер, но это потребует отдельного контекста, что нежелательно при небольшом объеме ОЗУ.
Возможно я слишком многого хочу, но было бы удобно запускать таймер следующей ф-ей:
timer_start (int ms, void(*callback)(void)), где callback - указатель на ф-ю обратного вызова.
Запускать этот указатель из под прерывания проблем не составляет - у меня есть библиотека и не для ОС (просто вызываешь ф-ю по указателю из обработчика и все).
А вот в треде возникают проблемы о которых я уже писал.

Цитата
Это я сказал как оно реализовано в ядре. Для пользователя же, это может быть оформлено, как специальный источник событий. Если пользователь хочет просто получать евент или мессагу в очередь мессаг  треда, он попросит EventSource кидать событие в очередь, если захочет написать хук - сделает соотв Listener, и прицепит его к данному EventSource. В первом случае он будет реагировать на event асинхронно, во втором - синхронно.


про listener можно поподробнее? Это то что я назвал callback?
merk0
***Основной вопрос - как управлять приоритетом этого треда? Хотелось бы чтобы его текущий приоритет был равен приоритету запустившего таймер процесса. ***

Зачем? Таймеры - это обьекты чьи срабатывания привязаны ко времени. Чем точнее они привязаны - тем лучше. То есть таймерный тред должен быть более приоритетным, чем все остальные. Мягкие таймеры обычно обслуживают прикладной софт, а жесткие - системный.

То есть приоритет таймерного треда должен быть просто выше приоритета тех тредов, что пользуются этими событиями - то есть выше прикладных.
Вообще приоритет расставляется по признаку - что важней.
Никто не мешает запускать несколько тамйрных тредов обслуживающих свое множество таймеров. Один - таймеры прикладные - его приоритет выше махUserPriority, но меньше minSystemPriority. Системные мягкие таймеры обслуживаются тредом, что выше MaxSystemPriority. Ну и так далее.

***Конечно можно делать отдельный тред на каждый таймер, но это потребует отдельного контекста, что нежелательно при небольшом объеме ОЗУ.***
Сделать можно, с точки зрения общей теории листенер(ну да это callback оформленный как класс) - будет можно ставить в ожидание, только это весьма избыточно для листенеров вообще.


***Возможно я слишком многого хочу, но было бы удобно запускать таймер следующей ф-ей:
timer_start (int ms, void(*callback)(void)), где callback - указатель на ф-ю обратного вызова.***

Ну оформите так как написали.

листенер - это просто класс имеющий виртуальный метод on_event. Создав свой наследник от базового класса, вы переопределяете этот метод, определяя свою функциональность. А у класса EventSource есть метод - add(Listener& fl) и соотв - remove(Listener& fl). Экземпляр листенера вы добавляете к какому-то евентсорсу, технически он заносится в список листенеров данного сорса. при "событии" список листенеров сорса сканируется и у каждого запускается метод - on_event. Так что это колбек, но в терминах ооп. К тому-же каждый листенер может иметь свои переменные в обьекте и работать с ними.

Вообще то чем я занимаюсь сейчас...пересказываю сиплюсный текст нашего последннего ядра простыми словами...
TMX
Цитата(merk0 @ May 11 2005, 19:06)
Зачем? Таймеры - это обьекты чьи срабатывания привязаны ко времени. Чем точнее они привязаны - тем лучше. То есть таймерный тред должен быть более приоритетным, чем все остальные. Мягкие таймеры обычно обслуживают прикладной софт, а жесткие - системный.
*

Ну, крыть нечем, обосновали.
Просто тогда неясно как рассчитывать время реакции:
например:
есть N процессов с низким приоритетом, во время работы запускающие таймеры, и 1 процесс с высоким приоритетом, ожидающий события. Это событие возникает и запускает высокоприоритетный процесс на выполнение.
Вопрос: какая будет задержка для худшего случая?
Ответ:
1. В случае, если таймеры наследуют приоритет, то задержка будет равна задержке диспетчера.
2. В случае, если таймеры имеют наивысший пользовательский приоритет, то задержка будет равна времени выполнения всех таймеров плюс какое-то количество запусков диспетчера (у меня - каждые 1 мс). Некрасиво получается.

А listener - хорошая вещь. Мне в ОС на С такое приходится делать ссылкой на список аргументов, уничтожаемый при вызове callback. (Ф-я с переменным числом параметров не подходит, потому что они не передаются как надо).
merk0
теоретически вы правы, про таймеры..но
практически - установить N таймеров так что они будут срабатывать прямо все сразу - затруднительно даже специально. Их срабатывание распределено во времени случайно. А метод - on_clock() - обычно очень короткий.
Таймеры в системе о которой я говорю вообще должны работать так, чтобы успеть выполниться до следующего тика аппаратного таймера и не задерживать такт диспетчера до следующего. Поскольку если такое происходит - система станет работать плохо.
То есть в ваших временных интервалах таймеры должны сработать короче чем за 1 мс, а потом переключится тред. То есть задержки быть не должно.
Если же время выполнения on_clock() будет выше чем 1 мс, то это отложит переключение тредов до следующих тактов, что плохо.
Таймеры не регулярное средство программирования, а вспомогательное, просто привязка к физическому времени системы, потому, мое личное мнение, доводить их "до ума" - не стоит.

то есть можно сделать так, чтобы таймерный тред менял приоритет - устанавливая его равным максимальному приоритету таймеров в списке...то это вызовет дополнительные расходы на изменение приоритета...впрочем это немного, а вот будет ли реальный от этого эффект - сказать сложно. Если он и будет - то при высокоих уровнях загрузки процессора,..а при таких уровнях говорить о гарантированном времени реакции - вообще уже нельзя.
TMX
[quote=merk0,May 11 2005, 22:38]
теоретически вы правы, про таймеры..но
практически - установить N таймеров так что они будут срабатывать прямо все сразу - затруднительно даже специально. Их срабатывание распределено во времени случайно. А метод - on_clock() - обычно очень короткий.
[quote]
Ну, для soft Real-Time можно рассматривать статистическое распределение срабатывания таймеров, исходя из каких-то предположений. А для Hard Real-Time надо рассматривать наихудший случай (Worst Case Analisys).

[/quote]
Таймеры в системе о которой я говорю вообще должны работать так, чтобы успеть выполниться до следующего тика аппаратного таймера и не задерживать такт диспетчера до следующего. Поскольку если такое происходит - система станет работать плохо.
[quote]
Как я понял, в преиведенном варианте реализации:
Сумма времен исполнения обработчиков <1мс. При этом считается, что запуск и срабатывание таймеров распределены во времени более-менее равномерно. Для большинства задач сгодится. Просто я делаю систему под себя, а в моих задачах есть спорадические события - практически одновременное срабатывание защит, я обрабатываю их таким же способом, но иногда думаю о возможностях оптимизации.

[quote]
Таймеры не регулярное средство программирования, а вспомогательное, просто привязка к физическому времени системы, потому, мое личное мнение, доводить их "до ума" - не стоит.
[/quote]
Ну не знаю, например при организации протокола обмена по сети, например, в соответствии со стандартом OSEK/NMI, к каждому сообщению приходится добавлять таймер. Причем сообщения могут быть и между приложениями. Таймеров набирается много и ,главное, приоритеты у всех различные.

[quote]
то есть можно сделать так, чтобы таймерный тред менял приоритет - устанавливая его равным максимальному приоритету таймеров в списке...то это вызовет дополнительные расходы на изменение приоритета...впрочем это немного, а вот будет ли реальный от этого эффект - сказать сложно. Если он и будет - то при высокоих уровнях загрузки процессора,..а при таких уровнях говорить о гарантированном времени реакции - вообще уже нельзя.
[/quote]
Вы правы. Но проблема не в том, чтобы таймерный тред менял приоритет, а в вытеснении обработчиков.
Пример: сработал таймер с низким приоритетом, запустил обработчик в треде; запустилась задача с приоритетом выше и вытеснила обработчик таймера; сработал таймер с высоким приоритетом и его обработчик ждет окончания совершенно левой задачи, чтобы закончить предыдущий и запуститься.
Т.е. налицо инверсия приоритетов, хотя в данном случае можно использовать протокол наследования приоритетов в самом простом варианте.

Кстати, как в Вашей системе решается проблема инверсии приоритетов?
merk0
В той идеологии, что исповедую я, жесткие таймеры никогда не прерываются тредами. и не могут их вытеснить. Они работают в начале кванта времени системы, остаток же кванта работает какой-то тред.
Мягкие таймеры - по сути просто тред высокого приоритета, и вызываемые из него колбеки - имеют приоритет этого треда, что "крутит" мягкие таймеры. То есть любой тред что выше приортетом, чем тот что крутит таймеры - будет прерывать колбеки этих мягких таймеров.

В чем проблема? Я не понимаю, что такое у вас - таймеры высокого приоритета. Зачем придумывать таймерам какие-то иные приоритеты чем приоритет того кода что их вызывает синхронно. Я имею ввиду то, что если низкоприоритетный тред, зачем-то получил доступ к системным мягким таймером(кто вообще дал ему такой доступ? это должно быть блокировано через апи) - то такой хук будет выполняться в высоким приоритетом автоматически.
В хорошем апи системные(то есть суперприоритетные) мягкие таймеры не видны через апи, ими пользуются только системные задачи или треды, те кому предоставлен системный апи.
То есть раскладка по эффективным приоритетам такая.

сверху вниз
1. аппаратные прерывания
2. мягкие системные таймеры
3. треды ввода-вывода(те что обслуживают данные берущиеся от прерываний)
4. просто системные треды
5. мягкие таймеры прикладные
6. прикладные треды
7. тред что слипает систему.

То есть тут два слоя - системный и прикладной.
Никто не мешает еще подразбить систему на "слои" - это ваше дело. Даже можно вделать в систему механизм генерации такого нового слоя...например существуют среди разрабюотчиков прикладники-полусистемщики и прикладники-типа раздолбай. Вот этим группам можно выделить свой особый слой каждой, тогда вторые не смогут всерьез портить первым жизнь своим разнузданным программированием.
TMX
Цитата(merk0 @ May 12 2005, 13:47)
сверху вниз
1. аппаратные прерывания
2. мягкие системные таймеры
3. треды ввода-вывода(те что обслуживают данные берущиеся от прерываний)
4. просто системные треды
5. мягкие таймеры прикладные
6. прикладные треды
7. тред что слипает систему.

Я уже практически все это реализовал, очень похоже получилось - отр.значение приоритета - системные треды, положительное динамич. значение - прикладные. Но нет предела совершенству ;-)

Насчет решения проблемы инверсии приоритетов не могли бы ответить (если не секрет).
merk0
я бы не стал на вашем месте концентрироваться на этом вопросе, вы всегда сможете добавить потом нужную функциональность.
Мне кажется это проблема - достаточно академична, и в реальной жизни роли не играет.
Кажется что-то про нее я читал в документации к eCOS. Но в нашей оси ничего подобного мы не делали. У нас была несколько иная архитектура и я прочитал про эти "неприятности" в eCOS- по диагонали.
В любом случае добавить в ядро скрытое изменение приоритетов тредов - проблем не составляет.

Когда я говорил о динамических приоритетах, я имел ввиду не этот вопрос конкретно, а возможность треду менять приоритет самостоятельно во время работы. То есть программист может это делать. Но строго говоря - это источник неприятностей связаннных с некорректным стремлением многих программеров, сделать своим тредам слишком выскоий приоритет. Это влияет на другие программы, и часто они начинают работать плохо.
то есть пока я придерживаюсь концепции статических приоритетов, а если и давать возможность программеру менять треду приоритет, тут надо делать еще и какую-то защиту от проблем, что он может породить.
TMX
Цитата(merk0 @ May 12 2005, 17:27)
я бы не стал на вашем месте концентрироваться на этом вопросе, вы всегда сможете добавить потом нужную функциональность.

"лучше день потерять, а потом за пять минут долететь" - надо мной сроки не висят, есть возможность поэкспериментировать.
Цитата
У нас была несколько иная архитектура и я прочитал про эти "неприятности" в eCOS- по диагонали.

А что за архитектура такая иная? Можно в общих словах охарактеризовать?
С несравниваемыми приоритетами как у Бабаоглу? (приоритеты задач можно сравнивать только попарно).
Или удалось создать модель реального времени с размножением ресурсов? т.е. без захвата/ожидания?

Цитата
То есть программист может это делать. Но строго говоря - это источник неприятностей связаннных с некорректным стремлением многих программеров, сделать своим тредам слишком выскоий приоритет. Это влияет на другие программы, и часто они начинают работать плохо.
то есть пока я придерживаюсь концепции статических приоритетов, а если и давать возможность программеру менять треду приоритет, тут надо делать еще и какую-то защиту от проблем, что он может породить.
*

Ну у меня есть динамические приоритеты в смысле повышающиеся с каждым тиком таймера, как у Liu написано. Это может служить некоторой защитой.
Возможно имеет смысл таймер запускать - изменять приоритет на некоторое время?
merk0
по моему вы увлекаетесь этими приоритетами. Как показывает практика управлять динамикой задач, просто играя их приортетами, можно только вочень узком дипазоне и потом - это очень неустойчивая система если системе необходим точный тюнинг приоритетов.
Просто софт делится на слои - более важные, менее важные, не важные, совсем никакие и проч. И реально в системе крутятся треды всего-то с 6-7 разными приритетами, вообще их не меняя никогда. И все работает стабильно. ЕСли не работает стабильно то
- что-то написано плохо(обычно как раз то что плохо работает)
- кто-то внаглую отьедает чье-то время и важная задача тормозит.
- система настолько перегружена высокоприоритетными задачами, что никакая новая идеология уже не поможет. Просто надо брать более мощный процессор и больше памяти. либо все написано из рук вон плохо.
Вообщем я бы делал приоритеты статическими, делил систему на слои и имел запас по мощности проца.
И ну их - эти повышения приоритетов по тикам. Кстати чего ради приоритет должен расти от времени? Приоритет это Важность данной задачи по отношению к другим задачам. Важность - понятие статическое. Значит и приоритет должен быть статическим.
TMX
По моему мнению, критерий РВ один - предсказуемость. Из этого вытекает мой интерес к приоритетам. Для инверсии приоритетов (основной проблемы для предсказуемости) достаточно трех слоев задач, обращающихся к одному ресурсу. Или в Вашей модели доступ к ресурсам зависит от слоя? Как тогда организуется доступ к памяти (особенно важно для С++)?
Цитата(merk0 @ May 12 2005, 20:29)
И ну их - эти повышения приоритетов по тикам. Кстати чего ради приоритет должен расти от времени? Приоритет это Важность данной задачи по отношению к другим задачам. Важность - понятие статическое. Значит и приоритет должен быть статическим.
*

Ну как это, ради чего - существует модель анализа Deadline Monotonic, в которой приоритет задачи обратно пропорционален времени до дедлайна. Т.е. указываем время, в течение которого задача должна быть обработана - оно статическое, но если задачу не обрабатывать, то приоритет растет.
merk0
Вы очень уж абстрактно академично рассматриваете систему.
По вашему высокприоритетная(вп) и низкоприоритетная(нп) задачи пытаются работать с одним ресурсом.
Тогда могу выдвинуть общее утверждение. В силу неизбежности разделения доступа к ресурсу, нп-задача будет в каких-то случаях блокировать вп -задачу. И ничего другого быть не может.
Вопрос решется радикально, как в теории так и в практике.
На практике задачи таких разных приоритетов живут в своих окружениях и весьма редко(если это случается - это скорее недочет разработчика) обращаются к общим разделяемым ресурсам.
Потому в практике такие блокировки не случаются. Никогда задача высокого приоритета не пытается работать с файловой системой или брать/отдавать память, если только не при инициализации и финализации.
Вы понимаете куда я клоню?
Если ваша задача - высокого приоритета, то разумеется она не должна пытаться взаимодействовать даже косвенно с низкоприоритетными так, что это может привести к блокировке на заметное время высокоприоритетной.
В противном случае, просто рассуждая, всегда можно найти такой пример, когда низкоприоритетная заблокирует высокоприоритетую.

Потому рассуждения о инверсии приоритетов - чисто академические и сделаны при слишком вольных допущениях. И даже если так вольнго рассуждать - видно, что вопрос неразрешим в принципе на системном уровне. Всегда можно найти такой алгоритм, что привдет к блокировке.
Простейший - высокоприоритетная посылает мессагу низкоприоритетной и ждет ответа. Сразу видно, что в данной точке код вп-задачи имеет эффективный приоритет - низкий, поскольку будет возобновлен только после того когда нп-код отработает. И никакими системными конструкциями вы этого не решите. Посколку то что вп-задача ждет ответа от нп, это уже семантика кода вп задачи, который невозможно проанализировать в принципе.

А ваша инверсия приоритетов - более запутанный вариант этого типа "взаимодействия".
Kopa
По моему убеждению,
интересной идеей реализации RTОS может стать
ее написание на высокоуровневом языке максимально
близком к ассемблеру и который легко портируется для целевого процессора.

Претендентом на роль таекого языка, длительное время разрабатываемого в МГУ, может стать например ДССП ( DSSP )
диалоговый язык структурного программирования.

Ссылка ( ориентировочно) http://www.forth.org.ru/~dssp

Идеи заложенные в нем пересекаются с идеями Форт ( Forth ) языка.

При этом портировать RTОS на конкретный процессор можно отдельной програмкой-компилятором ЯВУ данного проца.( Также написанной на этом же ЯВУ) Получаем бинарный файл

А прикладным программам можно передать, интерфейс использования
сервисов!:)
-------------------------------------------------------------------------------------
P.S. При реализации поддержки данного языка в кремнии (Форт, байт код виртуальной java машины - поддержаны, по DSSP работы возможно
ведутсяsmile.gif получаем готовую операционку максимально эффекnивно
использующую процессор.
Если это стековый процессор, то одной из прелестей использования двух стековой архитектуры для быстрого переключения контекста задачи очевидны.

Попытки написать RTOS на языке Форт существуют. Порты Форта
часто пишут на Cи. Есть программы использования Форта для
разработки кода для JVM. ANSI стандарт 94-го года переведен
на русский язык. Форт, по определению, инструментальный язык.


Удачи,
( И просьба о результатах сообщить!!!!! )
bmf
Цитата(merk0 @ May 14 2005, 12:13)
На практике задачи таких разных приоритетов живут в своих окружениях и весьма редко(если это случается - это скорее недочет разработчика) обращаются к общим разделяемым ресурсам.
Потому в практике такие блокировки не случаются. Никогда задача высокого приоритета не пытается работать с файловой системой или брать/отдавать память, если только не при инициализации и финализации.
Вы понимаете куда я клоню?
Если ваша задача - высокого приоритета, то разумеется она не должна пытаться взаимодействовать даже косвенно с низкоприоритетными так, что это может привести к блокировке на заметное время высокоприоритетной.
В противном случае, просто рассуждая, всегда можно найти такой пример, когда низкоприоритетная заблокирует высокоприоритетую.
...
Потому рассуждения о инверсии приоритетов - чисто академические и сделаны при слишком вольных допущениях.

Думаю вы в корне заблуждаесь исходя только из своего личного опыта, в реальных сложных задачах все очень даже переплетается, кроме дисковой системы может быть индикация или например разделяемая внешняя шина или доступ к какому-то контроллеру. Доступ осуществляется только через блокировки, и без решения на уровне OS проблемы инверсии приоритетов ваша OS реально не будет RTOS, и проблема инверсии не тогда когда ресурс заблокирован задачей с более низким приоритетом (в этом случае процессор освободит ее максимально и расчетно быстро), а когда в этот момент начинает выполняться другая задача скажем среднего приоритета, которая не знает что высокий приоритет ждет освобождения ресурса, в этом случае блокировка может затянутся на слишком долгое как для RTOS время. Такая блокировка может случаться не часто, но ее последствия...
Самый извесный пример из инета - потеря американцами своего марсохода как раз из-из отсутсвия инверсии.
для ознакомления наберите в google "mars priority inversion"
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.