3076dbc
--- a/atomic/unix/mutex64.c	2023/02/09 12:45:02	1907540
3076dbc
+++ b/atomic/unix/mutex64.c	2023/02/09 13:36:18	1907541
3076dbc
@@ -96,7 +96,26 @@
3076dbc
 
3076dbc
 APR_DECLARE(apr_uint64_t) apr_atomic_read64(volatile apr_uint64_t *mem)
3076dbc
 {
3076dbc
+    /* On 32bit CPUs this loads with two instructions (tearing),
3076dbc
+     * so a lock is needed to ensure atomicity.
3076dbc
+     *
3076dbc
+     * APR_SIZEOF_VOIDP is probably not the right check for 32 vs 64 bits CPUs
3076dbc
+     * but it spares an (hardly-)exhaustive list of supported CPUs (and using
3076dbc
+     * assembly). If APR_SIZEOF_VOIDP==4 means that the compiler generates
3076dbc
+     * 32bit instructions (-m32 or whatever) then it's the right check though.
3076dbc
+     */
3076dbc
+#if APR_SIZEOF_VOIDP >= 8
3076dbc
     return *mem;
3076dbc
+#else
3076dbc
+    apr_uint64_t cur_value;
3076dbc
+    DECLARE_MUTEX_LOCKED(mutex, mem);
3076dbc
+
3076dbc
+    cur_value = *mem;
3076dbc
+
3076dbc
+    MUTEX_UNLOCK(mutex);
3076dbc
+
3076dbc
+    return cur_value;
3076dbc
+#endif
3076dbc
 }
3076dbc
 
3076dbc
 APR_DECLARE(void) apr_atomic_set64(volatile apr_uint64_t *mem, apr_uint64_t val)