Skip to content
/ server Public
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion storage/innobase/btr/btr0cur.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1719,7 +1719,12 @@ ATTRIBUTE_COLD void mtr_t::index_lock_upgrade()
return;
ut_ad(slot.type == MTR_MEMO_SX_LOCK);
index_lock *lock= static_cast<index_lock*>(slot.object);
lock->u_x_upgrade(SRW_LOCK_CALL);
if (!lock->u_x_upgrade_try())
{
lock->u_unlock();
ut_ad(!lock->have_any());
lock->x_lock(SRW_LOCK_CALL);
}
slot.type= MTR_MEMO_X_LOCK;
}

Expand Down
10 changes: 10 additions & 0 deletions storage/innobase/include/srw_lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,15 @@ class ssux_lock_impl

bool rd_u_upgrade_try() noexcept { return writer.wr_lock_try(); }

bool u_wr_upgrade_try() noexcept
{
DBUG_ASSERT(writer.is_locked());
uint32_t lk= 0;
return readers.compare_exchange_strong(lk, WRITER,
std::memory_order_acquire,
std::memory_order_relaxed);
}

void u_wr_upgrade() noexcept
{
DBUG_ASSERT(writer.is_locked());
Expand Down Expand Up @@ -496,6 +505,7 @@ class ssux_lock
else
lock.u_wr_upgrade();
}
bool u_wr_upgrade_try() noexcept { return lock.u_wr_upgrade_try(); }
bool rd_lock_try() noexcept { return lock.rd_lock_try(); }
bool u_lock_try() noexcept { return lock.u_lock_try(); }
bool wr_lock_try() noexcept { return lock.wr_lock_try(); }
Expand Down
19 changes: 17 additions & 2 deletions storage/innobase/include/sux_lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,31 @@ class sux_lock final
/** Upgrade an update lock */
inline void u_x_upgrade();
inline void u_x_upgrade(const char *file, unsigned line);
/** @return whether an update lock was upgraded to exclusive */
bool u_x_upgrade_try() noexcept
{
ut_ad(have_u_not_x());
if (!lock.u_wr_upgrade_try())
return false;
recursive/= RECURSIVE_U;
return true;
}

/** @return whether a shared lock was upgraded to exclusive */
bool s_x_upgrade_try()
bool s_x_upgrade_try() noexcept
{
ut_ad(have_s());
ut_ad(!have_u_or_x());
if (!lock.rd_u_upgrade_try())
return false;
claim_ownership();
s_unlock();
lock.u_wr_upgrade();
if (!lock.u_wr_upgrade_try())
{
ut_d(recursive= RECURSIVE_U);
u_s_downgrade();
return false;
}
recursive= RECURSIVE_X;
return true;
}
Expand Down