diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-10-02 09:25:40 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-10-02 09:25:40 +0300 |
commit | ec619a1def69c175d9fa07201b2567c3478e9408 (patch) | |
tree | 562c8edace1f7d587df5340f0dd7048b3e0f2388 /storage | |
parent | a49e394399859b23ba609d0058b498cfa876cac4 (diff) | |
download | mariadb-git-ec619a1def69c175d9fa07201b2567c3478e9408.tar.gz |
MDEV-26467 fixup: Prefer fetch_add() to fetch_or() on IA-32 and AMD64
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/include/srw_lock.h | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/storage/innobase/include/srw_lock.h b/storage/innobase/include/srw_lock.h index 3d0d82b81df..9e2eac15df0 100644 --- a/storage/innobase/include/srw_lock.h +++ b/storage/innobase/include/srw_lock.h @@ -226,8 +226,18 @@ public: void wr_lock() { writer.wr_lock(); +#if defined __i386__||defined __x86_64__||defined _M_IX86||defined _M_IX64 + /* On IA-32 and AMD64, this type of fetch_or() can only be implemented + as a loop around LOCK CMPXCHG. In this particular case, setting the + most significant bit using fetch_add() is equivalent, and is + translated into a simple LOCK XADD. */ + static_assert(WRITER == 1U << 31, "compatibility"); + if (uint32_t lk= readers.fetch_add(WRITER, std::memory_order_acquire)) + wr_wait(lk); +#else if (uint32_t lk= readers.fetch_or(WRITER, std::memory_order_acquire)) wr_wait(lk); +#endif } void u_wr_upgrade() |