]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Use atomic store for num_leap_seconds in tzdb.cc
authorJonathan Wakely <jwakely@redhat.com>
Wed, 1 Jul 2026 18:44:41 +0000 (19:44 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 2 Jul 2026 08:36:10 +0000 (09:36 +0100)
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>
libstdc++-v3/src/c++20/tzdb.cc

index 1aae07033f73b9fe174b531a57a5cee353065a9a..998a363151dc0416f628b75f41e2c6af9b793755 100644 (file)
@@ -1463,16 +1463,22 @@ struct tzdb_list::_Node::NumLeapSeconds
     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: