Здравствуйте, ·, Вы писали:
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 не возбраняется.