MySQL 8.3.0
Source Code Documentation
LatchDebug Struct Reference

The deadlock detector. More...

Classes

struct  latch_level_less
 Comparator for the Levels . More...
 

Public Types

typedef OSMutex Mutex
 Debug mutex for control structures, should not be tracked by this module. More...
 
typedef std::map< std::thread::id, Latches *, std::less< std::thread::id >, ut::allocator< std::pair< const std::thread::id, Latches * > > > ThreadMap
 For tracking a thread's latches. More...
 

Public Member Functions

 LatchDebug () 1
 Constructor. More...
 
 ~LatchDebug () 1
 Destructor. More...
 
Latchesthread_latches (bool add=false) 1
 Create a new instance if one doesn't exist else return the existing one. More...
 
const Latchedfind_lower_or_equal (const Latches *latches, latch_level_t limit) const 1
 Check that all the latches already owned by a thread have a higher level than limit and returns the latch which violates this expectation if any. More...
 
const latch_tfind (const Latches *latches, latch_level_t level) const 1
 Checks if the level value exists in the thread's acquired latches. More...
 
const latch_tfind (latch_level_t level) 1
 Checks if the level value exists in the thread's acquired latches. More...
 
void crash (const Latches *latches, const Latched *latched, latch_level_t level) const 1
 Report error and abort. More...
 
void assert_all_held_are_above (const Latches *latches, latch_level_t requested_level, ulint forbidden_level) const 1
 Do a basic ordering check. More...
 
void assert_requested_is_lower_than_held (latch_level_t requested_level, const Latches *latches) const 1
 Asserts that all the latches already acquired by the thread have a level higher than the newly requested latch. More...
 
void assert_requested_is_lower_or_equal_to_held (latch_level_t requested_level, const Latches *latches) const 1
 Asserts that all the latches already acquired by the thread have a level higher or equal to the newly requested latch. More...
 
void lock_validate (const latch_t *latch, latch_level_t level) 1
 Adds a latch and its level in the thread level array. More...
 
void lock_granted (const latch_t *latch, latch_level_t level) 1
 Adds a latch and its level in the thread level array. More...
 
void relock (const latch_t *latch) 1
 For recursive X rw-locks. More...
 
bool for_each (sync_check_functor_t &functor) 1
 Iterate over a thread's latches. More...
 
void unlock (const latch_t *latch) 1
 Removes a latch from the thread level array if it is found there. More...
 
const std::string & get_level_name (latch_level_t level) const 1
 Get the level name. More...
 

Static Public Member Functions

static void init () 1
 Initialise the debug data structures. More...
 
static void shutdown () 1
 Shutdown the latch debug checking. More...
 
static LatchDebuginstance () 1
 
static void create_instance () 1
 Create the singleton instance. More...
 

Static Public Attributes

static bool s_initialized = false
 For checking whether this module has been initialised or not. More...
 

Private Types

typedef std::map< latch_level_t, std::string, latch_level_less, ut::allocator< std::pair< const latch_level_t, std::string > > > Levels
 

Private Member Functions

 LatchDebug (const LatchDebug &)
 Disable copying. More...
 
LatchDebugoperator= (const LatchDebug &)
 
Latchescheck_order (const latch_t *latch, latch_level_t level) 1
 Adds a latch and its level in the thread level array. More...
 
void print_latches (const Latches *latches) const 1
 Print the latches acquired by a thread. More...
 
bool is_rtr_mutex (const latch_t *latch) const 1
 Special handling for the RTR mutexes. More...
 

Private Attributes

Mutex m_mutex
 Mutex protecting the deadlock detector data structures. More...
 
ThreadMap m_threads
 Thread specific data. More...
 
Levels m_levels
 Mapping from latche level to its string representation. More...
 

Static Private Attributes

static LatchDebugs_instance = nullptr
 The singleton instance. More...
 

Detailed Description

The deadlock detector.

Member Typedef Documentation

◆ Levels

typedef std::map<latch_level_t, std::string, latch_level_less, ut::allocator<std::pair<const latch_level_t, std::string> > > LatchDebug::Levels
private

