LINUX.ORG.RU

BuguRTOS исполняется пять лет!

 , , ,


0

4

В далеком 2010 году один анонимус с Нульчана (R.I.P.) решил, что он обладает достаточной квалификацией и достаточным количеством свободного времени, чтобы создать свою встраиваемую ОСРВ, или ее эрзац.

В результате, в самом конце 2010 года появилась нулевая версия BuguRTOS.

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

Из проекта, созданного ради лулзов и троллинга, получилась довольно неплохая встраиваемая ОСРВ, одна из сотен написанных, но одна из четырех, поддерживающих STM8 (современное распространенное семейство микроконтроллеров).

В своей статье, посвященной первому юбилею BuguRTOS, автор рассказывает историю возникновения проекта, благодарит всех, кто как-либо помогал проекту и принимал в нем участие, делится некоторыми планами на будущее, поздравляет всех с наступающим Новым годом.

>>> Подробности

★★★★★

Проверено: splinter ()
Последнее исправление: Psych218 (всего исправлений: 3)
Ответ на: bgrt_index_search() от Manhunt

Тяжкое наследие еще с первых экспериментов... Сам думал на clz перейти, но... Не переносимо это все, видимо дефолтная реализация все таки нужна...

shkolnick-kun ★★★★★
() автор топика
Ответ на: комментарий от bernd

Рипнулся Нульчан. Приходится счас на ССовском варианте сидеть...

shkolnick-kun ★★★★★
() автор топика
Ответ на: комментарий от shkolnick-kun

А как?

Я слишком слабо понимаю твой код, чтобы рассказывать «как надо». Как раз хотел узнать, из каких соображений ты именно такие проверки расставил. Чтобы понимание свое развить немного.

А в сферической в вакууме библиотеке... Ну вот при захвате мьютекса детектить желательно оба вида переполнений, и в обоих случаях как-то сигнализировать пользовательскому коду о возникшей проблеме. Чтобы пользователь мог в ответ на это какие-то адекватные действия выполнить. (Скажем, выполнить аварийную парковку исполнительных устройств и слить дамп памяти. Или ребутнуться. Или пойти по альтернативной ветке алгоритма, не прекращая штатную работу своего устройства. В общем, это не нам решать, как он будет выкручиваться.) В случае overflow было бы достаточно вернуть какой-нибудь E_BUSY, и оставить мьютекс в старом состоянии. В случае underflow очевидно, что программа сошла с ума, и мьютекс больше никакой адекватной синхронизации уже не обеспечивает; так что нужно вернуть какой-нибудь E_UNDERFLOW, а на любые дальнейшие попытки с этим мьютексом работать возрващать E_POISONED. Подробнее про идею poison вот тут написано: https://doc.rust-lang.org/std/sync/struct.Mutex.html

Manhunt ★★★★★
()
Последнее исправление: Manhunt (всего исправлений: 2)

Эта ОС как специально создана для ЛОРчика

af5 ★★★★★
()
Ответ на: комментарий от Manhunt

В случае overflow было бы достаточно вернуть какой-нибудь E_BUSY, и оставить мьютекс в старом состоянии. В случае underflow очевидно, что программа сошла с ума, и мьютекс больше никакой адекватной синхронизации уже не обеспечивает; так что нужно вернуть какой-нибудь E_UNDERFLOW, а на любые дальнейшие попытки с этим мьютексом работать возрващать E_POISONED.

Код в pcounter.c был сделан, чтобы считать статистику для SMP (да, есть коварный план портировать поделие на что-нибудь многоядерное), потом, чтобы считать захваченные мьютексы в протоколе highest locker (ветка 0.6.х), потом для учета приоритетов ожидающих процессов в протоколах наследования приоритетов (более новые ветки).

Проверки писались исходя из соображений типа: «Если я могу избежать хотя бы какого-то случая переполнения, то лучше это сделать».

Если сделать тип bgrt_cnt_t достаточно широким, то переполнение в «+» будет не реально (ну не получится создать в системе столько пересчитываемых сущностей).

Думаю, что надо ввести константу BGRT_CONFIG_CNT_MAX, проверять значения сверху и снизу, при опсаности переполнений тупо уходить в панику. А дальше юзер сделает вачдог, и система ресетнется.

По bgrt_index_search, сделаю BGRT_CONFIG_SEARCH для поиска через FFS, и если он андеф - то дефолтную реализацию с линейным поиском (в больших процессорах так или иначе есть FFS/CLZ, а в маленьких линейный поиск будет работать быстрей, чем бинарный).

Спасибо за критику, реально помогло!

shkolnick-kun ★★★★★
() автор топика
Ответ на: комментарий от Manhunt

Сделал панику на проверках proc->lres, нашел вот это.

Еще раз огромное спасибо, Manhunt.

shkolnick-kun ★★★★★
() автор топика
Ответ на: bgrt_index_search() от Manhunt

Doen! Ну, почти. Когда буду тестировать на ARM-ах версию 1.0.0, - доделаю, пока только #ifndef BGRT_CONFIG_USER_SEARCH.

shkolnick-kun ★★★★★
() автор топика
Ответ на: комментарий от shkolnick-kun

