commit -m "better"
3.24K subscribers
1.03K photos
149 videos
3 files
2.39K links
just random thoughts
Download Telegram
https://github.com/microsoft/msquic

Портабельная реализация QUIC, от MS.

Альтернативная реализация от Google обладает каким-то странным свойством, что для ее работоспособности надо написать 100К привязок к платформе. In the wild оно есть только в Chromium, с привязкой к его кодовой базе. И, по слухам, в envoy, но про там я ничего не знаю.

UPD: вспомнил, еще есть quiche от Cloudflare, на Rust. Бардачная ситуация, потому что разобраться где quiche от Google, а где от cloudflare, решительно невозможно.

Признаться, я в восторге!
🔥6
Новости одной строкой: #mrustc https://github.com/thepowersgang/mrustc умеет в rust 1.54.0.

Надо бы им попробовать собрать не rustc, а что-то полезное. В отличие от mainstream rustc, оно умеет в процедурные макросы без загрузки .so в адресное пространство rustc.
👍2
https://xanmod.org/ - скажите, а кто-нибудь пробовал? Какие результаты?
Ну и, пользуясь случаем - кого бы мне подергать про ручки шедулера Linux? Хочу понять, как уменьшить цену миграции процесса с одного ядра на другое.
Пробую собирать #mrustc, https://github.com/thepowersgang/mrustc

Автор этого проекта, очевидно, разбирается в компиляторах, но совершенно не разбирается в системах сборки.

Его система сборки - это 4 Makefile, котрые рекурсивно вызывают друг друга, модифицируя аргументы и переменные среды.

https://github.com/thepowersgang/mrustc/blob/master/build-1.54.0.sh - главный драйвер сборки, вызывает make 7 раз, с разными Makefile, и аргументами(и каждый из этих вызовов еще рекурсивно дергает make!)

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

Пока получилось:

* собрать компилятор
* собрать minicargo
* с их помощью собрать cargo(1) из mainstream исходников

Дальше цепочка bootstrap предполагает:

* mrustc + minicargo -> rustc(1)
* minicargo + rustc(1) -> std(2)
* std(2) + cargo(1) + rustc(1) -> rustc(2), cargo(2)

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

То есть, получить rustc(1), cargo(1) я могу, а вот дальше с ними сделать ничего не выйдет.

Я, как и собирался, попробовал собрать какой-нить сторонний софт с помощью mrustc + minicargo, но, увы, пока он заточен только на сборку самого rust.

Что я могу заметить по процессу?

Разработчики rust, конечно, пионеры, с завышенным ЧСВ. Иначе я никак не могу объяснить вот это вот говно - https://github.com/rust-lang/libc/tree/master/src/unix/linux_like/linux

Поштырьте по исходникам, и оцените, как изящно эти долбоебы обертывают libc. Фактически, они хардкодят оффсеты и размеры структур.

Нормальный человек нагенерил бы кучу setter/getter для структур, типа:

int struct_stat_get_inode(struct stat* s) {
return s->st_ino;
}

И скомпилял бы это С-компилятором, чтобы вообще не думать о layout этого С-шного хлама.

Но это же не по пацански, и вообще, у нас комплексы лапки, и нужно сделать вид, что C тут и рядом не стояло, поэтому мы построим все на Rust: https://github.com/rust-lang/libc/blob/master/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs#L10 Копипаста под все платформы и возможность разъехаться - не, не слышали.

А потом нормальный человек будет искать, где у него проезд по памяти, потому что код собрался под glibc вариант, а используется musl.

True story, я искал, в качестве фикса mrustc у меня принудительно собирает под musl, потому что куда это в нем передать, я не нашел.https://git.sr.ht/~pg/mix/tree/main/item/pkgs/bin/mrustc/mix.sh#L41

Ну и вендоринг C/C++ исходников(openssl, git2, curl, etc) - я про это уже писал, и повторю еще раз. Код эти пионеры вендорят, данные - нет. Потому что вендорить корневые сертификаты - это сложна, одной системой сборки не обойтись. Поэтому, конечно, найти в системе корневые сертификаты свежеиспеченный cargo не умеет.
👍6🤔2
#bs #vendor #gold

Почему дистрибутивы не любят контрибы:

* Когда у тебя в сборке принимают участие несколько разных версий одной и той же библиотеки, патчить приходится все версии

* В случае использования конвенциональных дистрибутивов(dynamic linking + LSB FHS, в противовес nix/guix/mix/static linking) это еще и технически сложно - динамеческая либа и ее данные хотят жить по одному и тому же файловому пути, для разных версий этой либы.

* Например, нужно, чтобы freetype/fontconfig/harfbuzz/ca-certs у всех пакетов были общие. Потому что кто, в своем уме, хочет разный рендеринг шрифтов в разных приложениях? Это частный случай первого пункта, но хочу подчеркнуть его отдельно.

