summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2018-07-05 00:07:55 +0530
committerMarko Mäkelä <marko.makela@mariadb.com>2018-07-05 15:47:51 +0300
commitd897b4dc253d00f14c9b0b3bb94a99aadb358f6c (patch)
tree15433f2118c31af87e6b71183ead0b47035844c1
parentfdb9e66feea4ee3a8769bff74277f76e49734fc8 (diff)
downloadmariadb-git-d897b4dc253d00f14c9b0b3bb94a99aadb358f6c.tar.gz
MDEV-15855: Use atomics for dict_table_t::n_ref_count
Make dict_table_t::n_ref_count private, and protect it with a combination of dict_sys->mutex and atomics. We want to be able to invoke dict_table_t::release() without holding dict_sys->mutex.
-rw-r--r--storage/innobase/btr/btr0sea.cc2
-rw-r--r--storage/innobase/dict/dict0dict.cc4
-rw-r--r--storage/innobase/handler/ha_innodb.cc4
-rw-r--r--storage/innobase/include/dict0dict.ic19
-rw-r--r--storage/innobase/include/dict0mem.h10
-rw-r--r--storage/innobase/lock/lock0lock.cc4
6 files changed, 18 insertions, 25 deletions
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index 278062afa78..7419ed2bfd5 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -1337,7 +1337,7 @@ void btr_search_drop_page_hash_when_freed(const page_id_t& page_id)
/* In all our callers, the table handle should
be open, or we should be in the process of
dropping the table (preventing eviction). */
- ut_ad(index->table->n_ref_count > 0
+ ut_ad(index->table->get_ref_count() > 0
|| mutex_own(&dict_sys->mutex));
btr_search_drop_page_hash_index(block);
}
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index c4b88cbea56..8dc29863367 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -423,7 +423,7 @@ dict_table_try_drop_aborted(
dict_table_t* table, /*!< in: table, or NULL if it
needs to be looked up again */
table_id_t table_id, /*!< in: table identifier */
- ulint ref_count) /*!< in: expected table->n_ref_count */
+ int32 ref_count) /*!< in: expected table->n_ref_count */
{
trx_t* trx;
@@ -1353,7 +1353,7 @@ static
ibool
dict_table_can_be_evicted(
/*======================*/
- const dict_table_t* table) /*!< in: table to test */
+ dict_table_t* table) /*!< in: table to test */
{
ut_ad(mutex_own(&dict_sys->mutex));
ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 198255a30ef..7cba4ef5794 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -3058,7 +3058,7 @@ ha_innobase::update_thd(
m_user_thd, thd));
/* The table should have been opened in ha_innobase::open(). */
- DBUG_ASSERT(m_prebuilt->table->n_ref_count > 0);
+ DBUG_ASSERT(m_prebuilt->table->get_ref_count() > 0);
trx_t* trx = check_trx_exists(thd);
@@ -14186,7 +14186,7 @@ ha_innobase::info_low(
m_prebuilt->trx->op_info = "returning various info to MariaDB";
ib_table = m_prebuilt->table;
- DBUG_ASSERT(ib_table->n_ref_count > 0);
+ DBUG_ASSERT(ib_table->get_ref_count() > 0);
if (flag & HA_STATUS_TIME) {
if (is_analyze || innobase_stats_on_metadata) {
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index ca2ea769612..fe2f8e32b1a 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -1498,23 +1498,13 @@ dict_table_is_file_per_table(
return !is_system_tablespace(table->space);
}
-/** Get reference count.
-@return current value of n_ref_count */
-inline
-ulint
-dict_table_t::get_ref_count() const
-{
- ut_ad(mutex_own(&dict_sys->mutex));
- return(n_ref_count);
-}
-
/** Acquire the table handle. */
inline
void
dict_table_t::acquire()
{
ut_ad(mutex_own(&dict_sys->mutex));
- ++n_ref_count;
+ my_atomic_add32_explicit(&n_ref_count, 1, MY_MEMORY_ORDER_RELAXED);
}
/** Release the table handle.
@@ -1523,9 +1513,10 @@ inline
bool
dict_table_t::release()
{
- ut_ad(mutex_own(&dict_sys->mutex));
- ut_ad(n_ref_count > 0);
- return !--n_ref_count;
+ int32 n = my_atomic_add32_explicit(
+ &n_ref_count, -1, MY_MEMORY_ORDER_RELAXED);
+ ut_ad(n > 0);
+ return n == 1;
}
/** Encode the number of columns and number of virtual columns in a
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 56f695f305d..02561176706 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -1357,7 +1357,11 @@ struct dict_table_t {
/** Get reference count.
@return current value of n_ref_count */
- inline ulint get_ref_count() const;
+ inline int32 get_ref_count()
+ {
+ return my_atomic_load32_explicit(&n_ref_count,
+ MY_MEMORY_ORDER_RELAXED);
+ }
/** Acquire the table handle. */
inline void acquire();
@@ -1737,13 +1741,11 @@ struct dict_table_t {
It is protected by lock_sys->mutex. */
ulint n_rec_locks;
-#ifndef UNIV_DEBUG
private:
-#endif
/** Count of how many handles are opened to this table. Dropping of the
table is NOT allowed until this count gets to zero. MySQL does NOT
itself check the number of open handles at DROP. */
- ulint n_ref_count;
+ int32 n_ref_count;
public:
/** List of locks on the table. Protected by lock_sys->mutex. */
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index ee0dc5a9000..1ce798fcd43 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -1493,7 +1493,7 @@ lock_rec_create_low(
lock_rec_bitmap_reset(lock);
lock_rec_set_nth_bit(lock, heap_no);
index->table->n_rec_locks++;
- ut_ad(index->table->n_ref_count > 0 || !index->table->can_be_evicted);
+ ut_ad(index->table->get_ref_count() > 0 || !index->table->can_be_evicted);
#ifdef WITH_WSREP
if (c_lock && wsrep_on_trx(trx)
@@ -3664,7 +3664,7 @@ lock_table_create(
lock->un_member.tab_lock.table = table;
- ut_ad(table->n_ref_count > 0 || !table->can_be_evicted);
+ ut_ad(table->get_ref_count() > 0 || !table->can_be_evicted);
UT_LIST_ADD_LAST(trx->lock.trx_locks, lock);