summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2023-02-09 13:36:18 +0000
committerYann Ylavic <ylavic@apache.org>2023-02-09 13:36:18 +0000
commitc0cce761f8e04183ddd506bdb814d66bab5f4a78 (patch)
treef78eabc76f55a1085e8836c1f484a3516309df9e
parent8c6a1aa1fa33f8c82d1333c9ef38c09799b4cf7b (diff)
downloadapr-c0cce761f8e04183ddd506bdb814d66bab5f4a78.tar.gz
apr_atomic: Generic apr_atomic_read64() needs a mutex on 32bit systems (tearing).
A 64bit load on a 32 bit CPU/system uses two instructions (tearing), so ensure atomicity with regard to other atomic functions by using the (same) lock. test_atomics_threaded_setread64() fails because of this on 32bit systems. PR 66457. * atomic/unix/mutex64.c(apr_atomic_read64): Use locking when APR_SIZEOF_VOIDP < 8 git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1907541 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--atomic/unix/mutex64.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/atomic/unix/mutex64.c b/atomic/unix/mutex64.c
index 9fc44af61..9f1f1df6d 100644
--- a/atomic/unix/mutex64.c
+++ b/atomic/unix/mutex64.c
@@ -96,7 +96,26 @@ apr_status_t apr__atomic_generic64_init(apr_pool_t *p)
APR_DECLARE(apr_uint64_t) apr_atomic_read64(volatile apr_uint64_t *mem)
{
+ /* On 32bit CPUs this loads with two instructions (tearing),
+ * so a lock is needed to ensure atomicity.
+ *
+ * APR_SIZEOF_VOIDP is probably not the right check for 32 vs 64 bits CPUs
+ * but it spares an (hardly-)exhaustive list of supported CPUs (and using
+ * assembly). If APR_SIZEOF_VOIDP==4 means that the compiler generates
+ * 32bit instructions (-m32 or whatever) then it's the right check though.
+ */
+#if APR_SIZEOF_VOIDP >= 8
return *mem;
+#else
+ apr_uint64_t cur_value;
+ DECLARE_MUTEX_LOCKED(mutex, mem);
+
+ cur_value = *mem;
+
+ MUTEX_UNLOCK(mutex);
+
+ return cur_value;
+#endif
}
APR_DECLARE(void) apr_atomic_set64(volatile apr_uint64_t *mem, apr_uint64_t val)