The deadlock detector.
More...
|
| LatchDebug () 1 |
| Constructor. More...
|
|
| ~LatchDebug () 1 |
| Destructor. More...
|
|
Latches * | thread_latches (bool add=false) 1 |
| Create a new instance if one doesn't exist else return the existing one. More...
|
|
const Latched * | find_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_t * | find (const Latches *latches, latch_level_t level) const 1 |
| Checks if the level value exists in the thread's acquired latches. More...
|
|
const latch_t * | find (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 bool | s_initialized = false |
| For checking whether this module has been initialised or not. More...
|
|
◆ Levels
◆ Mutex
Debug mutex for control structures, should not be tracked by this module.
◆ ThreadMap
For tracking a thread's latches.
◆ LatchDebug() [1/2]
LatchDebug::LatchDebug |
( |
| ) |
|
Constructor.
Setup the mapping from level ID to level name mapping.
◆ ~LatchDebug()
LatchDebug::~LatchDebug |
( |
| ) |
|
|
inline |
◆ LatchDebug() [2/2]
◆ 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] | latches | thread's existing latches |
[in] | requested_level | the 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_level | Exclusive 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] | latches | thread's existing latches |
[in] | requested_level | the 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] | latches | thread's existing latches |
[in] | requested_level | the level of the requested latch |
◆ check_order()
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] | latch | pointer to a mutex or an rw-lock |
[in] | level | level in the latching order |
- Returns
- the thread's latches
◆ crash()
Report error and abort.
- Parameters
-
[in] | latches | thread's existing latches |
[in] | latched | The existing latch causing the invariant to fail |
[in] | level | The new level request that breaks the order |
◆ create_instance()
static void LatchDebug::create_instance |
( |
| ) |
|
|
inlinestatic |
Create the singleton instance.
◆ find() [1/2]
Checks if the level value exists in the thread's acquired latches.
- Parameters
-
[in] | latches | the thread's existing (acquired) latches |
[in] | level | to lookup |
- Returns
- latch if found or 0
◆ find() [2/2]
Checks if the level value exists in the thread's acquired latches.
- Parameters
-
[in] | level | The level to lookup |
- Returns
- latch if found or NULL
◆ find_lower_or_equal()
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] | latches | the thread's existing (acquired) latches |
[in] | limit | to check against |
- Returns
- latched if there is one with a level <= limit .
◆ for_each()
Iterate over a thread's latches.
- Parameters
-
[in,out] | functor | The 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] | level | The level ID to lookup |
- Returns
- level name
◆ init()
void LatchDebug::init |
( |
void |
| ) |
|
|
static |
Initialise the debug data structures.
◆ instance()
- 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
-
- Returns
- true if it is a an RTR mutex
◆ lock_granted()
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] | latch | latch that the thread wants to acquire. |
[in] | level | latch level to check against |
◆ lock_validate()
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] | latch | latch that the thread wants to acqire. |
[in] | level | latch level to check against |
◆ operator=()
◆ print_latches()
void LatchDebug::print_latches |
( |
const Latches * |
latches | ) |
const |
|
private |
Print the latches acquired by a thread.
- Parameters
-
[in] | latches | Latches acquired by a thread |
◆ relock()
void LatchDebug::relock |
( |
const latch_t * |
latch | ) |
|
|
inline |
For recursive X rw-locks.
- Parameters
-
[in] | latch | The 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] | add | add 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] | latch | The latch that was released |
Must find the latch.
◆ m_levels
Mapping from latche level to its string representation.
◆ m_mutex
Mutex LatchDebug::m_mutex |
|
private |
Mutex protecting the deadlock detector data structures.
◆ m_threads
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
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: