MySQL 8.3.0
Source Code Documentation
sync0arr.cc File Reference

The wait array used in synchronization primitives. More...

#include "sync0arr.h"
#include <sys/types.h>
#include <time.h>
#include "lock0lock.h"
#include "os0event.h"
#include "os0file.h"
#include "srv0srv.h"
#include "sync0arr_impl.h"
#include "sync0debug.h"
#include "sync0sync.h"

Macros

#define sync_array_exit(a)   mutex_exit(&(a)->mutex)
 
#define sync_array_enter(a)   mutex_enter(&(a)->mutex)
 

Functions

static bool sync_array_detect_deadlock (sync_array_t *arr, sync_cell_t *cell, size_t depth)
 Detects a deadlock of one or more threads because of waits of semaphores. More...
 
static void sync_array_validate (sync_array_t *arr)
 Validates the integrity of the wait array. More...
 
sync_cell_tsync_array_get_nth_cell (sync_array_t *arr, ulint n)
 Gets the nth cell in array. More...
 
static void sync_array_free (sync_array_t *arr)
 Frees the resources in a wait array. More...
 
static os_event_t sync_cell_get_event (sync_cell_t *cell)
 Returns the event that the thread owning the cell waits for. More...
 
sync_cell_tsync_array_reserve_cell (sync_array_t *arr, void *object, ulint type, ut::Location location)
 Reserves a wait array cell for waiting for an object. More...
 
void sync_array_free_cell (sync_array_t *arr, sync_cell_t *&cell)
 Frees the cell. More...
 
void sync_array_detect_deadlock ()
 
void sync_array_wait_event (sync_array_t *arr, sync_cell_t *&cell)
 This function should be called when a thread starts to wait on a wait array cell. More...
 
template<typename Mutex >
static void sync_array_mutex_print (FILE *file, const Mutex *mutex)
 Reports info about a mutex (seen locked a moment ago) into a file. More...
 
void sync_array_cell_print (FILE *file, const sync_cell_t *cell)
 Reports info of a wait array cell into a file. More...
 
static sync_cell_tsync_array_find_thread (sync_array_t *arr, std::thread::id thread)
 Looks for a cell with the given thread id. More...
 
static bool sync_array_deadlock_step (sync_array_t *arr, std::thread::id thread, size_t depth)
 Recursion step for deadlock detection. More...
 
template<typename Mutex >
static bool sync_array_detect_mutex_deadlock (const Mutex *mutex, sync_array_t *arr, sync_cell_t *cell, size_t depth)
 A helper for sync_array_detect_deadlock() to handle the case when the cell contains a thread waiting for a mutex. More...
 
template<typename F >
bool sync_array_detect_rwlock_deadlock (sync_cell_t *cell, sync_array_t *arr, const size_t depth, F &&conflicts)
 
static bool sync_array_detect_deadlock_low (sync_array_t *arr, sync_cell_t *cell, size_t depth)
 
static bool sync_arr_cell_can_wake_up (sync_cell_t *cell)
 Determines if we can wake up the thread waiting for a semaphore. More...
 
void sync_array_object_signalled ()
 Increments the signalled count. More...
 
static void sync_array_wake_threads_if_sema_free_low (sync_array_t *arr)
 If the wakeup algorithm does not work perfectly at semaphore releases, this function will do the waking (see the comment in mutex_exit). More...
 
void sync_arr_wake_threads_if_sema_free (void)
 If the wakeup algorithm does not work perfectly at semaphore releases, this function will do the waking (see the comment in mutex_exit). More...
 
static bool sync_array_print_long_waits_low (sync_array_t *arr, std::thread::id *waiter, const void **sema, bool *noticed)
 Prints warnings of long semaphore waits to stderr. More...
 
bool sync_array_print_long_waits (std::thread::id *waiter, const void **sema)
 Prints warnings of long semaphore waits to stderr. More...
 
static void sync_array_print_info_low (FILE *file, sync_array_t *arr)
 Prints info of the wait array. More...
 
static void sync_array_print_info (FILE *file, sync_array_t *arr)
 Prints info of the wait array. More...
 
void sync_array_init (ulint n_threads)
 Create the primary system wait array(s), they are protected by an OS mutex. More...
 
void sync_array_close (void)
 Close sync array wait sub-system. More...
 
void sync_array_print (FILE *file)
 Print info about the sync array(s). More...
 

Variables

ulong srv_sync_array_size = 1
 User configured sync array size. More...
 