◆ Mutex

Debug mutex for control structures, should not be tracked by this module.

◆ ThreadMap

typedef std::map<std::thread::id, Latches *, std::less<std::thread::id>, ut::allocator<std::pair<const std::thread::id, Latches *> > > LatchDebug::ThreadMap

For tracking a thread's latches.

Constructor & Destructor Documentation

◆ LatchDebug() [1/2]

LatchDebug::LatchDebug ( )

Constructor.

Setup the mapping from level ID to level name mapping.

◆ ~LatchDebug()

LatchDebug::~LatchDebug ( )
inline

Destructor.

◆ LatchDebug() [2/2]

LatchDebug::LatchDebug ( const LatchDebug )
private

Disable copying.

Member Function Documentation

◆ assert_all_held_are_above()

void LatchDebug::assert_all_held_are_above ( const Latches latches,
latch_level_t  requested_level,
ulint  forbidden_level 
) const

Do a basic ordering check.

Asserts that all the existing latches have a level higher than the forbidden_level.

Parameters
[in]latchesthread's existing latches
[in]requested_levelthe level of the requested latch, used in error message only, to provide the context of the check to the user. For actual comparisons in asserts the value of forbidden_level will be used.
[in]forbidden_levelExclusive lower bound on levels of currently held latches - i.e. each latch in latches must have level strictly grater than forbidden_level. Usually, forbidden_level equals requested_level, but if we allow a thread to hold more than one latch at requested_level (avoiding deadlock between them in some other way), then it will be requested_level - 1. It can have a value other than these two, in rare cases, where deadlock avoidance rules are even more complicated, but this should be avoided.

◆ assert_requested_is_lower_or_equal_to_held()

void LatchDebug::assert_requested_is_lower_or_equal_to_held ( latch_level_t  requested_level,
const Latches latches 
) const
inline

Asserts that all the latches already acquired by the thread have a level higher or equal to the newly requested latch.

This is a rule used for latches which can have multiple instances and a thread is allowed to latch more than one such instance, when we can somehow prove there's no deadlock due to threads requesting more than one. It's the responsibility of the developer to document and prove this additional property, ideally encoding it in LatchDebug::check_order. One example of such case would be when we know that to latch more than one instance the thread must first acquire exclusive right to another singleton latch. Another example would be if we always follow some natural ordering on the latches of this kind, like by increasing address in an array.

Parameters
[in]latchesthread's existing latches
[in]requested_levelthe level of the requested latch

◆ assert_requested_is_lower_than_held()

void LatchDebug::assert_requested_is_lower_than_held ( latch_level_t  requested_level,
const Latches latches 
) const
inline

Asserts that all the latches already acquired by the thread have a level higher than the newly requested latch.

This is the most typical latching order rule ensuring no deadlock cycle: strictly descending sequence can not have a loop.

Parameters
[in]latchesthread's existing latches
[in]requested_levelthe level of the requested latch

◆ check_order()

Latches * LatchDebug::check_order ( const latch_t latch,
latch_level_t  level 
)
private

Adds a latch and its level in the thread level array.

Allocates the memory for the array if called first time for this OS thread. Makes the checks against other latch levels stored in the array for this thread.

Parameters
[in]latchpointer to a mutex or an rw-lock
[in]levellevel in the latching order
Returns
the thread's latches

◆ crash()

void LatchDebug::crash ( const Latches latches,
const Latched latched,
latch_level_t  level 
) const

Report error and abort.

Parameters
[in]latchesthread's existing latches
[in]latchedThe existing latch causing the invariant to fail
[in]levelThe new level request that breaks the order

◆ create_instance()

static void LatchDebug::create_instance ( )
inlinestatic

Create the singleton instance.

◆ find() [1/2]

const latch_t * LatchDebug::find ( const Latches latches,
latch_level_t  level 
) const

Checks if the level value exists in the thread's acquired latches.

Parameters
[in]latchesthe thread's existing (acquired) latches
[in]levelto lookup
Returns
latch if found or 0

