https://gist.github.com/stepan-neretin7/225d8753ef...
Error: Attempting to unlock a mutex not owned by the calling thread.
Ума не приложу почему такая ошибка со своим mutex
подскажите, пожалуйста
никак не получается отловить почему
res2001, я не вижу гонки, но вижу сомнительное обращение к owner вот здесь. Как минимум там нужен барьер, парный к этому барьеру. В других местах на мой взгляд всё ок. count и owner меняются только владельцем мьютекса под защитой lock, который меняется атомарно.
jcmvbkbc, Ну да тут гонка на чтении, аналогично и в unlock(). Нужен барьер или атомарные операции.
Вероятно не правильное срабатывание (или не срабатывание) условия.
Отсюда и появление ошибки.
res2001, объясни, кто с кем гоняется, я не вижу гонки. Условие здесь может быть истинным только в потоке-владельце, владелец может менять count как хочет, потому что другие потоки к нему не обращаются. Более того, если поток освободит мьютекс, а потом захочет захватить его обратно будучи на том же процессоре, он гарантированно увидит, что он не является владельцем. Вот чтобы гарантировать, что он увидит, что он не является владельцем будучи на другом процессоре нужен барьер чтения перед этой проверкой. Ну и аналогично, когда вледелец мьютекса только что захвативший его на одном CPU мигрирует на другой CPU и захватывает его повторно тот же самый барьер гарантирует, что условие проверки владения сработает правильно.
Нужен барьер или атомарные операции.
Для чего тут атомарные операции?
Отсюда и появление ошибки.
Появление ошибки -- из-за неправильно написанного кода. Обе упомянутые ошибки 100% детерминированные и воспроизводятся с одним потоком.
На счет того же потока на другом процессоре - думаю тут нет проблемы - при переключении контекста, по моему, происходит синхронизация (где-то читал про это), так что поток на новом ядре увидит как минимум собственные изменения, которые были на предыдущем проце.
Но я бы предпочел явную синхронизацию.
Можешь не называть это гонкой, я не знаю другого подходящего термина.
По формальным признакам (общие данные и нет синхронизации) вижу, что тут возможно состояние гонки.
Но я ее себе не обосновал. Но ошибка есть. Предполагаю, что из-за этого.
Для чего тут атомарные операции?
Атомарные операции - т.к. они включают в себя барьер. Или барьер или атомарные операции c owner.
Кстати, ошибка
Total: 0 asc: 0 dsc: 0 eq: 0
возможно говорит о том, что кастомный мьютекс не обеспечивает барьер памяти. А должен.
Хотя у него там сгенерированная строка не копируется в узел списка, поэтому все манипуляции со списком происходят на пустых узлах без данных. Но хотя бы Total и eq расти должны.
Обе упомянутые ошибки 100% детерминированные и воспроизводятся с одним потоком.
Этот код не запускал, т.к. сейчас на винде сижу, а у него тут фьютексы. Но запускал предыдущую версию с нормальными pthread мьютексами - все работало.