![]()  | 
  
    MySQL 9.5.0
    
   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 ()=default | |
| 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 |