◆ find() [2/2]

const latch_t * LatchDebug::find ( latch_level_t  level)

Checks if the level value exists in the thread's acquired latches.

Parameters
[in]levelThe level to lookup
Returns
latch if found or NULL

◆ find_lower_or_equal()

const Latched * LatchDebug::find_lower_or_equal ( const Latches latches,
latch_level_t  limit 
) const

Check that all the latches already owned by a thread have a higher level than limit and returns the latch which violates this expectation if any.

Parameters
[in]latchesthe thread's existing (acquired) latches
[in]limitto check against
Returns
latched if there is one with a level <= limit .

◆ for_each()

bool LatchDebug::for_each ( sync_check_functor_t functor)
inline

Iterate over a thread's latches.

Parameters
[in,out]functorThe callback
Returns
true if the functor returns true.

◆ get_level_name()

const std::string & LatchDebug::get_level_name ( latch_level_t  level) const
inline

Get the level name.

Parameters
[in]levelThe level ID to lookup
Returns
level name

◆ init()

void LatchDebug::init ( void  )
static

Initialise the debug data structures.

◆ instance()

static LatchDebug * LatchDebug::instance ( )
inlinestatic
Returns
the singleton instance

◆ is_rtr_mutex()

bool LatchDebug::is_rtr_mutex ( const latch_t latch) const
inlineprivate

Special handling for the RTR mutexes.

We need to add proper levels for them if possible.

Parameters
[in]latchLatch to check
Returns
true if it is a an RTR mutex

◆ lock_granted()

void LatchDebug::lock_granted ( const latch_t latch,
latch_level_t  level 
)
inline

Adds a latch and its level in the thread level array.

Allocates the memory for the array if called for the first time for this OS thread. Makes the checks against other latch levels stored in the array for this thread.

Parameters
[in]latchlatch that the thread wants to acquire.
[in]levellatch level to check against

◆ lock_validate()

void LatchDebug::lock_validate ( const latch_t latch,
latch_level_t  level 
)
inline

Adds a latch and its level in the thread level array.

Allocates the memory for the array if called for the first time for this OS thread. Makes the checks against other latch levels stored in the array for this thread.

Parameters
[in]latchlatch that the thread wants to acqire.
[in]levellatch level to check against

◆ operator=()

LatchDebug & LatchDebug::operator= ( const LatchDebug )
private

◆ print_latches()

void LatchDebug::print_latches ( const Latches latches) const
private

Print the latches acquired by a thread.

Parameters
[in]latchesLatches acquired by a thread

◆ relock()

void LatchDebug::relock ( const latch_t latch)
inline

For recursive X rw-locks.

Parameters
[in]latchThe RW-Lock to relock

◆ shutdown()

void LatchDebug::shutdown ( )
static

Shutdown the latch debug checking.

Note: We don't enforce any synchronisation checks. The caller must ensure that no races can occur

◆ thread_latches()

Latches * LatchDebug::thread_latches ( bool  add = false)

Create a new instance if one doesn't exist else return the existing one.

Parameters
[in]addadd an empty entry if one is not found (default no)
Returns
pointer to a thread's acquired latches.

◆ unlock()

void LatchDebug::unlock ( const latch_t latch)

Removes a latch from the thread level array if it is found there.

Parameters
[in]latchThe latch that was released

Must find the latch.

Member Data Documentation

◆ m_levels

Levels LatchDebug::m_levels
private

Mapping from latche level to its string representation.

◆ m_mutex

Mutex LatchDebug::m_mutex
private

Mutex protecting the deadlock detector data structures.

◆ m_threads

ThreadMap LatchDebug::m_threads
private

Thread specific data.

Protected by m_mutex.

◆ s_initialized

bool LatchDebug::s_initialized = false
static

For checking whether this module has been initialised or not.

◆ s_instance

LatchDebug * LatchDebug::s_instance = nullptr
staticprivate

The singleton instance.

The latch order checking infra-structure.

Must be created in single threaded mode.


The documentation for this struct was generated from the following file: