Re[45]: Безопасность Rust
От: vdimas Россия  
Дата: 04.06.19 13:19
Оценка:
Здравствуйте, ·, Вы писали:

V>>Не-не-не, Дэвид Блэйн, вы показывали Алексу, что в одном случае атомарность, а в другом нет.

·>Нет, Алекс пытался доказать что sig_atomic_t атомарен с т.з. многопоточности на том основании, что генерится одинаковый код. Это у него заняло несколько попыток. Последний результат — он назвал текущую имплементацию в gcc бажной.

Назвал другой человек, всерьёз проверивший этот момент, Алекс привёл ссылки.

Примечательно было то, что в реализации, про которую говорится, что она верная, действительно, генерируется простое sw в случае memory_order_release.


·>Но это всё мягко говоря не в тему, т.к. это всё равно не докажет многопоточную атомарность


Как минимум для приведённой тобой архитектуры докажет.
Напомню, что встречный вопрос был "приведите такую архитектуру, где это не так?"


V>>Тем самым ты и Сайберикс показали, что не понимаете, что есть атомарность, путаете её с упорядочиванием/синхронизацией.

·>Это ты путаешь. Нет такого понятия "нет упорядоченности", а есть order_relaxed.

))
Речь о гарантиях сохранения упорядоченности и возможности её нарушения.

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


V>>А я лишь утверждал о требовании записи значения в память в одну инструкцию из-за работы в условиях прерываний.

·>Это я как раз и упомянул первым. Ты же совершенно необоснованно пытаешься это натянуть на многопоточность.

Свои обоснования я приводил — из-за механизма вытеснения через прерывание.
Отвечать надо на конкретные доводы, а не эдаким широким жестом — "необоснованно!".


·>Хотя стандарт явно разделяет эти понятия. Посмотри хотя бы на наличие atomic_signal_fence и atomic_thread_fence.


Дык, первое запрещает переупорядочивание инструкций компилятором в этой точке, второй запрещает переупорядочивание инструкций внутри процессора.

Первое говорит о взаимодействии обработчика, прервавшего некий поток, и сам этот поток.
Т.е. речь об одном и том же физическом потоке, в котором поочерёдно выполняются два логических — пользовательский поток, поток обработки прерывания, опять пользовательский поток.

Есть еще и третий барьер, не введённый пока в стандарт С++ — это полная синхронизация когерентных кешей всех ядер.
(не уверен, что такое будет когда-нить в стандарте, но в современных ОС такая ф-ия есть)



V>>По стандарту sig_atomic_t в любом случае будет atomic.

·>Не в контексте многопоточки

Де-факто в контексте.


·>т.к. такое его использование — data race, а значит ub. Использование std::atomic не является data race.


1. Data race не всегда UB, часто так и задумано.

2. Использование std::atomic, защищает от data race неатомарные типы, для специализаций под эти типы структура std::atomic содержит внутри себя мьютекс.
Что характерно, что для таких типов memory_order не играет никакого значения, т.к. оперирование примитивами синхронизации означает выполнение самых строгих гарантий, т.е. обсуждаемый memory_order актуален только для типов, которые проц умеет сохранять/читать атомарно.


V>>Симметричная мякотка в том, что в многопроцессорной системе обработчик прерывания может быть вызыван из другого потока (из основного), а не из того, в котором ты осуществляешь оперироавние с переменной типа sig_atomic_t.

·>Верно. Но это обработчик сигнала будет вызван снаружи.

Не важно.


·>А тред должен дёргать signal().


Вызов signal устанавливает обработчика, а не генерирует сигнал.
Сигнал посылает kill/raise/alarm.
Сигнал посылается процессу, а не потоку.
Для посылки сигнала потоку есть отдельная ф-ия в либе pthread.


·>В этом случае сработают соответсвующие механизмы atomic.


А как до атомик-то жили? ))

Notes
Until C++11, which introduced std::atomic and std::atomic_signal_fence, about the only thing a strictly conforming program could do in a signal handler was to assign a value to a volatile static std::sig_atomic_t variable and promptly return.


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

Т.е. обработчики сигнала могут работать конкурентно, т.е. конкурентно писать в переменную volatile static std::sig_atomic_t variable из двух одновременно работающих физических потоков на многопроцессорной/многоядерной технике.
И всё должно при этом работать непротиворечиво.
Т.е., как ни крути, но писать конкурентно в sig_atomic_t не возбраняется.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.