Although NumLeapSeconds::set_locked is always called with list_mutex()
locked, if ATOMIC_INT_LOCK_FREE == 2 then readers ofthe variable will be
loading it without list_mutex() locked. We need to use an atomic store
even if the lock is held.
Also simplify the non-atomic version of NumLeapSeconds::set to just set
the variable instead of indirecting via set_locked.
libstdc++-v3/ChangeLog:
* src/c++20/tzdb.cc (_Node::NumLeapSeconds::set_locked)
[ATOMIC_INT_LOCK_FREE == 2]: Use atomic store.
(_Node::NumLeapSeconds::set) [ATOMIC_INT_LOCK_FREE != 2]: Set
value directly instead of calling set_locked.
Reviewed-by: Tomasz KamiĆski <tkaminsk@redhat.com>
ref.store(val, memory_order::release);
#else
lock_guard<mutex> l(list_mutex());
- set_locked(val, l);
+ count = val;
#endif
}
void
set_locked(unsigned val, const lock_guard<mutex>&)
{
+#if ATOMIC_INT_LOCK_FREE == 2
+ // Even though the caller locked the mutex, we still need to use an
+ // atomic store in this case, because there could be concurrent loads.
+ set(val);
+#else
// The only caller of this function locks list_mutex() so we would
// deadlock if we locked it again here.
count = val;
+#endif
}
private: