Skip to content

Commit

Permalink
Allocate lock_sys statically
Browse files Browse the repository at this point in the history
There is only one lock_sys. Allocate it statically in order to avoid
dereferencing a pointer whenever accessing it. Also, align some
members to their own cache line in order to avoid false sharing.

lock_sys_t::create(): The deferred constructor.

lock_sys_t::close(): The early destructor.
  • Loading branch information
Sergey Vojtovich authored and dr-m committed Feb 23, 2018
1 parent 59dd046 commit 131d9a5
Show file tree
Hide file tree
Showing 21 changed files with 248 additions and 240 deletions.
2 changes: 0 additions & 2 deletions extra/mariabackup/xtrabackup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3672,8 +3672,6 @@ xtrabackup_backup_func()
"innodb_redo_log", SRV_LOG_SPACE_FIRST_ID, 0,
FIL_TYPE_LOG, NULL);

lock_sys_create(srv_lock_table_size);

for (i = 0; i < srv_n_log_files; i++) {
err = open_or_create_log_file(space, &log_file_created, i);
if (err != DB_SUCCESS) {
Expand Down
6 changes: 3 additions & 3 deletions storage/innobase/btr/btr0btr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3675,7 +3675,7 @@ btr_lift_page_up(
if (dict_index_is_spatial(index)) {
lock_mutex_enter();
lock_prdt_page_free_from_discard(
block, lock_sys->prdt_page_hash);
block, lock_sys.prdt_page_hash);
lock_mutex_exit();
}
lock_update_copy_and_discard(father_block, block);
Expand Down Expand Up @@ -3968,7 +3968,7 @@ btr_compress(
/* No GAP lock needs to be worrying about */
lock_mutex_enter();
lock_prdt_page_free_from_discard(
block, lock_sys->prdt_page_hash);
block, lock_sys.prdt_page_hash);
lock_rec_free_all_from_discard_page(block);
lock_mutex_exit();
} else {
Expand Down Expand Up @@ -4126,7 +4126,7 @@ btr_compress(
}
lock_mutex_enter();
lock_prdt_page_free_from_discard(
block, lock_sys->prdt_page_hash);
block, lock_sys.prdt_page_hash);
lock_rec_free_all_from_discard_page(block);
lock_mutex_exit();
} else {
Expand Down
2 changes: 1 addition & 1 deletion storage/innobase/buf/buf0buf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3058,7 +3058,7 @@ buf_pool_resize()

/* normalize lock_sys */
srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE);
lock_sys_resize(srv_lock_table_size);
lock_sys.resize(srv_lock_table_size);

/* normalize btr_search_sys */
btr_search_sys_resize(
Expand Down
4 changes: 2 additions & 2 deletions storage/innobase/gis/gis0sea.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1255,8 +1255,8 @@ rtr_check_discard_page(
mutex_exit(&index->rtr_track->rtr_active_mutex);

lock_mutex_enter();
lock_prdt_page_free_from_discard(block, lock_sys->prdt_hash);
lock_prdt_page_free_from_discard(block, lock_sys->prdt_page_hash);
lock_prdt_page_free_from_discard(block, lock_sys.prdt_hash);
lock_prdt_page_free_from_discard(block, lock_sys.prdt_page_hash);
lock_mutex_exit();
}

Expand Down
6 changes: 3 additions & 3 deletions storage/innobase/include/dict0mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -1908,7 +1908,7 @@ struct dict_table_t {
ulong n_waiting_or_granted_auto_inc_locks;

/** The transaction that currently holds the the AUTOINC lock on this
table. Protected by lock_sys->mutex. */
table. Protected by lock_sys.mutex. */
const trx_t* autoinc_trx;

/* @} */
Expand All @@ -1923,7 +1923,7 @@ struct dict_table_t {

/** Count of the number of record locks on this table. We use this to
determine whether we can evict the table from the dictionary cache.
It is protected by lock_sys->mutex. */
It is protected by lock_sys.mutex. */
ulint n_rec_locks;

#ifndef DBUG_ASSERT_EXISTS
Expand All @@ -1935,7 +1935,7 @@ struct dict_table_t {
ulint n_ref_count;

public:
/** List of locks on the table. Protected by lock_sys->mutex. */
/** List of locks on the table. Protected by lock_sys.mutex. */
table_lock_list_t locks;

/** Timestamp of the last modification of this table. */
Expand Down
100 changes: 58 additions & 42 deletions storage/innobase/include/lock0lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,23 +65,6 @@ ulint
lock_get_size(void);
/*===============*/
/*********************************************************************//**
Creates the lock system at database start. */
void
lock_sys_create(
/*============*/
ulint n_cells); /*!< in: number of slots in lock hash table */
/** Resize the lock hash table.
@param[in] n_cells number of slots in lock hash table */
void
lock_sys_resize(
ulint n_cells);

/*********************************************************************//**
Closes the lock system at database shutdown. */
void
lock_sys_close(void);
/*================*/
/*********************************************************************//**
Gets the heap_no of the smallest user record on a page.
@return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */
UNIV_INLINE
Expand Down Expand Up @@ -605,7 +588,7 @@ lock_print_info_all_transactions(
Return approximate number or record locks (bits set in the bitmap) for
this transaction. Since delete-marked records may be removed, the
record count will not be precise.
The caller must be holding lock_sys->mutex. */
The caller must be holding lock_sys.mutex. */
ulint
lock_number_of_rows_locked(
/*=======================*/
Expand All @@ -614,7 +597,7 @@ lock_number_of_rows_locked(

/*********************************************************************//**
Return the number of table locks for a transaction.
The caller must be holding lock_sys->mutex. */
The caller must be holding lock_sys.mutex. */
ulint
lock_number_of_tables_locked(
/*=========================*/
Expand Down Expand Up @@ -897,11 +880,12 @@ struct lock_op_t{
typedef ib_mutex_t LockMutex;

/** The lock system struct */
struct lock_sys_t{
char pad1[CACHE_LINE_SIZE]; /*!< padding to prevent other
memory update hotspots from
residing on the same memory
cache line */
class lock_sys_t
{
bool m_initialised;

public:
MY_ALIGNED(CACHE_LINE_SIZE)
LockMutex mutex; /*!< Mutex protecting the
locks */
hash_table_t* rec_hash; /*!< hash table of the record
Expand All @@ -911,13 +895,13 @@ struct lock_sys_t{
hash_table_t* prdt_page_hash; /*!< hash table of the page
lock */

char pad2[CACHE_LINE_SIZE]; /*!< Padding */
MY_ALIGNED(CACHE_LINE_SIZE)
LockMutex wait_mutex; /*!< Mutex protecting the
next two fields */
srv_slot_t* waiting_threads; /*!< Array of user threads
suspended while waiting for
locks within InnoDB, protected
by the lock_sys->wait_mutex;
by the lock_sys.wait_mutex;
os_event_set() and
os_event_reset() on
waiting_threads[]->event
Expand All @@ -926,7 +910,7 @@ struct lock_sys_t{
srv_slot_t* last_slot; /*!< highest slot ever used
in the waiting_threads array,
protected by
lock_sys->wait_mutex */
lock_sys.wait_mutex */

ulint n_lock_max_wait_time; /*!< Max wait time */

Expand All @@ -938,6 +922,38 @@ struct lock_sys_t{

bool timeout_thread_active; /*!< True if the timeout thread
is running */


/**
Constructor.
Some members may require late initialisation, thus we just mark object as
uninitialised. Real initialisation happens in create().
*/
lock_sys_t(): m_initialised(false) {}


bool is_initialised() { return m_initialised; }


/**
Creates the lock system at database start.
@param[in] n_cells number of slots in lock hash table
*/
void create(ulint n_cells);


/**
Resize the lock hash table.
@param[in] n_cells number of slots in lock hash table
*/
void resize(ulint n_cells);


/** Closes the lock system at database shutdown. */
void close();
};

/*************************************************************//**
Expand Down Expand Up @@ -982,36 +998,36 @@ lock_rec_trx_wait(
ulint type);

/** The lock system */
extern lock_sys_t* lock_sys;
extern lock_sys_t lock_sys;

/** Test if lock_sys->mutex can be acquired without waiting. */
/** Test if lock_sys.mutex can be acquired without waiting. */
#define lock_mutex_enter_nowait() \
(lock_sys->mutex.trylock(__FILE__, __LINE__))
(lock_sys.mutex.trylock(__FILE__, __LINE__))

/** Test if lock_sys->mutex is owned. */
#define lock_mutex_own() (lock_sys->mutex.is_owned())
/** Test if lock_sys.mutex is owned. */
#define lock_mutex_own() (lock_sys.mutex.is_owned())

/** Acquire the lock_sys->mutex. */
/** Acquire the lock_sys.mutex. */
#define lock_mutex_enter() do { \
mutex_enter(&lock_sys->mutex); \
mutex_enter(&lock_sys.mutex); \
} while (0)

/** Release the lock_sys->mutex. */
/** Release the lock_sys.mutex. */
#define lock_mutex_exit() do { \
lock_sys->mutex.exit(); \
lock_sys.mutex.exit(); \
} while (0)

/** Test if lock_sys->wait_mutex is owned. */
#define lock_wait_mutex_own() (lock_sys->wait_mutex.is_owned())
/** Test if lock_sys.wait_mutex is owned. */
#define lock_wait_mutex_own() (lock_sys.wait_mutex.is_owned())

/** Acquire the lock_sys->wait_mutex. */
/** Acquire the lock_sys.wait_mutex. */
#define lock_wait_mutex_enter() do { \
mutex_enter(&lock_sys->wait_mutex); \
mutex_enter(&lock_sys.wait_mutex); \
} while (0)

/** Release the lock_sys->wait_mutex. */
/** Release the lock_sys.wait_mutex. */
#define lock_wait_mutex_exit() do { \
lock_sys->wait_mutex.exit(); \
lock_sys.wait_mutex.exit(); \
} while (0)

#ifdef WITH_WSREP
Expand Down
8 changes: 4 additions & 4 deletions storage/innobase/include/lock0lock.ic
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ lock_rec_hash(
ulint page_no)/*!< in: page number */
{
return(unsigned(hash_calc_hash(lock_rec_fold(space, page_no),
lock_sys->rec_hash)));
lock_sys.rec_hash)));
}

/*********************************************************************//**
Expand Down Expand Up @@ -99,11 +99,11 @@ lock_hash_get(
ulint mode) /*!< in: lock mode */
{
if (mode & LOCK_PREDICATE) {
return(lock_sys->prdt_hash);
return(lock_sys.prdt_hash);
} else if (mode & LOCK_PRDT_PAGE) {
return(lock_sys->prdt_page_hash);
return(lock_sys.prdt_page_hash);
} else {
return(lock_sys->rec_hash);
return(lock_sys.rec_hash);
}
}

2 changes: 1 addition & 1 deletion storage/innobase/include/lock0priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ operator<<(std::ostream& out, const lock_rec_t& lock)
return(lock.print(out));
}

/** Lock struct; protected by lock_sys->mutex */
/** Lock struct; protected by lock_sys.mutex */
struct lock_t {
trx_t* trx; /*!< transaction owning the
lock */
Expand Down
1 change: 0 additions & 1 deletion storage/innobase/include/lock0types.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ Created 5/7/1996 Heikki Tuuri
#define lock_t ib_lock_t

struct lock_t;
struct lock_sys_t;
struct lock_table_t;

/* Basic lock modes */
Expand Down
4 changes: 2 additions & 2 deletions storage/innobase/include/trx0sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -590,10 +590,10 @@ class rw_trx_hash_t
the transaction may get committed before this method returns.
With do_ref_count == false the caller may dereference returned trx pointer
only if lock_sys->mutex was acquired before calling find().
only if lock_sys.mutex was acquired before calling find().
With do_ref_count == true caller may dereference trx even if it is not
holding lock_sys->mutex. Caller is responsible for calling
holding lock_sys.mutex. Caller is responsible for calling
trx->release_reference() when it is done playing with trx.
Ideally this method should get caller rw_trx_hash_pins along with trx
Expand Down
Loading

0 comments on commit 131d9a5

Please sign in to comment.