![]() |
MySQL 8.0.43
Source Code Documentation
|
The Gcs_tagged_lock class Implements a tagged lock for optimistic read-side sections. More...
#include <gcs_tagged_lock.h>
Public Types | |
| using | Tag = std::uint64_t |
Public Member Functions | |
| Gcs_tagged_lock () noexcept | |
| ~Gcs_tagged_lock () | |
| Tag | optimistic_read () const |
| Starts an optimistic read-side section. More... | |
| bool | validate_optimistic_read (Tag const &tag) const |
| Validates an optimistic read-side section. More... | |
| bool | try_lock () |
| Attempts to start a write-side section, i.e. More... | |
| void | unlock () |
| Finishes the write-side section, i.e. More... | |
| bool | is_locked () const |
| Checks whether the lock is currently acquired. More... | |
Private Member Functions | |
| std::uint64_t | get_lock_word (std::memory_order order=std::memory_order_acquire) const |
Private Attributes | |
| std::atomic< std::uint64_t > | m_lock_word |
The Gcs_tagged_lock class Implements a tagged lock for optimistic read-side sections.
In a nutshell, the tagged lock is a read-write spin lock which offers the following API:
try_lock() -> bool unlock() optimistic_read() -> tag validate_optimistic_read(tag) -> bool
For the write-side section, one uses it as a typical spin lock, e.g.:
do: lock_acquired := try_lock() while (not lock_acquired) write-side section unlock()
For the read-side section, one can use it as follows:
done := false
while (not done):
tag := optimistic_read()
unsynchronised read-side section
done := validate_optimistic_read(tag)
if (not done):
rollback unsynchronized read-side section
The idea is to allow an optimistic read-side section that does not perform any memory stores. This is in contrast with a typical read-write lock, where the read side performs some memory stores to account for the reader, e.g. keeping a reader counter. The trade off is that:
a. the execution of the read-side of a tagged lock may be concurrent with the write-side section if meanwhile the tagged lock is acquired b. the read-side of a tagged lock may fail if meanwhile the tagged lock is acquired, in which case one may want to rollback the effects of the failed read-side section
The tagged lock is implemented over a single atomic 64-bit word with the following bit layout:
bit # 64 63 62 3 2 1
+---+---+---+-...-+---+---+---+
| | | | | | | |
+---+---+---+-...-+---+---+---+
\__________ ___________/ \ /
\/ v
tag locked?
| using Gcs_tagged_lock::Tag = std::uint64_t |
|
noexcept |
|
default |
|
private |
| bool Gcs_tagged_lock::is_locked | ( | ) | const |
Checks whether the lock is currently acquired.
| Gcs_tagged_lock::Tag Gcs_tagged_lock::optimistic_read | ( | ) | const |
Starts an optimistic read-side section.
| bool Gcs_tagged_lock::try_lock | ( | ) |
Attempts to start a write-side section, i.e.
acquire the lock.
| void Gcs_tagged_lock::unlock | ( | ) |
Finishes the write-side section, i.e.
releases the lock.
| bool Gcs_tagged_lock::validate_optimistic_read | ( | Gcs_tagged_lock::Tag const & | tag | ) | const |
Validates an optimistic read-side section.
| tag | The tag returned by the corresponding optimistic_read |
|
private |