Думаю, что надо ввести константу BGRT_CONFIG_CNT_MAX, проверять значения сверху и снизу, при опсаности переполнений тупо уходить в панику. А дальше юзер сделает вачдог, и система ресетнется.

По bgrt_index_search, сделаю BGRT_CONFIG_SEARCH для поиска через FFS, и если он андеф - то дефолтную реализацию с линейным поиском (в больших процессорах так или иначе есть FFS/CLZ, а в маленьких линейный поиск будет работать быстрей, чем бинарный).

Угу, логично

Спасибо

На здоровье! Рад, что смог помочь

Manhunt ★★★★★
()

shkolnick-kun , по части документации не хватает описания используемого протокола приоритетизации / свитчинга. Фраза «combines both protocols» слишком размытая. В педивикии, при внимательном рассмотрении, невнятное мычание. В статьях из гуглопоиска терминологическая путаница.

Как насчет того, чтобы дать явный перечень статей, после прочтения которых смысл фразы «combines both protocols» станет кристально ясен? Как насчет диаграмм, иллюстрирующих основные сценарии работы бугуртового протокола?

Актуальна ли вот эта проблема для бугуртового prio ceiling? «A static analysis of the application is required to determine the priority ceiling for each shared resource, a process that is often difficult and time consuming. To perform a static analysis, every task that accesses each shared resource must be known in advance. This might be difficult, or even impossible, to determine for a complex application.»

Manhunt ★★★★★
()
Последнее исправление: Manhunt (всего исправлений: 1)
Ответ на: комментарий от Manhunt

Используются оба протокола одновременно:в качестве базового предлагается использовать ICP (он позволяет избежать дэдлоков на 1-процессорной системе), но если юзер зафейлил статический анализ приоритетов, то тогда начинает работать Basic Priority Inheritance (BPI).

У типа bgrt_sync_t (базовый тип для блокирующих примитивов синхронизации) есть поле prio, оно задается при инициализации.

  • Если очередь спящих процессов пуста (поле sleep) , то приоритетом структуры bgrt_sync_t является зрачение поля prio, если не пуста, то приоритетом будет максимум (на самом деле минимум) из приоритетов спящих процессов и поля prio.
  • Если в поле prio имеет более высокий приоритет по сравнению со всеми спящими процессами, то приоритетом будет значение поля prio, соответственно будет работать протокол Highest Locker (подвид ICP).
  • Если некоторые процессы в очереди имеют действующее значение значение приоритета выше, чем поле prio, то приоритет структуры bgrt_sync_t определяется по наивысшему из процессов в очереди, в этом случае будет работать протокол BPI.

Когда процесс становится «хозяином» структуры типа bgrt_sync_t, приоритет такой структуры учитывается в поле lres процесса.

  • Соответственно, действующее значение приоритета процесса определяется полем base_prio и содержимым lres, всегда выбирается наивысший приоритет.
  • При изменении приоритета любой структуры типа bgrt_sync_t, «пренадлежащей» процессу обновляется его поле lres и пересчитывается его действующий приоритет.

Реализовано это все безобразие в файле sync.c

shkolnick-kun ★★★★★
() автор топика
Ответ на: комментарий от shkolnick-kun

Спасибо за описание, общая картина немного прояснилась.

Реализовано это все безобразие в файле sync.c

Угу, у меня пока не получается осознать sync.c и sched.c

позволяет избежать дэдлоков

Конкретно это — довольно странное «преимущество».

В случае BPI, чтобы гарантировать отсутствие дедлоков, достаточно:
1. По возможности строить код так, чтобы не требовалось держать захваченными одновременно несколько разных мьютексов;
2. В тех редких случаях, когда одновременный захват нескольких мьютексов все-таки необходим, всегда захватывать их в одной и той же последовательности.

В случае ICP, чтобы гарантировать отсутствие дедлоков, необходимо правильно вычислять priority ceiling. Разве это менее хлопотно?

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

1. По возможности строить код так, чтобы не требовалось держать захваченными одновременно несколько разных мьютексов;
2. В тех редких случаях, когда одновременный захват нескольких мьютексов все-таки необходим, всегда захватывать их в одной и той же последовательности.

Это общие правила работы с блокировками в любых ОС.

Угу, у меня пока не получается осознать sync.c и sched.c

sched.c - один из самых древних файлов. Там реализован O(1) планировщик в духе Linux-2.6.10 (дада, я обчиталься Р.Лава), поддерживаются политики FIFO и RR, процесс может быть обычным (time sharing) или RT.

Обычый процесс при израсходовании кванта времени перекидывается из очереди ready в очередь expired.

RT-процесс - в зависимости от BGRT_CONFIG_HARD_RT:

  • Если используется, то по израсходовании кванта времени его останавливают, если при этом он еще и залочен то остановки, то его «убивают».
  • Если не используется, то по израсходовании кванта времени просцесс останавливают, если он залочен - его перекидывают из ready в expired.

sync.c пояснять долго, однако в связи с https://github.com/shkolnick-kun/bugurtos/issues/14 У меня вообще подозрение, что его лучше переписать в духе ChibiOS/RT c циклом O(n) вместо того, что сейчас.

shkolnick-kun ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.