ulint sync_array_size
 Locally stored copy of srv_sync_array_size. More...
 
sync_array_t ** sync_wait_array
 The global array of wait cells for implementation of the database's own mutexes and read-write locks. More...
 
static ulint sg_count
 count of how many times an object has been signalled More...
 

Detailed Description

The wait array used in synchronization primitives.

Created 9/5/1995 Heikki Tuuri

Macro Definition Documentation

◆ sync_array_enter

#define sync_array_enter (   a)    mutex_enter(&(a)->mutex)

◆ sync_array_exit

#define sync_array_exit (   a)    mutex_exit(&(a)->mutex)

Function Documentation

◆ sync_arr_cell_can_wake_up()

static bool sync_arr_cell_can_wake_up ( sync_cell_t cell)
static

Determines if we can wake up the thread waiting for a semaphore.

Parameters
cellin: cell to search

◆ sync_arr_wake_threads_if_sema_free()

void sync_arr_wake_threads_if_sema_free ( void  )

If the wakeup algorithm does not work perfectly at semaphore releases, this function will do the waking (see the comment in mutex_exit).

This function should be called about every 1 second in the server.

Note that there's a race condition between this thread and mutex_exit changing the lock_word and calling signal_object, so sometimes this finds threads to wake up even when nothing has gone wrong.

◆ sync_array_cell_print()

void sync_array_cell_print ( FILE *  file,
const sync_cell_t cell 
)

Reports info of a wait array cell into a file.

Parameters
[in]fileFile where to print.
[in]cellSync array cell to report.

◆ sync_array_close()

void sync_array_close ( void  )

Close sync array wait sub-system.

◆ sync_array_deadlock_step()

static bool sync_array_deadlock_step ( sync_array_t arr,
std::thread::id  thread,
size_t  depth 
)
static

Recursion step for deadlock detection.

Parameters
[in]arrThe wait array we limit our search for cycle to. The caller must own the arr->mutex.
[in]threadThe thread which blocking other threads, which we want to find in the arr, to know if and why it's blocked, too
[in]depthThe recursion depth
Returns
true iff deadlock detected (there might be false negatives)

◆ sync_array_detect_deadlock() [1/2]

void sync_array_detect_deadlock ( )

◆ sync_array_detect_deadlock() [2/2]

static bool sync_array_detect_deadlock ( sync_array_t arr,
sync_cell_t cell,
size_t  depth 
)
static

Detects a deadlock of one or more threads because of waits of semaphores.

Reports a fatal error (and thus does not return) in case it finds one. The return value is only used in recursive calls (depth>0).

Parameters
[in]arrThe wait array we limit our search for cycle to. The caller must own the arr->mutex.
[in]cellThe cell to check
[in]depthThe recursion depth
Returns
true iff deadlock detected (there might be false negatives)

◆ sync_array_detect_deadlock_low()

static bool sync_array_detect_deadlock_low ( sync_array_t arr,
sync_cell_t cell,
size_t  depth 
)
static

◆ sync_array_detect_mutex_deadlock()

template<typename Mutex >
static bool sync_array_detect_mutex_deadlock ( const Mutex *  mutex,
sync_array_t arr,
sync_cell_t cell,
size_t  depth 
)
static

A helper for sync_array_detect_deadlock() to handle the case when the cell contains a thread waiting for a mutex.

Parameters
[in]mutexthe mutex to check
[in]arrwait array; NOTE! the caller must own the mutex to array
[in]cellthe cell which contains the mutex
[in]depthrecursion depth

◆ sync_array_detect_rwlock_deadlock()

template<typename F >
bool sync_array_detect_rwlock_deadlock ( sync_cell_t cell,
sync_array_t arr,
const size_t  depth,
F &&  conflicts 
)

◆ sync_array_find_thread()

static sync_cell_t * sync_array_find_thread ( sync_array_t arr,
std::thread::id  thread 
)
static

Looks for a cell with the given thread id.

Returns
pointer to cell or NULL if not found
Parameters
arrin: wait array
threadin: thread id

◆ sync_array_free()

static void sync_array_free ( sync_array_t arr)
static

Frees the resources in a wait array.

Parameters
arrin, own: sync wait array

◆ sync_array_free_cell()

void sync_array_free_cell ( sync_array_t arr,
sync_cell_t *&  cell 
)

Frees the cell.

NOTE! sync_array_wait_event frees the cell automatically!

Parameters
arrin: wait array
cellin/out: the cell in the array