Для меня, как яркого представителя content-based addressing distro(пути - это https://en.wikipedia.org/wiki/Merkle_tree), и дистрибутива со статической линковкой, часть этих проблем - не проблемы вовсе.

Поэтому я не всегда занимаюсь де-вендорингом(если вы понимаете, о чем я), но иногда приходится:

* freetype/etc case

* Конфликт по ромбовидным зависимостям того, что лежит в vendor у пакета, и того, что нужно мне. Ну, грубо говоря, я приношу свой curl вместо vendor curl, а мой curl зависит еще и от brotli, которая тоже лежит в vendor у проекта. И хотя на эту brotli мне глубоко пофиг, ее тоже приходится выкорчевывать.

* Так называемый "всратый" vendoring. Что это такое? Это очень разнообразный класс ситуаций, когда мейнтейнер пакета сошел с ума, и приходится его готовить, и приходится за ним подчищать. Например: кто-то сделал у себя в проектах submodules, но не делает git clone --recursive в момент изготовления пакета. В такой ситуации у тебя в пакете пустые папки вместо submodules, и делай с ними, чо хош. Странно? И не такое бывает.

Де-вендорингом можно заниматься по разному.

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

* Ковровые бомбометания. Например, в meson все такие штуки описываются с помощью wrap файлов, и достаточно их просто удалить. https://git.sr.ht/~pg/mix/tree/main/item/pkgs/mix/meson.sh#L87 NB: рассказать, как я злодейски поступаю с разными системами сборки, не церемонясь ни с их авторами, ни с разработчиками пакетов.

Вот, вчера так поступил с Rust.

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

Поэтому я поступил по рабоче-крестьянски, и просто обнулил сборочные файлы неугодных мне таргетов, благо, их названия вполне вписываются в регулярку: https://git.sr.ht/~pg/mix/tree/main/item/pkgs/bin/mrustc/cargo/unwrap/mix.sh#L14 Кстати, вполне возможно, что это таки моя первая строчка кода на Rust! (которую я реально скомпилировал и запустил)

Короче, если там какие-то сумасшедние авторы пакетов и систем сборок думают, что я буду разбираться с тем, как они предоставили ту или иную фичу(де-вендоринг, сборка с разными флагами компилятора, санитайзеры, static/dynamic linking, etc) - да щаз.

"Мы не можем ждать милостей от природы, взять их у нее – наша задача"
👍8🔥3
https://www.qt.io/blog/qt-6.3-released

Вышла новая версия QT. #ball_lick

Когда программисту нечего делать - он начинает вылизывать себе яйца код. В целом, задача построения gui библиотек уже завершена, поэтому теперь их авторы соревнуются в том, кто сделает побольше QtPDF, css/html/qml врапперов, чтобы даже макака могла строить GUI, и так далее.

Code bloat, который я ненавижу.

А хорошей gui библиотеки:

* VK/GL в качестве канвы, без прослоек.

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

* Большой набор виджетов из коробки, и чтобы он не выглядел так, как будто ты пишешь игру.

* IM/RM - хз, мне кажется, круто иметь один и тот же набор виджетов под обе парадигмы.

как не было, так и нет. Наверное, ближе всего к этому ImGUI?

Еще нужно сказать, что гномовцы, конечно, правы, и GTK - это таки платформенный Linux toolkit, и все из-за дурацкой политики QT.

Я тут пытался скачать исходники без смс и регистрации - пока не получилось. 10 страниц, которые навязчиво предлагают купить коммерческую версию, с какой-то невнятной ссылкой на OSS версию, но ведет оно снова на страницу, объясняющую, что OSS версия мне не нужна.

Ну как так?

И это очень печально, потому что, чем больше я погружаюсь в Linux графику, тем более невменяемыми мне кажутся гномовцы.

https://www.reddit.com/r/wayland/comments/r8t7pe/where_are_we_at_for_working_autotype_protocols/

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

Все, абсолютно все, согласны, что это должен быть протокол в Wayland. И только упоротые гномовцы считают, что нет, и изобретают очередной костыль по типу libdecor #GNOME, который там что-то должен делать через dbus и загрузку плагинов.

https://gitlab.freedesktop.org/libinput/libei

Вот их всратое изобретение.

https://gitlab.freedesktop.org/libinput/libei#why-not-foo

"The only connection to Wayland is merely that input events are received
through the Wayland protocol. So a Wayland protocol for emulating input is
not a great fit, it merely ticks the convenient box of "we already have IPC
through the wayland protocol, why not just do it there"."

Уровень аргументации - бог.

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

Посмотрите, какие шедевральные архитектурные картинки они там рисуют.
👍3🔥3
Я тут решил, из интереса, завести #http3 хоть где-нибудь, раз уж в моих руках оказалась msquic. https://github.com/microsoft/msquic

Что я имею вам сказать, дорогие радиослушатели?

* Что msquic, что связка ngtcp2 + nghttp3, что chromium quic, используют патченый openssl. https://github.com/quictls/openssl. Причем обе стороны, что вендоры, что openssl - дико извиняются, что ну вот никак-никак не смержат все это дело, а openssl еще и намекает, что, может, они и сами наговнякают реализацию quic. https://www.openssl.org/blog/blog/2020/02/17/QUIC-and-OpenSSL/

"We believe that the inclusion of QUIC support in OpenSSL is extremely important and there is an intention to provide it in a future version of OpenSSL. This may be in the form of an API to enable TLS integration into 3rd party QUIC products, or it may be in the form of a complete QUIC transport protocol implementation."

Я решил еще +1 openssl не класть, и заменил общий на патченый, благо, вендоры обещают не затягивать с обновлениями. Патч там, если убрать мусор, строк на 500 кода, но выглядит реально всрато.

* ms stack сырой донельзя, поддержка в curl появилась пару дней назад. https://daniel.haxx.se/blog/2022/04/10/msh3-as-the-third-h3-backend/ Причем оно использует какой-то всратый клей между msquic и нормальным миром, msh3 https://github.com/nibanks/msh3, которая, в свою очередь, полагается на приватные запчасти от msquic - https://github.com/nibanks/msh3/blob/main/lib/msh3.hpp#L43. Короче, обычному пользователю проще умереть, чем это попробовать.

* Но я попробовал, и имею вам сказать!

Как вы понимаете, я не стал ходить nghttp3 в nghttp3, и msquic в msquic, потому что зачем, а стал ходить ровно наоборот:

nghttp3 -> msquic:

pg-> /mix/store/KKTWnNVKMRCbB5Lq-bin-curl/bin/curl 
--http3 https://quic.westus.cloudapp.azure.com
curl: (56) Failed to connect to
quic.westus.cloudapp.azure.com
port 443 after 5446 ms: Failure when receiving
data from the peer

msquic -> nghttp3:

pg-> /mix/store/BHNhnDCyQ4HIZUFO-bin
-curl-bleed/bin/curl
--http3 https://nghttp2.org:4433/
Connection shutdown by transport, 0xbebc300
curl: (7) failed to connect, state=1

В свои родные сервера оно ходит норм, я, конечно, проверил.

Выводы? HTTP3 пока нет, по крайней мере, в том виде, чтобы все были согласны, что это оно.
🔥11😁4💩4👍2
#mold раньше всех - https://github.com/rui314/mold/releases/tag/v1.2, вышла новая версия супер-быстрого линкера. Попробую на выходных, подходит ли он на то, чтобы слинковать всю систему.

———
https://www.vedomosti.ru/technology/articles/2022/04/13/918008-times-new-roman-zablokirovali

Звучит как плохая первоапрельская шутка. Really, я на дату на часах посмотрел, когда прочел эту новость.

———
В поисках нормальной библиотеки виджетов.

Думал, нашел подходящий вариант - https://lvgl.io/

Компактная, без изъебов, есть все, что надо.

Но, как обычно, меня подвела привычка смотреть внутрь того, что я использую: https://github.com/lvgl/lv_drivers/blob/master/sdl/sdl_gpu.c#L79 Поддержка 2 мониторов, my ass.

Вот так вот, просто, без изысков(ну там типа "вектора мониторов"). 2 - это таки 2.

———
https://go.dev/blog/when-generics

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

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

Так, лет за 10, и нормальную обработку ошибок добавят, когда позавчерашние школьники устанут хуячить по клавиатуре со скоростью 300 символов в минуту, и начнут понимать, что продуктивность - это не число строк в секунду.

Каждый язык, видимо, взрослеет(и умирает) вместе со своей аудиторией.
🔥3
#mix digest

* Число пакетов:

pg-> find . | grep mix.sh | wc -l
1097

Надо понимать, что тут содержатся и всякие пакеты для bootstrap, которые пользователю никак не нужны и не интересны. Полезных пакетов около 700. Напомню, что база Arch Linux - 2700 пакетов.

* Постепенно полирую и доделываю всякое. Например, чтобы было понятно:

- до недавнего времени у меня и на пользователя, и на root, были пустые пароли. Ну просто потому что привсунуть их через useradd - не вариант, у нас же "чистое" управление системой, и это нужно было прокинуть через настройки #realm до конкретных пакетов. Выглядит это у меня вот так:

{
"flags": {
"failsafe": "1"
},
"name": "set/system/0"
},
{
"flags": {
"hash": "uz.......c",
"pubkey": "ssh-rsa AAAh...j2M= pg@mix",
"user": "pg"
},
"name": "etc/user/0"
},
{
"flags": {},
"name": "etc/zram/0"
}

пользователям nix/guix подобная схема может показаться знакомой, а остальные могут пофантазировать, как эти flags могут превращаться в конкретные записи в /etc/passwd, в /etc/authorized_keys, etc

Собственно, все, что я указал выше - это единственный state системы, все остальное выводится из него и из пакетной базы.

- Сегодня у меня был день date time. До этого я жил в UTC, выставленным руками. Сейчас я наладил синхронизацию времени через ntp, save/restore времени при reboot, и собрал пакет с таймзонами для musl. Все это несложно, но довольно муторно, и приходится вспоминать вещи, которые никому не нужны и не интересны.

* Фактически, из нерешенных задач у меня осталось две:

- bluetooth stack. Разобраться, чего там нахуевертили в Linux, выбрать реализацию, отполировать. https://www.bluez.org/

- Звук. #alsa

Пожалуй, самая серьезная моя проблема. Я уже выбрал и собрал 2 звуковых сервера на выбор(https://jackaudio.org/, https://sndio.org/). Мне лично симпатичнее всего #sndiod, маленькая, компактная запчасть из openbsd.

Проблема в том, что звука-то я пока ни разу и не услышал, хотя совершенно точно уверен, что до ядра данные идут. А как в этом месте отладить alsa - у меня пока затык. Дрова видны, они подцепляют устройство, микшер их видит, данные текут в канал. Звука нет, в dmsg пусто :( Если загрузиться в Fedora Live CD, звук есть. Дрова подцепляются все те же самые, микшер видит все те же самые устройства.

fun fact - я в какой-то момент времени офигел, узнав, что у меня 2 аудиокрты, и одна из них интегрирована в AMD GPU. Прежде чем я понял, что это такое представление для системы hdmi audio output, я был "слегка" озадачен.
👍6
Божечки-божечки-божечки, НАЧАЛОСЬ! #linux_kernel_rust

https://lwn.net/ml/rust-for-linux/CAHkG_ewRo5uPOue3ZMAAPAc+eP7MNNU5iVym-JVG1jN7HD+XMg@mail.gmail.com/
https://lwn.net/ml/rust-for-linux/CAKfU0DLS5icaFn0Mve6+y9Tn1vL+eLKqfquvXbX4oCpYH+VapQ@mail.gmail.com/

Какие-то школьники интересуются, когда можно будет использовать crates.io и cargo в разработке Linux. С патчами про Rust все было и так понятно, но надо же иметь хоть немного совести, и подождать, пока поддержка Rust попадет в mainline.

Парсера json им не хватает в ведре, да.

———
https://github.com/microsoft/mimalloc/issues/574

Нашел багу в свежем mimalloc. Как? Очень просто, пересобрал с ним мир, и увидел в логах красивое:

pg-> /mix/store/mAZUHwYPOIGAPJOH-bin
-coreutils-9-0/bin/sort
sort: memory exhausted

gnu sort начал так ругаться на пустом вводе.

Стандартов на эту функцию нет, кто формально виноват, непонятно, но есть мнение, что reallocarray(a, n, m) == realloc(a, n * m) для всех n, m, которые можно безопасно перемножить.

Код sort в этом месте тоже совершенно всратый, зачем там выделять память уже после того, как весь ввод обработан - непонятно.

———
https://github.com/WebPlatformForEmbedded/libwpe/commit/064bd78c534d18f9422ddbfe4ca762a42290531c

#igalia lia никак не уймется, и они запилили для WebKit еще один порт, для embedded. Он устроен хитро - есть loader, libwpe, который загружает конкретную имплементацию, которая уже и реализует настройку графического контекста для рендеринга. И есть конкретная референсная реализация для freedesktop проектов, wpe-fdo.

Сделано это всрато:

* loader зависит от libxkbcommon, то есть, наружу протекла абстракция ввода-вывода(от конкретной реализации)

* абстракция, насколько я понял, абстрагирует не только графику, но и звук. Через что они гоняют звук, я пока не понял, как бы не через wayland :D

На днях коллеги из Igalia решили, что, раз уж есть всего одна реализация плагина, то можно ее и не через dlopen открывать. Кстати, придумали элегантное(без шуток) решение - статический loader просто содержит в себе extern на символ из плагина, после чего с ним можно линковаться, как с обычной .so

https://github.com/WebPlatformForEmbedded/libwpe/blob/master/src/loader-static.c#L32

А теперь то же самое, в конкретном плагине:

https://github.com/Igalia/WPEBackend-fdo/blob/master/src/fdo.cpp#L33

Мне понадобился gdb, чтобы найти тут ошибку.

Очевидно, что этот статический loader никто никогда в реальной жизни даже не запускал. Я этим пидарасам так и написал - https://github.com/WebPlatformForEmbedded/libwpe/commit/064bd78c534d18f9422ddbfe4ca762a42290531c#r71375192

Вот моя реализация: https://git.sr.ht/~pg/mix/tree/main/item/pkgs/lib/wpe/loader/loader.c
🔥11👍3😁2
веселых картинок в ленту
👍12🥰4👏1😁1😢1
#musl

https://lobste.rs/s/osfunr/musl_preprocessor_debate
https://catfox.life/2022/04/16/the-musl-preprocessor-debate/
https://www.openwall.com/lists/musl/2013/03/29/13

Я уже как-то писал про сумасшедших авторов Musl, которые никак не хотят запилить
#define __MUSL__

Как ни странно, я немного поменял свое мнение, хотя и мои новые аргументы не подкрепляют точку зрения Ричарда Фелкера.

Мои аргументы:

* мало кто использует musl с аллокатором из musl, потому что аллокатор из musl сосет.

* стандарты на аллокатор - очень размытое понятие, потому что они менялись со временем, и некоторые функции тупо не стандартизированы(reallocarray, о которой я писал в прошлом посте).

* mimalloc(который я использую вместе с musl) недавно поменял свое поведение(оба поведения имеют право на существование) - конкретно, malloc(0) возвращал уникальный указатель, а теперь может возвращать nullptr.

* исходя из всего этого, потребители не могут пользоваться
__MUSL__
, для того, чтобы проверить свойство аллокатора - нужен configure-time тест.

Дело, конечно, усложняется кросс-компиляцией, и невозможностью получить нужную информацию через configure-time test, но что тут поделать.

Отдельно отмечу, от смены версии mimalloc сломалось прямо очень много configure-time тестов, и я предлагаю из этого сделать такие выводы:

- #semver не работает. Только тесты, только хардкор.

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

Кажется, совсем иделаьное решение - подставлять все нужные флажки в configure/cmake/meson/etc в системе построения пакетов, но, кажется, это утопично.

Конечным потребителям musl вполне можно продолжать иметь свой
#define __MUSL__
, потому что для них он продолжает нести вполне понятную семантику.
🔥2👍1
https://www.opennet.ru/opennews/art.shtml?num=57032 #cve

"Как и в случае с первой уязвимостью исправление проблемы вызывает недоумение - устранение проблемы сводится к тому, что для чтения файла конфигурации теперь запускается внешняя утилита "cat" ('Command::new("/bin/cat").arg(path).output()')."

"I am an 18 year old open-source developer and Linux enthusiast from the Philippines." #школота

(я тут немного манипулирую читателем, потому что это возраст автора фикса, а не автора исходного варианта, который я просто не знаю)

Хочу поспекулировать вот на какую тему.

Развитие программиста - долгий, многогранный, процесс. Человек одновременно учится инструментам, API, взаимодействию с товарищами.

Поэтому, раньше, когда человек наУчивался писать на С/С++ без проездов и багов, он уже начинал что-то понимать в Unix, в каких-то своих предметных областях, и так далее.

Rust же позволяет писать человеку memory safe код, и, на первый взгляд, кажется, что все ОК, а на самом деле школьник там 10 CVE допустил. А если бы писал на С/C++, то у вас программа бы просто упала на старте, и до дела бы дело не дошло.

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

Я искал себе login manager, чтобы не всратый, и lightweight, пока не нашел.

Зато могу привести пример "гармоничного" развития программиста - вот человек ищет себе свободный X display - https://github.com/fairyglade/ly/blob/master/src/login.c#L25. Ну так у него и код(этого демона в общем) течет и падает, никто в здравом уме пользоваться не будет.

Короче, возрастной ценз в президенты - не зря, ох, не зря.

———
Парочка "прикольных" предупреждения от сборки с clang, волосы на жопе шевелятся:

common.c:125:29: warning: 
format specifies type 'char *'
but the argument has type 'int'
[-Wformat]

fprintf(stream, _("%s."),
strerror_r(error, buf, DESCR_BUFSZ));

xfs_copy.c:264:21: warning:
comparison between pointer and integer
('pthread_t' (aka 'struct __pthread *')
and 'pid_t' (aka 'int'))
[-Wpointer-integer-compare]

if (target[i].pid == pid) {
🔥8👍3😁2
https://www.phoronix.com/scan.php?page=article&item=apple-m1-compilers&num=1

После запуска Linux на M1 стало возможным проверить codegen от gcc для Apple M1. Под darwin оно уже давно сломано от слова совсем.

Я, если честно, сильно удивлен результату, gcc, в среднем, генерит все еще более лучший код для aarch64, несмотря на то, что clang - родной компилятор для M1.

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

———
Много ссылок про Wayland, без особого порядка и смысла, просто накопилось, хочу сбросить dump, чтобы перестать про них помнить.

https://www.reddit.com/r/linux/comments/u3m7s0/chromium_is_developing_support_for_using_qt_on/i4rg0jr/

Интересная ветка дискуссии про поддержку QT в Chrome, перетекло на дефекты Wayland, и на то, как сумасшедшие разработчики, захватившие власть в Wayland, не дают нормально работать людям.

Например, https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/132. Ну простая же задача, сделать поддержку картинки-в-картинке? Это такое оверлейное окно поверх всего остального.

"There's a merge request for adding PIP support to wayland-protocols, but as a surprise to absolutely nobody, it's stalled because some upstream developer thinks it shouldn't be done like specified, because it goes against the wayland philosophy. So, that's going to take optimistically 3 more years, for a really minor feature, to be officially supported with Wayland."

Ну так эти капризные мудаки, которым непонятно кто дал этот жалкий кусочек власти, начинают обсуждать космические корабли, бороздящие просторы Большого театра - "а можно input туда, или нет", "а может, разрешить туда только видеопоток", etc.

Кстати, fun fact - 50gb chrome source vs kernel 1gb source. Никогда не задумывались, насколько chrome огромен?

https://gitlab.freedesktop.org/mesa/mesa/-/issues/6249 - интересное обсуждение в Mesa отличие построенного пайплайна в RADV(4 буфера в swapchain vs. 2 буфера в #AMDVLK).

https://www.opennet.ru/opennews/art.shtml?num=57038 - SDL отменяет "wayland по умолчанию". Одна из причин - #libdecor не всегда корректно подхватывает плагины для отрисовки декораций. Про леденящий пиздец под названием libdecor я уже однажды рассказывал, поэтому, думаю, мое злорадство тут вполне понятно и уместно. У меня, конечно, в силу статической линковки все всегда работает как надо.

Про libdecor еще добавлю:

* Как бы нормальный разработчик сделал fallback в случае отсутствия необходимого плагина? Ну, понятно, был бы или плагин, который всегда устанавливается в систему, или плагин, который принудительно линкуется в основное приложение.

Чувак сделал и то, и то - ему, наверное, за строки кода деньги платят.

https://gitlab.gnome.org/jadahl/libdecor/-/blob/master/src/libdecor-fallback.c - линкуется принудительно
https://gitlab.gnome.org/jadahl/libdecor/-/blob/master/src/plugins/dummy/libdecor-dummy.c - ставится по умолчанию всегда

Но и это еще не все! В поставку входит еще 1 плагин, который тоже ставится всегда, и делает что-то полезное!

https://gitlab.gnome.org/jadahl/libdecor/-/blob/master/src/plugins/cairo/libdecor-cairo.c

То есть, вместо того, чтобы просто по умолчанию всегда линковать эту реализацию с cairo, чувак 3 раза сделал одно и то же. Пиздец.

Ну и могу рассказать, как я элегантно из всего этого соорудил библиотеку с вкомпиленным внутрь плагином:

* В первый раз собираем libdecor, оставляем от нее только плагин, и в нем переименовываем и делаем global символ, который libdecor будет звать в виде fallback https://git.sr.ht/~pg/mix/tree/main/item/pkgs/lib/decor/cairo/mix.sh#L16 , https://gitlab.gnome.org/jadahl/libdecor/-/blob/master/src/libdecor.c#L1657

* Во второй раз собираем libdecor, но обнуляем в ней символ libdecor_fallback_plugin_new, чтобы он взялся из плагина от первой сборки. https://git.sr.ht/~pg/mix/tree/main/item/pkgs/lib/decor/mix.sh#L9
🔥3
Я уже несколько раз писал про то, что считаю, что на #semver полагаться нельзя.

И, будучи последовательным сумасшедшим, я исповедую следующую практику версионирования:

* стабильные снепшоты кода нужно помечать автоинкрементным счетчиком.

Я лично предпочитаю v1, v2, etc.

Так же имеет право на существование схема vyyyymmdd, и подобные. Они несколько удобнее для ориентации от версии к версии. #calver

Для багфикс релизов можно делать что-то типа vN.M, где М может быть чем угодно. Я нумерую любимыми сериями из Футурамы. На самом деле, я бы тут мог написать все, что угодно, потому что багов не сажаю, и багфикс релизы не завожу.

В связи с этой нумерацией могу вспомнить очень давнюю историю, как я чуть было не подрался с начальником качества всего поиска, потому что забраковал отведенную(вроде шестую?) версию, и, ничтоже сумняшеся, завел N + 1, а он не хотел дырок в нумерации.

———
Вторая холиварная тема на сегодня - source based distro.

У меня есть две противоположные точки зрения на эту тему.

1) source based distro победят.

* Вычислительная мощность растет все еще экспоненциально. Сложность программ хер его знает, как растет, но, органолептически, как-то немножко медленнее. Давайте я поспекулирую, и скажу, что как квадрат. 30 лет назад на сборку gcc можно было потратить 2 суток. 15 лет назад это занимало час, а сейчас - 5 минут. Через 10 лет это будет еще относительно быстрее.

* Мы проверям md5 перед запуском бинарников из интернетов

* Самый лучший способ провалидировать, что бинарник собран правильным образом - это собрать его из исходников

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

2) сохранится status quo

* На самом деле, всем похер, и никто не заморочен на том, чтобы не запустить какую-нить хрень.
😁8👏2
Закончил эпопею с телегой.

"Закончил" - значит, наконец-то, собрал telegram desktop. До этого я сначала пользовался:

* Веб версией. Там есть две версии - K https://web.telegram.org/k, и Z(совпадение?) https://web.telegram.org/z. Пишут, что это две соревнующиеся команды. Дурову за это респект, если на конечную задачу бесконечно много денег, очень хороший способ. https://www.reddit.com/r/Telegram/comments/mzicwm/what_is_the_difference_between_webktelegramorg/

* Потом я обернул web версию в webview.

webview я взял на основе webkitgtk. https://github.com/webview/webview Автор какой-то упырь, принципиально не прикручивает систему сборки, типа, "один файл, чо вам еще надо". При использовании этого webview столкнулся со странным - если загрузить сайт в webview, то у него некорректно работают размеры контролов и прочего гуи. С проблемой столкнулся не только я - https://github.com/luakit/luakit/issues/279, люди рекомендуют руками выставить zoom.

Мне было понятно, что это workaround для какого-то бага, я решил разобраться.

TL;DR - передаю привет любителям int, sentinel == -1, и, как результат, DPI в -1/1024.0

https://github.com/WebKit/WebKit/blob/main/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp#L115

int - зло, sentinel - убивал бы за такое, в том числе, за ZTS.

https://git.sr.ht/~pg/mix/tree/main/item/pkgs/bin/webview/unwrap/mix.sh#L25 - починил, соорудил себе бинарь webview, гонял телегу в нем.

Все же, как бы ни был хорош JS telegram, хотелось нативочки.

* Сегодня дособирал себе настоящую телегу.

Что хотел бы сказать по этому поводу?

* Не понимаю, чего там дистрибутивы жалуются на разрабов телеги, они делают все, что в их ограниченных силах для де-вендоринга. Даже страницу с инструкциями накидали - https://github.com/telegramdesktop/tdesktop/wiki/The-Packaged-Building-Mode

* Пишут телегу олимпиадники. Код норм, не рыхлый, читать приятно. Слишком сильно увлекаются последними стандартами. Поэтому clang у меня этот код отказался компилировать, а gcc падал на некоторых файлах:

ceFiles/main/session/send_as_peers.cpp.o.d 
-o Telegram/CMakeFiles/Telegram.dir/
SourceFiles/main/session/
send_as_peers.cpp.o
-c /mix/build/coPWMHWqHpBGFNTA/src/
Telegram/SourceFiles/main/session/
send_as_peers.cpp
x86_64-pc-linuxg++: internal compiler error:
Segmentation fault signal
terminated program cc1plus
Please submit a full bug report,
with preprocessed source if appropriate.

(gcc как был всратым говном, так и остался. Компиляет он, по ощущениям, раза в 2 - 3 медленнее, чем clang)

Казалось бы, все пропало?

Но ваш покорный слуга не растерялся, и соорудил cadavercc:

cat << EOF > clang++
#!/bin/sh
/path/to/clang++ "\${@}" || g++ "\${@}"
EOF

cadavercc, на удивление, прожевал кодовую базу, и выдал рабочий результат.

Исходники пришлось подпатчить.

Пришлось очень долго возиться с cmake. Коллеги накостыляли сборку subproject, а cmake не передает в глубину все нужные аргументы, пришлось делать над ним враппер, который бы верно обрабатывал рекурсию. https://git.sr.ht/~pg/mix/tree/main/item/pkgs/bin/telegram/desktop/mix.sh#L83

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

* самая мякотка - полез чинить сборку с clang. https://github.com/telegramdesktop/tdesktop/issues/24385 Как обычно, не сдержался, влез. Как ни странно, полностью на стороне дуровцев - делают все, что могут, в ограниченных условиях, не больше, но и не меньше.
👍17😁6🔥5
#tcmalloc #mimalloc #allocator

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

Я как-то уже писал, что включил себе zswap на несколько гигабайт, ровно по этой же причине - в моменте там есть пара файлов, на которых у меня система упирается в лимит по памяти.

Странно, что оно начало случаться снова.

В барабашек я не верю, полез разбираться.

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

Дуровцы собирают телегу с jmalloc, я собираю весь дистрибутив с mimalloc.

Тут будет небольшое лирическое отступление.

Я фанат mimalloc. Мне он очень нравится идейно, я даже статью прочел. Хорошо знаю его кодовую базу.

Но, если честно, собирать целый дистрибутив на mimalloc - это, во многом, эмоциональное решение.

Потому что в качестве аллокатора по умолчанию я всем рекомендую tcmalloc, из gperftools.

Почему?

* жОпыт. Мой говорит, что tcmalloc - наиболее предсказуемый из всех известных мне аллокаторов. Да, он почти во всех сценариях уступает локальному лидеру, но, зато, никогда не приходит хуже, чем вторым. Предсказуемость - это очень важно.

* Известно довольно много случаев, когда в Я переходили на tcmalloc там, где важны latency spike.

* Я очень верю в hard work :) tcmalloc - это прямо очень hard work, туда вбуханы, не знаю, сотня человеко-лет. За это время инженеры гугла успели идентифицировать и починить кучу corner case, от которых страдают те или иные аллокаторы. Красивой идеей можно обогнать hard work в некоторых случаях, но не в среднем.

Поэтому, если есть время на тесты, я советую взять mimalloc, tcmalloc, и hualloc, и прогнать их на реальной нагрузке, а если нет - то tcmalloc как аллокатор по умолчанию.

Я решил посмотреть, как ведет себя сборка tdesktop с разными аллокаторами.

setup у меня примерно такой - собираю испытуемую программу с нужным аллокатором, запускаю ее, и начинаю серфить. В соседней консоли - top, по нему я в realtime слежу за RSS. CPU и прочее не смотрю, не интересно.

Графиков я не строил, все же, не новую конфигурацию железа для ДЦ выбираю.

Победил tcmalloc:

* В steady режиме процентов на 15 меньше RSS.

* В пиках потребления он лучше конкурентов в 1.5 раза.

Из интересного:

* tcmalloc потрясающе бережно относится к вирутальной памяти - он распределяет где-то 80% от аллоцированного адресного пространства. jemalloc - 50%(это довольно примерные цифры, скачет же все), mimalloc - 15%. В целом, кажется(я пока себя не до конца в этом убедил), это должно в лучшую сторону влиять на спайки, потому что чаще выдаем уже прогретую память.

* jemalloc - какая-то непредсказуемая хрень, то у нее потребление памяти скакануло высоко, то вообще все, досуха, вернули в систему.

* mimalloc, jemalloc примерно одинаково жрут памяти в среднем, и в пиках.

* mimalloc почему-то очень много выделяет адресного пространства.
🔥12👍7
Хорошие измерения - сложно.

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

Мне стало интересно, как это починить для #tcmalloc, и я решил запустить background thread, который бы постепенно возвращал память в систему.

Вот мой код. https://git.sr.ht/~pg/mix/tree/main/item/pkgs/lib/tcmalloc/trim/mix.sh

(тут хочу отдельно отметить, какая у меня крутая система сборки - кодогенерация исходников на С++, с настройками от потребителя через флажки - https://git.sr.ht/~pg/mix/tree/main/item/pkgs/bin/telegram/desktop/unwrap/mix.sh#L38 - тут написано, что мы используем такую библиотеку, которая бы освобождала по 10 мегабайт в секунду. Мне, признаться, даже немного стремно выпускать такую описательную мощь наружу)

Все работало очень хорошо, при выбранных мной параметрах телега возвращалась в steady режим за пару минут, этот режим был лучше того, что показывал jemalloc.

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

Но не тут-то было, и в комментариях мне рассказали, что телега, в случае сборки по феншую, каноничными скриптами, активирует похожий режим, только для jemalloc. https://github.com/desktop-app/cmake_helpers/blob/87d46d81111d9ebfff560e1be3d52306c7475fe7/linux_jemalloc_helper/linux_jemalloc_helper.cpp

Починил, провел новые измерения, и имею сказать:

* В пике RSS у tcmalloc и jemalloc при просмотре этого канала примерно одинаковый - 4 гига.

* После возвращения в steady режим жрут они по 450 - 500 мегабайт, тоже одинаково.

* В steady режим jemalloc возвращается быстрее, но это мой личный выбор, потому что вернуть много памяти сразу - это долго, и может быть заметно в виде latency spike.

* Для mimalloc я такого режима не нашел, для него результатов не будет.

Короче, jemalloc для телеги тоже норм, но я доверюсь своему личному жОпыту.

Хочу попробовать воткнуть такое в другие программы, которые в пиках могут жрать много памяти - в worker браузера, etc.

Так же мне стало интересно, как дела обстоят с телегами, которые собирают дистрибутивы - все ли там хорошо, или нет.

* Alpine linux - https://git.alpinelinux.org/aports/tree/community/telegram-desktop/disable-jemalloc.patch они явно отключают jemalloc в пользу системного. Скорее всего, там все плохо, и телега жрет памяти, как не в себя.

* Arch linux - https://archlinux.org/packages/community/x86_64/telegram-desktop/ https://github.com/archlinux/svntogit-community/blob/packages/telegram-desktop/trunk/PKGBUILD - все сложно. Есть зависимость от системного jemalloc, но забандленый явно не выключен. Поэтому все зависит от того, как работает configure/cmake(выключит он или нет забандленый код, если найдет системный), а дальше - от порядка линковки и фичей системного jemalloc. Пара вариантов:

1. Все работает just as planned, используется забандленный, линкер просто выкидывает зависимость от системного.

2. Все работает наперекосяк. Самыми разными способами. Например, символы аллокатора берутся из системного, заголовки - из забандленного, код по активации вызывается или нет, ну и в системном может просто не быть поддержки этого вызова.

Нужно брать и проверять наживую, фанатам того или иного дистра рекомендую проверить телегу в нем - поставить gdb на mallctl, и потрейсить готовые бинари.
🔥9👍1😁1
https://lwn.net/Articles/892334/

"Тихо и незаметно" вышел M1-ready OpenBSD. 3D там, очевидно, нет, и быть не может.

———
https://www.opennet.ru/opennews/art.shtml?num=57067
https://gitflic.ru/project/erthink/libmdbx

github беснуется.

Вроде, обещали, что банить без причин и возможности оправдаться не будут, но нет.

С libmdbx вообще какая-то странная ситуация, я не понимаю, за что их.

———
Я тут захотел себе kinetic scrolling везде.

Хотел было даже запилить в libinput, но вовремя остановился, поискал, почему еще нет.

https://wayland.freedesktop.org/libinput/doc/latest/faqs.html#kinetic-scrolling-does-not-work

Удивительно, но совершенно корректная причина - если сделать по рабоче-крестьянски(как я и хотел), то ошметки могут попасть в другое приложение.

Дальше моя мысль пошла по 2 направлениями:

* А что с kinetic в qt, или, на худой конец, прямо в телеге?

https://github.com/telegramdesktop/tdesktop/issues/6746

Читаем, ходим по ссылочкам.

TL;DR - оно подвисло где-то в QT, видимо, они не заинтересованы. И, наверное, их можно понять, потому что, если я их верно понимаю, у них деньги не от десктопа. Десктоп - всего лишь витрина.

* Запилить прямо в sway. Композитор может послать шлейф kinetic эвентов в нужное окно. Понятно, что в upstream такое не примут, читаю код, можно ли это сделать малой кровью, чтобы потом было несложно мержить.

———
https://www.phoronix.com/scan.php?page=news_item&px=Linux-5.18-x86-WERROR

В Linux 5.18 хотят включить werror дляx 86_64. Шансов на это нет, потому что, имея на руках нетестируемое декартово произведение всех возможных настроек, средняя сборка не будет иметь шансов сойтись.

К счастью, я имею возможность override идиотских решений разработчиков, у меня враппер для компилятора, куда я добавлю -w принудительно.
👍5
Наши телерадиослушатели коммитят исправление сборки с clang в телегу, не могу не поделиться!
https://github.com/telegramdesktop/tdesktop/pull/24435

———
Задачка на unix shell - переместить все файлы из директории в какую-то другую, не являющуюся потомком исходной.

Нельзя пользоваться C/Perl/Python, etc

Я делал подход к снаряду несколько раз, и всегда у меня находились дыры :)) Однострочником так и не получилось, пришлось в циклы и вот это вот все.

https://superuser.com/questions/62141/how-to-move-all-files-from-current-directory-to-upper-directory

Тред с обсуждением решений. Во всех решениях, которые там есть(не читерские), есть дыры, попробуйте их поискать.

———
https://gitlab.freedesktop.org/libinput/libinput/-/commit/a423d7d3269dc32a87384f79e29bb5ac021c83d1

Фикс бага в libinput.

"Ядро" фикса, конечно, доставляет - https://gitlab.freedesktop.org/libinput/libinput/-/commit/a423d7d3269dc32a87384f79e29bb5ac021c83d1#29a46532ba391d88b6cc8668e181e65c1e43a7d7_401_409

———
https://spacedoutandsmiling.com/blog/2021-12-27-nerdy-aws-graviton-vs-m1-vs-m1-pro-nodejsr-benchmarks

Старая ссылка, почему-то забыл про нее написать. По косвенным данным можно сделать вывод, насколько одно ядро M1 круче, чем одно ядро от graviton.
👍6
У меня сегодня 2 истории, несколько технические, но, КМК, интересные.

В #tcmalloc нет реализации reallocarray(). В принципе, они в своем праве, потому что никому ничего не должны.

Проблема в том, что в musl reallocarray реализован.

Почему это проблема? Потому что у нас получается интересная ситуация - в stdlib.h есть сигнатура для reallocarray(), а в libmusl.a + libtcmalloc.a такого символа нет.

Дальше получается следующее:

1) Если configure проекта определяет наличие символа через компиляцию, то он получит, что reallocarray есть в наличии, и не включит у себя флажок, по которому бы код подставил свою реализацию. И в момент линковки будет ошибка.

2) Если configure определяет это через линковку, то он получит, что reallocarray нет, и включит флажок, по которому код включит у себя fallback на свою реализацию. Казалось бы, все хорошо? Нет, потому что эта рализация может не скомпилироваться, потому что в stdlib.h есть сигнатура от musl, и они могут, в деталях, не совпадать(например, throw()/noexept/etc).

Засада.

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

https://git.sr.ht/~pg/mix/tree/main/item/pkgs/lib/tcmalloc/mix.sh#L25

Кстати, в реализации, в которой я на это наткнулся, ошибка - https://git.sr.ht/~emersion/basu/tree/master/item/src/basic/alloc-util.h#L76 (впрочем, AFAIK стандарта на это еще нет, поэтому все в своем праве)

———
Решил я себе собрать #dosbox.

А он, зараза, зависит от SDL1, которая давно не обновляется, и собирать ее с wayland мне особо не хотелось.

Есть реализация api sdl1 через sdl2. https://github.com/libsdl-org/sdl12-compat/blob/main/src/SDL12_compat.c (в одном файле, да)

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

Проблема в том, что у sdl1 и sdl2 один и тот же namespace, и функции пересекаются по именам. Поэтому коллега, ничтоже сумняшеся, загружает .so с SDL2 в RTLD_LOCAL режиме, и достает оттуда символы почем зря.

Мне пришлось соорудить интересную шутку - собрать библиотеку SDL2, и переложить все символы в другой namespace(по сути, добавить префикс V2_ ко всем экспортируемым именам). Я назвал библиотеку "SDL2 chimera". https://git.sr.ht/~pg/mix/tree/main/item/pkgs/lib/sdl/chimera/mix.sh#L12 После чего "загрузка" такой .a библиотеки дело техники - нужно всего лишь составить список вида [("SDL2", "SDL_xxx", &V2_SDL_xxx)] для моего загрузчика .so. https://git.sr.ht/~pg/mix/tree/main/item/pkgs/lib/sdl/chimera/dl/mix.sh#L14 Пересечений с SDL1 в общем пространстве имен бинарника не будет.

dosbox, сликованный в один бинарь с SDL2 - никто не умеет, а я умею :)

Отмечу, что вот это решение - оно вполне себе норм, то есть, это не хак, который будет разваливаться от каждого чиха. Переименование символов - хорошо определенная операция на объектных файлах, без странных side effect. Ну а добавить "V2_" - это очень разумная эмуляция для RTLD_LOCAL, найдите 5 отличий, что называется.
👍10🔥5