• DZ Online Tech: Postgres Professional

      Привет.

      В прошлом году я начал снимать серию передач/интервью на тему цифровой трансформации бизнеса (они тут, кому интересно — подписывайтесь). Эти передачи были на стыке IT и бизнеса, но, всё же, больше про бизнес.

      В процессе стало понятно, что есть немало тем, которые имеют существенную глубину с программерской точки зрения. И в этом году мы начали снимать серию интервью под общим лейблом «DZ Online Tech» — теперь уже с упором на то, что под капотом. Ну и поскольку видео всем смотреть лень, конечно, эти интервью расшифровываются, и сегодня я публикую первое — с Иваном Панченко из Postgres Professional.

      Кому интересен оригинал — вот он:


      (Ну и, кстати, я не могу поклясться, что все выпуски будут выходить в расшифровке, так что если понравилось — подписывайтесь на ютубе, туда всё приходит раньше и гарантированно.)

      Для тех, кто любит читать — расшифровка:
      Читать дальше →
    • Колибри для Фантома

        Краткое содержание: разработка модуля совместимости с ОС Колибри внутри модуля совместимости с ОС Юникс внутри ОС Фантомь)

        Внутри ОС Фантом есть маленький простенький Юникс. POSIX подсистема. В принципе необязательная для работы самого Фантома и довольно неполная — Unix Quake под ней собрать удалось, а, например, апач не соберётся почти наверняка. Тем не менее — она есть.

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

        Почему же, тем не менее, любопытно реализовать слой совместимости с этой ОС? Тому несколько причин:

        • Она очень компактна. Забегая вперёд — первую программу для Колибри в Фантоме удалось запустить через четыре часа работы.
        • Этот мини-проект стал драйвером развития некоторых нативных подсистем Фантома,
          в частности — оконной.
        • Главное — всё состояние процесса Колибри, известное ядру, укладывается в небольшую структуру. Многие (почти все!) вызовы — stateless, то есть не опираются о какое-либо знание,
          хранимое в ядре. Это идеальный кандидат на реализацию персистентных (переживающих перезапуск ОС) бинарных (не написанных на байткод-языке) процессов в Фантоме.
        Читать дальше →
        • +27
        • 3,4k
        • 6
      • Фантом: большая сборка мусора

          Эта статья — продолжение, начало здесь. Для тех, кто не кликнул на ссылку, краткая вводная:

          Мы обсуждаем сборку мусора в операционной системе Фантом, то есть в среде виртуальной (байткод-) машины, работающей в персистентной оперативной памяти. Размер персистентной памяти — порядка размера диска, то есть единицы терабайт на сегодня и, потенциально, десятки и сотни терабайт завтра.

          Поскольку речь идёт о виртуальной памяти, то существенная часть объектов в любом случае находится не в оперативной памяти, независимо от того, какой алгоритм и вообще подход мы избрали. То есть — стоимость доступа к объекту велика. Это, в общем случае, дисковая операция.

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

          Принятая мной идея схемы сборки мусора в такой среде выглядит как совокупность двух сборщиков.
          Читать дальше →
        • Драйверы умного или виртуального железа

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

            Для начала введём определение bus master: устройство, способное быть не только ведомым, но и ведущим на шине компьютера. То есть — не только отвечать на транзакции ввода-вывода, инициированные процессором, но и самостоятельно их инициировать — по собственной инициативе «ходить» в память.

            История таких устройств уходит корнями в понятие DMA: ещё во времена прародителя микропроцессоров, микропроцессора 8080 (КР5080ИК80), появилось понимание, что процессор хорошо бы разгрузить от рутинной операции перетаскивания байтиков между устройствами в-в и памятью.
            Читать дальше →
            • +13
            • 10,3k
            • 6
          • UDP/TCP File System, Trivial Remote File System

              Сегодня выходной, так что напишу коротко про мелочи, до которых, как правило, руки не доходят.

              TCP FS



              Есть ещё одна вещь, которой нет в современном Юниксе и которую я хочу иметь в unix box фантома. Она проста как мычание, и почему её никто не сделал — непостижимо:

              #cat /tcp/host/port > local_file
              


              Правда, я хочу использовать иной синтаксис имени файла, URL style — tcp://host:port, но это уже детали. Естественно, наравне с TCP просится UDP, и там вообще проблем нет.

              Заголовок спойлера
              Вообще unix-подсистема Фантома «ест» как традиционные Юниксовые имена, /usr/include/stdio.h, так и URL-и, tcp://ya.ru:80.


              Для TCP есть очевидная проблема — нужен ли нам listen или connect, но её можно решить через указание в имени «файла» определённого суффикса.

              Сказать на эту тему настолько больше нечего, что перейдём без остановки к следующей.

              TRFS — тривиальная дистанционная файловая система.


              Читать дальше →
            • Lazy threads: опциональный параллелизм

                Статья-гипотеза. Описанное нигде не было реализовано, хотя, в принципе, ничто не мешает запилить такое в Фантоме.

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

                Сформулирую проблему, описанную там, как я её понимаю: сетевой драйвер Линукса работает в отдельной нити, которая читает принятые пакеты из устройства и синхронно их обрабатывает. Прогоняет через роутинг, файрволл и, если пакет не нам, отправляет его в исходящий интерфейс.

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

                То есть хотелось бы такого вызова функции, который при необходимости можно конвертировать в старт нити. Но по цене вызова функции, если нить реально не оказалась нужна.

                Мне эта идея пришла когда я рассматривал совершенно фантастические модели для Фантом, включая акторную модель с запуском нити вообще на любой вызов функции/метода. Саму модель я отбросил, а вот идея lazy threads осталась и до сих пор кажется интересной.

                Как это.
                Читать дальше →
              • Анатомия драйвера

                  Опять вернёмся в традиционную область разработки операционных систем (и приложений для микроконтроллеров) — написание драйверов.

                  Я попробую выделить некоторые общие правила и каноны в этой области. Как всегда — на примере Фантома.

                  Драйвер — функциональная компонента ОС, ответственная за отношения с определённым подмножеством аппаратуры компьютера.

                  С лёгкой руки того же Юникса драйвера делятся на блочные и байт-ориентированные. В былые времена классическими примерами были драйвер диска (операции — записать и прочитать сектор диска) и драйвер дисплея (прочитать и записать символ).

                  В современной реальности, конечно, всё сложнее. Драйвер — типичный инстанс-объект класса, и классов этих до фига и больше. В принципе, интерфейс драйверов пытаются как-то ужать в прокрустово ложе модели read/write, но это самообман. У драйвера сетевой карты есть метод «прочитать MAC-адрес карты» (который, конечно, можно реализовать через properties), а у драйвера USB — целая пачка USB-специфичных операций. Ещё веселее у графических драйверов — какой-нибудь bitblt( startx, starty, destx, desty, xsize, ysize, operation ) — обычное дело.

                  Цикл жизни драйвера, в целом, может быть описан так:

                  • Инициализация: драйвер получает ресурсы (но не доступ к своей аппаратуре)
                  • Поиск аппаратуры: драйвер получает от ядра или находит сам свои аппаратные ресурсы
                  • Активация — драйвер начинает работу
                  • Появление/пропадание устройств, если это уместно. См. тот же USB.
                  • Засыпание/просыпание аппаратуры, если это уместно. В контроллерах часто неиспользуемая аппаратура выключается для экономии.
                  • Деактивация драйвера — обслуживание запросов прекращается
                  • Выгрузка драйвера — освобождаются все ресурсы ядра, драйвер не существует.


                  (Вообще я написал в прошлом году черновик открытой спецификации интерфейса драйвера — см. репозиторий и документ.)

                  Мне известны три модели построения драйвера:

                  • Поллинг
                  • Прерывания
                  • Нити (threads)

                  Читать дальше →
                • Персистентная ОС: ничто не блокируется

                    Это — статья-вопрос. У меня нет идеального ответа на то, что здесь будет описано. Какой-то есть, но насколько он удачен — неочевидно.

                    Статья касается одной из концептуальных проблем ОС Фантом, ну или любой другой системы, в которой есть персистентная и «волатильная» составляющие.

                    Для понимания сути проблемы стоит прочесть одну из предыдущих статей — про персистентную оперативную память.

                    Краткая постановка проблемы: В силу того, что прикладная программа в ОС Фантом персистентна (не перезапускается при перезагрузке), а ядро — нет (перезапускается при перезагрузке и может быть изменено между запусками), в такой системе нельзя делать блокирующие системные вызовы. Обычным способом.
                    Читать дальше →
                  • Атрибуты устройств, или ioctl must die

                      В процессе работы над ОС Фантом, которая вообще не Юникс никаким местом, мне, тем не менее, захотелось сделать в нём Unix-compatible подсистему. Не то, чтобы прямо POSIX, но что-то достаточно близкое. Отчасти из любопытства, отчасти для удобства, отчасти как ещё один migration path. (Ну и вообще было интересно, насколько трудно написать простенький Юникс «из головы».) В качестве цели номер 1 была поставлена задача запустить quake 1 for Unix, которая и была достигнута.

                      В процессе, естественно, появились open/close/r/w/ioctl, и появилось ощущение, что последний неприлично, постыдно устарел. В качестве упражнения для размятия мозга я реализовал (в дополнение к обычному ioctl) некоторый альтернативный API, который бы позволил управлять свойствами устройств более гибким и удобным с точки зрения пользователя способом. Этот API, конечно, имеет свои очевидны минусы, и, в целом, эта статья — RFC, aka request For Comments.

                      Итак, API на уровне пользователя:

                      // returns name of property with sequential number nProperty, or error
                      errno_t listproperties( int fd, int nProperty, char *buf, int buflen );
                      
                      errno_t getproperty( int fd, const char *pName, char *buf, int buflen );
                      errno_t setproperty( int fd, const char *pName, const char *pValue );
                      


                      Правила:

                      1. Никаких дефайнов с номерами, только имена.
                      2. Никаких бинарных данных, только строки

                      Читать дальше →
                    • От шедулера к планировщику

                        См. две другие статьи этой группы — Делаем многозадачность и Преемптивность: как отнять процессор.

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

                        Итак, в прошлых статьях описан механизм реализации многозадачности за вычетом планировщика, он же шедулер, он же скедулер, он же Васька меченый, сорри, заговариваюсь я с этими терминами…

                        Как я уже говорил, шедулер — это просто функция, которая отвечает на вопрос: какую нить и на сколько времени поставить на процессор.

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

                        Говоря о шедулере нельзя не сказать о приоритетах.

                        Приоритет — свойство нити (или процесса) влияющее на конкуренцию этой нити с другими нитями за процессор.

                        Приоритет обычно описывается парой <класс приоритета, значение приоритета внутри класса>.
                        Читать дальше →