Forwarded from Денис Чужой про комедию
This media is not supported in your browser
VIEW IN TELEGRAM
После прохождения Half Life 2 наконец-то придумал продолжение для «Неуверенной России»
📷 Подписывайтесь на меня в соцсети «Инстаграм» и показывайте иностранным друзьям.
📷 Подписывайтесь на меня в соцсети «Инстаграм» и показывайте иностранным друзьям.
😁6🤡3
#prog #article #abnormalprogramming
Subtraction Is Functionally Complete (перевод)
To be precise, IEEE-754 floating point subtraction is functionally complete. That means you can construct any binary circuit using nothing but floating point subtraction.
(thanks @teamerlin)
Subtraction Is Functionally Complete (перевод)
To be precise, IEEE-754 floating point subtraction is functionally complete. That means you can construct any binary circuit using nothing but floating point subtraction.
(thanks @teamerlin)
😁7
#prog #rust #rustasync #article
На этот раз — целая серия статей от Cliff L. Biffle. Все из них прямо или косвенно связаны с lilos — подходящая для встраиваемых систем операционная система реального времени, которая использует растовый async для запуска тасок (= приложений в этой OS) и потребляет очень мало ресурсов как в долговременной памяти, так и в оперативной:
This is a wee operating system written to support the
lilos has been deployed in real embedded systems since 2019, running continuously. I've built about a dozen systems around it of varying complexity, on half a dozen varieties of microcontroller. It works pretty okay! Perhaps you will find it useful too.
Первая статья, которую я хочу затронуть — это How to think about `async`/`await` in Rust. В ней рассказывается о принципиальном отличии async fn от обычных функций — о том, что async fn суть машина состояний и потому в случае асинхронных функций контроль над исполнением кода имеет вызывающая сторона — а также немного о том, в какие практические следствия это вытекает.
Вторая статья: Composing concurrency in drivers (An example of why I like async for embedded). На примере наброска I2C-драйвера автор показывает, как можно добавить в код драйвера обработку ошибок и прерываний, не внося изменений в бизнес-логику протокола. Эта возможность весьма существенно полагается на особенности реализации async в Rust. Если быть более конкретным, итоговый код полагается на futures::select_biased!.
Как несложно догадаться, для корректной работы подобного кода исполняемые футуры должны быть cancel safe. Как сказано в документации к tokio::select!:
Cancellation safety can be defined in the following way: If you have a future that has not yet completed, then it must be a no-op to drop that future and recreate it. This definition is motivated by the situation where a
И cancellation safety обладает рядом крайне неприятных свойств:
* Она (или её отсутствие, что немаловажно) редко задокументирована.
* Cancellation unsafety заразительна: если футура не является cancel safe, то поверх неё невозможно сделать cancel safe обёртку.
* Cancellation safety (в отличие от weak exception safety) не композируется: можно взять два куска асинхронного кода, каждый из которых по отдельности cancel safe, и совместить их так, что получится cancel unsafe код.
* Так как cancellation safety является довольно сложным семантическим свойством (и, как справедливо замечают в документации tokio, cancel unsafe код — это не всегда что-то плохое), cancellation safety никак не отслеживается компилятором.
(конкретно последний пункт можно было бы, в теории, починить, используя линейные типы — а не афинные, как сейчас в Rust — но, как писал лодочник, впихнуть их в уже существующий язык с широкой экосистемой весьма сложно)
Имеющуюся плачевную ситуацию можно до какой-то степени улучшить, предоставив набор документированных cancel safe примитивных операций. И вот тут lilos заметно отличается от прочих асинк-экосистем. В статье с провокационным названием Mutex without lock, Queue without push: cancel safety in lilos автор рассказывает, как он смог сделать API в lilos cancel safe, причём в более строгом смысле, чем обычно. Именно, автор вводит несколько уровней cancellaton safety:
На этот раз — целая серия статей от Cliff L. Biffle. Все из них прямо или косвенно связаны с lilos — подходящая для встраиваемых систем операционная система реального времени, которая использует растовый async для запуска тасок (= приложений в этой OS) и потребляет очень мало ресурсов как в долговременной памяти, так и в оперативной:
This is a wee operating system written to support the
async
style of programming in Rust on microcontrollers. It fits in about 2 kiB of Flash and uses about 20 bytes of RAM (before your tasks are added). In that space, you get a full async
runtime with multiple tasks, support for complex concurrency via join
and select
, and a lot of convenient but simple APIs.lilos has been deployed in real embedded systems since 2019, running continuously. I've built about a dozen systems around it of varying complexity, on half a dozen varieties of microcontroller. It works pretty okay! Perhaps you will find it useful too.
Первая статья, которую я хочу затронуть — это How to think about `async`/`await` in Rust. В ней рассказывается о принципиальном отличии async fn от обычных функций — о том, что async fn суть машина состояний и потому в случае асинхронных функций контроль над исполнением кода имеет вызывающая сторона — а также немного о том, в какие практические следствия это вытекает.
Вторая статья: Composing concurrency in drivers (An example of why I like async for embedded). На примере наброска I2C-драйвера автор показывает, как можно добавить в код драйвера обработку ошибок и прерываний, не внося изменений в бизнес-логику протокола. Эта возможность весьма существенно полагается на особенности реализации async в Rust. Если быть более конкретным, итоговый код полагается на futures::select_biased!.
Как несложно догадаться, для корректной работы подобного кода исполняемые футуры должны быть cancel safe. Как сказано в документации к tokio::select!:
Cancellation safety can be defined in the following way: If you have a future that has not yet completed, then it must be a no-op to drop that future and recreate it. This definition is motivated by the situation where a
select!
is used in a loop. Without this guarantee, you would lose your progress when another branch completes and you restart the select!
by going around the loop.И cancellation safety обладает рядом крайне неприятных свойств:
* Она (или её отсутствие, что немаловажно) редко задокументирована.
* Cancellation unsafety заразительна: если футура не является cancel safe, то поверх неё невозможно сделать cancel safe обёртку.
* Cancellation safety (в отличие от weak exception safety) не композируется: можно взять два куска асинхронного кода, каждый из которых по отдельности cancel safe, и совместить их так, что получится cancel unsafe код.
* Так как cancellation safety является довольно сложным семантическим свойством (и, как справедливо замечают в документации tokio, cancel unsafe код — это не всегда что-то плохое), cancellation safety никак не отслеживается компилятором.
(конкретно последний пункт можно было бы, в теории, починить, используя линейные типы — а не афинные, как сейчас в Rust — но, как писал лодочник, впихнуть их в уже существующий язык с широкой экосистемой весьма сложно)
Имеющуюся плачевную ситуацию можно до какой-то степени улучшить, предоставив набор документированных cancel safe примитивных операций. И вот тут lilos заметно отличается от прочих асинк-экосистем. В статье с провокационным названием Mutex without lock, Queue without push: cancel safety in lilos автор рассказывает, как он смог сделать API в lilos cancel safe, причём в более строгом смысле, чем обычно. Именно, автор вводит несколько уровней cancellaton safety:
GitHub
GitHub - cbiffle/lilos: A wee async RTOS for Cortex-M
A wee async RTOS for Cortex-M. Contribute to cbiffle/lilos development by creating an account on GitHub.
👍8❤1🔥1😱1
1. Cancel-unsafe — никакого вменяемого поведения при дропе, считай, unspecified behavior.
2. Strictly cancel-safe — удовлетворяет определению cancel safety из документации tokio выше, операция или происходит полностью, или не происходит вовсе при дропе футуры.
3. Weakly cancel-safe — дроп футуры не является noop, но, по крайней мере, эффект дропа полностью задокументирован.
4. Vacuously cancel-safe — код, который технически является cancel safe, но поощряет написание cancel unsafe кода. Как пишет автор: "These APIs are bug generators!".
Как автор выяснил (в частности, на собственных шишках), асинхронная операция push на очереди является weakly cancel safe, а операция взятия блокировки мьютекса — vacuously cancel-safe. В статье он предлагает cancel-safe альтернативу этим API, которые в итоге и были реализованы в последующих версиях lilos.
В несколько более техничной статье Writing a basic `async` debugger автор рассказывает о lildb — разработанным им инструменте, который позволяет неинтрузивно снимать с состояния программы await-trace-ы: именно, пути через код от корневых async-функций к листовым. Это позволяет помочь с ответами на вопросы в духе "почему эта часть асинхронного кода не исполняется". Существующие отладчики плохо подходят для подобных разбирательств, поскольку футуры в промежутках между вызовами poll — это просто структуры данных, у которых отсутствует стек. TL;DR: костыли.
В ещё более техничном продолжении Getting file/line in await traces автор рассказывает о том, как он смог сделать await-trace-ы более информативным за счёт указания на место в исходниках, в которых футуры остановились. TL;DR: больше костылей.
2. Strictly cancel-safe — удовлетворяет определению cancel safety из документации tokio выше, операция или происходит полностью, или не происходит вовсе при дропе футуры.
3. Weakly cancel-safe — дроп футуры не является noop, но, по крайней мере, эффект дропа полностью задокументирован.
4. Vacuously cancel-safe — код, который технически является cancel safe, но поощряет написание cancel unsafe кода. Как пишет автор: "These APIs are bug generators!".
Как автор выяснил (в частности, на собственных шишках), асинхронная операция push на очереди является weakly cancel safe, а операция взятия блокировки мьютекса — vacuously cancel-safe. В статье он предлагает cancel-safe альтернативу этим API, которые в итоге и были реализованы в последующих версиях lilos.
В несколько более техничной статье Writing a basic `async` debugger автор рассказывает о lildb — разработанным им инструменте, который позволяет неинтрузивно снимать с состояния программы await-trace-ы: именно, пути через код от корневых async-функций к листовым. Это позволяет помочь с ответами на вопросы в духе "почему эта часть асинхронного кода не исполняется". Существующие отладчики плохо подходят для подобных разбирательств, поскольку футуры в промежутках между вызовами poll — это просто структуры данных, у которых отсутствует стек. TL;DR: костыли.
В ещё более техничном продолжении Getting file/line in await traces автор рассказывает о том, как он смог сделать await-trace-ы более информативным за счёт указания на место в исходниках, в которых футуры остановились. TL;DR: больше костылей.
👍8
— Ты играешь в World of Tanks?
— Нет, я предпочитаю другие игры с танками.
Игры с танками:
— Нет, я предпочитаю другие игры с танками.
Игры с танками:
#prog #rust #article
Важная веха в развитии rustc_codegen_gcc: теперь он в состоянии компилировать Rust for Linux
It was announced last year that rustc_codegen_gcc can compile Rust for Linux with very few hacks. Today, I’m happy to announce that it can compile Rust for Linux without any patches! (Well, we still need patches to GCC itself like the rest of rustc_codegen_gcc, but those will be merged upstream eventually.)
Также автор провёл тесты на нескольких крейтах (полный список в статье) из числа широко используемых. Все компилируются и проходят тесты.
Важная веха в развитии rustc_codegen_gcc: теперь он в состоянии компилировать Rust for Linux
It was announced last year that rustc_codegen_gcc can compile Rust for Linux with very few hacks. Today, I’m happy to announce that it can compile Rust for Linux without any patches! (Well, we still need patches to GCC itself like the rest of rustc_codegen_gcc, but those will be merged upstream eventually.)
Также автор провёл тесты на нескольких крейтах (полный список в статье) из числа широко используемых. Все компилируются и проходят тесты.
blog.antoyo.xyz
Progress Report #26: rustc_codegen_gcc can now compile Rust for Linux!
Antoyo's Personal Blog
🔥16👍1
#prog #rust хайлайты
▪️Примитивным числовым типам добавили метод для вычисления целочисленного квадратного корня.
▪️В случае, если тип в выражении в
▪️Добавили функцию для сравнения только адресов указателей (без сравнения метаданных).
▪️Метод Result::unwrap_or_else получил атрибут #[track_caller]. Код вида
▪️Линты, указывающие на невалидные UTF-8 значения, теперь стараются указывать на выражение, которое содержит исходный невалидный литерал.
▪️Добавлен макрос cfg_match!, который как cfg_if!, но мимикрирует под синтаксис
▪️Примитивным числовым типам добавили метод для вычисления целочисленного квадратного корня.
▪️В случае, если тип в выражении в
break
отличается от типа loop
в целом, компилятор теперь указывает на места в коде, из-за которых типы не совпадают (1, 2) (Эстебан, кто ж ещё).▪️Добавили функцию для сравнения только адресов указателей (без сравнения метаданных).
▪️Метод Result::unwrap_or_else получил атрибут #[track_caller]. Код вида
.unwrap_or_else(|| panic!(...))
часто используется, когда unwrap
и expect
не подходят (из-за ненужных ограничений на E
или недостаточно внятных сообщений). Сообщение о панике для такого кода теперь даже при отсутствии стектрейса будет указывать на место вызова метода, а не на кишки core.▪️Линты, указывающие на невалидные UTF-8 значения, теперь стараются указывать на выражение, которое содержит исходный невалидный литерал.
▪️Добавлен макрос cfg_match!, который как cfg_if!, но мимикрирует под синтаксис
match
.GitHub
Add "integer square root" method to integer primitive types by FedericoStra · Pull Request #116176 · rust-lang/rust
For every suffix N among 8, 16, 32, 64, 128 and size, this PR adds the methods
const fn uN::isqrt() -> uN;
const fn iN::isqrt() -> iN;
const fn iN::checked_isqrt() -> Option<iN>;
to ...
const fn uN::isqrt() -> uN;
const fn iN::isqrt() -> iN;
const fn iN::checked_isqrt() -> Option<iN>;
to ...
❤🔥5👍2❤1
#prog #rust #amazingopensource
svgbob — это библиотека и утилита для перевода ASCII-диаграмм в SVG. На сайте проекта можете посмотреть эти и другие примеры (серьёзно, посмотрите, их там предостаточно, я заскринил лишь небольшую часть), причём в веб-редакторе вы можете отредактировать текстовые исходники и увидеть, как изменения сказываются на отрендеренном SVG.
В пару к нему — mdbook-svgbob, плагин к mdbook для использования svgbob-диаграм прям в исходниках.
svgbob — это библиотека и утилита для перевода ASCII-диаграмм в SVG. На сайте проекта можете посмотреть эти и другие примеры (серьёзно, посмотрите, их там предостаточно, я заскринил лишь небольшую часть), причём в веб-редакторе вы можете отредактировать текстовые исходники и увидеть, как изменения сказываются на отрендеренном SVG.
В пару к нему — mdbook-svgbob, плагин к mdbook для использования svgbob-диаграм прям в исходниках.
🔥12👍4❤2