◆ sync_array_get_nth_cell()

sync_cell_t * sync_array_get_nth_cell ( sync_array_t arr,
ulint  n 
)

Gets the nth cell in array.

Parameters
[in]arrSync array to get cell from.
[in]nIndex of cell to retrieve.
Returns
cell

◆ sync_array_init()

void sync_array_init ( ulint  n_threads)

Create the primary system wait array(s), they are protected by an OS mutex.

in: Number of slots to create

Parameters
n_threadsin: Number of slots to create in all arrays

◆ sync_array_mutex_print()

template<typename Mutex >
static void sync_array_mutex_print ( FILE *  file,
const Mutex *  mutex 
)
static

Reports info about a mutex (seen locked a moment ago) into a file.

Parameters
[in]fileFile where to print.
[in]mutexThe mutex to describe.

◆ sync_array_object_signalled()

void sync_array_object_signalled ( )

Increments the signalled count.

Note that one of the wait objects was signalled.

◆ sync_array_print()

void sync_array_print ( FILE *  file)

Print info about the sync array(s).

Prints info of the wait array.

Parameters
filein/out: Print to this stream

◆ sync_array_print_info()

static void sync_array_print_info ( FILE *  file,
sync_array_t arr 
)
static

Prints info of the wait array.

Parameters
filein: file where to print
arrin: wait array

◆ sync_array_print_info_low()

static void sync_array_print_info_low ( FILE *  file,
sync_array_t arr 
)
static

Prints info of the wait array.

Parameters
filein: file where to print
arrin: wait array

◆ sync_array_print_long_waits()

bool sync_array_print_long_waits ( std::thread::id waiter,
const void **  sema 
)

Prints warnings of long semaphore waits to stderr.

Returns
true if fatal semaphore wait threshold was exceeded
Parameters
waiterout: longest waiting thread
semaout: longest-waited-for semaphore

◆ sync_array_print_long_waits_low()

static bool sync_array_print_long_waits_low ( sync_array_t arr,
std::thread::id waiter,
const void **  sema,
bool *  noticed 
)
static

Prints warnings of long semaphore waits to stderr.

Returns
true if fatal semaphore wait threshold was exceeded
Parameters
arrin: sync array instance
waiterout: longest waiting thread
semaout: longest-waited-for semaphore
noticedout: true if long wait noticed

◆ sync_array_reserve_cell()

sync_cell_t * sync_array_reserve_cell ( sync_array_t arr,
void *  object,
ulint  type,
ut::Location  location 
)

Reserves a wait array cell for waiting for an object.

The event of the cell is reset to nonsignalled state.

Parameters
[in]arrwait array
[in]objectpointer to the object to wait for
[in]typelock request type
[in]locationlocation where requested
Returns
sync cell to wait on

◆ sync_array_validate()

static void sync_array_validate ( sync_array_t arr)
static

Validates the integrity of the wait array.

Checks that the number of reserved cells equals the count variable.

Parameters
arrin: sync wait array

◆ sync_array_wait_event()

void sync_array_wait_event ( sync_array_t arr,
sync_cell_t *&  cell 
)

This function should be called when a thread starts to wait on a wait array cell.

In the debug version this function checks if the wait for a semaphore will result in a deadlock, in which case prints info and asserts.

Parameters
arrin: wait array
cellin: index of the reserved cell

◆ sync_array_wake_threads_if_sema_free_low()

static void sync_array_wake_threads_if_sema_free_low ( sync_array_t arr)
static

If the wakeup algorithm does not work perfectly at semaphore releases, this function will do the waking (see the comment in mutex_exit).

This function should be called about every 1 second in the server.

Note that there's a race condition between this thread and mutex_exit changing the lock_word and calling signal_object, so sometimes this finds threads to wake up even when nothing has gone wrong.

◆ sync_cell_get_event()

static os_event_t sync_cell_get_event ( sync_cell_t cell)
static

Returns the event that the thread owning the cell waits for.

Parameters
cellin: non-empty sync array cell

Variable Documentation

◆ sg_count

ulint sg_count
static

count of how many times an object has been signalled

◆ srv_sync_array_size

ulong srv_sync_array_size = 1

User configured sync array size.

◆ sync_array_size

ulint sync_array_size

Locally stored copy of srv_sync_array_size.

◆ sync_wait_array

sync_array_t** sync_wait_array

The global array of wait cells for implementation of the database's own mutexes and read-write locks.