Pull to refresh
147
0.1
Дмитрий Завалишин @dzavalishin

Архитектор

Send message
Я всего лет 7 назад помогал в исправлении ошибки в коде на языке Кобол. Кобол. Знаете такой? Джермейн, IBM360, середина прошлого века, слышали? Работает! Используют!

Так и Си.

Некоторым не везёт. Некоторые балдеют. Я вот пишу на Си уже тридцать лет, нехреново умею это делать и определённое удовольствие от этого испытываю.

Но не нужно путать неизбежность (хрен куда Линукс с Си спрыгнет, это ясно), собственные сексуальные предпочтения (писать на си — разновидность онанизма) и ЦЕЛЕСООБРАЗНОСТЬ.

Писать на Си в 99% случаев — НЕЦЕЛЕСООБРАЗНО. Потому что 3.14здец как дорого и 3.14здец как ненадёжно. Это я говорю вам как человек, который этим языком занимается 30 (тридцать) лет и как создатель нескольких крупнейших софтверных систем в России, типа Я.Маркета и инфраструктуры портала Яндекса, Юлмарта и ещё с сотни проектов помельче.

И как человек, написавший ОС почти в одно рыло.

Так вот — почти ПОЛОВИНА кода ОС посвящена заморочкам, которые из Си делают что-то жизнеспособное.

Всякие референс каунты (ручной ad hoc garbage collection), очереди, списки, эмуляции виртуальных методов, мемберофы, проверки и затычки.

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

Но это всё — уже история. Как Кобол. Лямбды уверенно вытесняют указатели на функцию.
Надеюсь, Вы знаете, на кой хрен Вы до сих пор с С++. Я вижу только две причины: исторические наслоения и те 10% кода, которые правда надо оптимизировать.
Она написана на GPU, который занимается графикой, и на динамическом языке, на котором пишут AI. Си там — тонкая прослойка между ними, которая написана на Си только в силу стереотипности мышления разрабов. Технически в этом давно нет смысла.

Скучно это. Я в 90-х наблюдал истерику разработчиков на ассемблере, которым говорили, что асм умер и всё пишут на си. Потом истерику сишников с переходом на яву. Сегодня истерика явистов с переходом на ФП языки.

(И да, если вы ещё истерите по поводу фразы «си умер в пользу явы», вы проспали поколение — уже пора рассказывать, что ява — это легаси.)
ls /proc

это, в общем, тот же путь, да.
в принципе, да — но, всё же, смысл существования ОС — в виртуализации железа. смысл opengl — обобщить и унифицировать интерфейсы и capabilities железа. обойти его — и ОС превращается в толстый и дорогой MS DOS.
Это тоже правда, но в этом смысле весь позикс — одна сплошная дыра. Впрочем, не давайте fd другому потоку, и всё. Ну или мьютекс возьмите — многопоточное программирование предполагает управление параллельным доступом через примитивы синхронизации, так или иначе.
Верно. Но есть более полезный (и более простой организационно) заход для этого упражнения. Напишу позже.
Кстати, разумный механизм — это через ioctl только переключать стейт, а ввод-вывод всё равно делать через read/write.

set_property( fd, "iomode", "palette" ); 
write( fd, &palette, sizeof(palette) );
Это правда.

Но посмотрите на жизнь с другой стороны.

Языка Си больше нет.

Вся современная разработка — переносимые языки с динамическим рантаймом, и никаких дефайнов там нет. Они всё равно мепятся в ioctl через ж. автогеном, и всё равно в рантайме.
Это же универсальный интерфейс для выполнения драйвером обслуживающим файл произвольных действий с передачей произвольных данных.


Увы, да. Можно и это поддержать, сделав какой-нибудь ioread( fd, ioctl_id, void *, size_t ), но, кажется, перебор.
он же на fd меппится. что open позволяет открыть, то и предмет. захочет драйвер дать открыть не устройство, а себя вообще — будут проперти драйвера.
Я этим делом тридцать лет занимаюсь. Вы уверены, что именно моя терминология — новояз? :)

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

Он Вам просто не нравится. А мне просто не нравится (омонимичный) термин «поток», который куда более io stream, чем thread. И то, что большинство людей называют копир ксероксом не делает этот «термин» более верным.

Это разговор о вкусах. И, ещё раз повторю — в нём был бы хоть какой смысл, если бы термин «нить» был бы хоть на полграна омонимичен.

Забейте. Единственное важное свойство буквенного лейбла, приклеенного к точке в семантическом пространстве — понятность. Если его поняли — всё хорошо.
Угу. А ещё есть люди, которые на кондиционере ставят -16, чтобы посильнее холодило. :) Того же поля ягоды. :)
Есть разные модели хард риалтайма, и описание этих моделей в мои задачи на данном этапе не входило. Про выделение жёстких таймслотов я упомянул, а вот уже реакция на отказ — вопрос отдельный. Если у нас есть резервирование, и нить переиспользовала процессор, и мы считаем это проблемой, можно переключиться на горячий резерв. Но, вообще, это очень сложная тема. В анналах истории есть описание ситуации, в которой софт от старой ракеты перенесли на новую, новая полетела быстрее ожидаемого, в расчёте координат делитель оказался равным нулю и процессор упал в фолт. Система переключилась на резервный и он… тоже упрал в фолт — программа и данные-то те же самые. :)
Да деление на юзер и кернел тоже не очень принципиально. Очевидно, что если в realtime нити случился вечный цикл — система умерла. Где бы это ни было. Оживить можно, но это требует дополнительных механизмов, которые логически неочевидны и это отдельный разговор.
1. Такой класс никуда не исчез.

2. «Даемон триды» — это тоже нити, у них тоже есть приоритет. Иногда именно такой. А ещё есть нити драйверов. И т.п.

3. Я описываю механизм, а не его применение. Конкретная ОС может запретить нитям пользователя иметь приоритеты выше некоторого предела, чтобы гарантировать себя от зависания по вине ошибочной программы пользователя. Или выставить пределы на фактическую загрузку процессора.

4. Все озвученные вопросы не имеют вообще никакого отношения к защищённому режиму процессоров Интел и вообще к процессору Интел. Они совершенно не зависят от процессора и всё вышесказанное специалистам по разработке ОС к моменту рождения компании Интел было более-менее известно.

Вы правы — алгоритм назначения нити на процессор в SMP системах учитывает, на каком процессоре нить работала в предыдущем слоте, и предпочитает его.

Но это исключительно оптимизация. Если её не сделать, шедулер всё равно будет работать. Фактически, несколько процессоров занимаются назначением нити для себя совершенно самостоятельно и асинхронно.

Сама по себе привязка нити делается довольно просто — при выборе нити осуществляется некоторая сортировка нитей по признаку. Например, по приоритету. В релевантность этой сортировки можно подмешать бонус, если нить до этого исполнялась именно на данном процессоре, таким образом повысив её шансы этот же процессор и занять.
Мне кажется, Вы немного смешиваете разные вещи.

1. Статья описывает реализацию в ядре. user mode в ней не затрагивается почти совсем.

2. Если вызов функции (yield — функция) портит стек, то компилятор надобно починить или заменить на исправный. Если стек портит реализация — её не надо было писать с ошибками. Если Вы её вызвали, а SP смотрит не на стек — ну, наверное, Вы погорячились.

3. Как Вы совершенно справедливо заметили (ну и, если Вы внимательно читали, у меня это написано сразу после примера кода «cpu_tss[ncpu].esp0 = (addr_t)t->kstack_top;») — Интеловские, да и все иные процессоры переключают стек при переходе из режима пользователя в режим ядра. Вызов функции yield и фактическое переключение контекста происходит именно в режиме ядра. Эта мера действительно позволяет программисту в юзермоде вытворять со стекпойнтером всякую фигню. Но к теме статьи это не относится.

4. Ну и, насколько я помню, нигде в моей статье не написано, что «вытесняющая многозадачность эквивалентна вызову yield()». Она эквивалентна таймерному прерыванию+вызов yield().

В снапшоте нет сканирования памяти. (Все изменения фиксируются подсистемой виртуальной памяти процессора). Но делать уничтожение объектов, у которых refcount == 0 — можно, потому что в снапшоте все виртуальные машины точно на границе инструкции.
Вы же поняли, о чём речь? Ну и слава богу. Я, право, совсем не люблю споры о терминологии. Смысла нет. Если вы считаете, что другой термин лучше — назовите его в комментариях. Читатели увидят и обрадуются.

Information

Rating
3,580-th
Location
Москва, Москва и Московская обл., Россия
Works in
Date of birth
Registered
Activity