From 7037ade3bd5259d71234cdc1918162e7541106da Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 27 Feb 2018 17:12:46 +0530 Subject: MDEV-15053 Split buf_pool_t::mutex Used atomic operations for - srv_buf_pool_old_size - srv_buf_pool_size - srv_buf_pool_curr_size - srv_buf_pool_base_size - buf_pool_t::buddy_stat[].used - buf_pool_t::curr_size - buf_pool_t::n_chunks_new --- include/atomic/gcc_builtins.h | 1 + include/my_atomic.h | 2 ++ storage/innobase/btr/btr0sea.cc | 4 ++++ storage/innobase/buf/buf0buf.cc | 32 +++++++++++++++++++++++--------- storage/innobase/buf/buf0lru.cc | 17 +++++++++++++---- storage/innobase/buf/buf0rea.cc | 14 +++++++++----- storage/innobase/handler/ha_innodb.cc | 7 ++++++- storage/innobase/include/sync0types.h | 14 ++++++++++++++ 8 files changed, 72 insertions(+), 19 deletions(-) diff --git a/include/atomic/gcc_builtins.h b/include/atomic/gcc_builtins.h index e2c3b10c267..05b90d30d18 100644 --- a/include/atomic/gcc_builtins.h +++ b/include/atomic/gcc_builtins.h @@ -38,6 +38,7 @@ #define my_atomic_add32_explicit(P, A, O) __atomic_fetch_add((P), (A), (O)) #define my_atomic_add64_explicit(P, A, O) __atomic_fetch_add((P), (A), (O)) +#define my_atomic_addptr_explicit(P, A, O) __atomic_fetch_add((P), (A), (O)) #define my_atomic_cas32_weak_explicit(P, E, D, S, F) \ __atomic_compare_exchange_n((P), (E), (D), 1, (S), (F)) diff --git a/include/my_atomic.h b/include/my_atomic.h index 1f5d85fcf12..b42ef936757 100644 --- a/include/my_atomic.h +++ b/include/my_atomic.h @@ -121,6 +121,7 @@ #define my_atomic_loadlong(A) my_atomic_load32((int32*) (A)) #define my_atomic_loadlong_explicit(A,O) my_atomic_load32_explicit((int32*) (A), (O)) #define my_atomic_storelong(A,B) my_atomic_store32((int32*) (A), (B)) +#define my_atomic_storelong_explicit(A,B,O) my_atomic_store32_explicit((int32*) (A), (B), (O)) #define my_atomic_faslong(A,B) my_atomic_fas32((int32*) (A), (B)) #define my_atomic_caslong(A,B,C) my_atomic_cas32((int32*) (A), (int32*) (B), (C)) #else @@ -128,6 +129,7 @@ #define my_atomic_loadlong(A) my_atomic_load64((int64*) (A)) #define my_atomic_loadlong_explicit(A,O) my_atomic_load64_explicit((int64*) (A), (O)) #define my_atomic_storelong(A,B) my_atomic_store64((int64*) (A), (B)) +#define my_atomic_storelong_explicit(A,B,O) my_atomic_store64_explicit((int64*) (A),(B), (O)) #define my_atomic_faslong(A,B) my_atomic_fas64((int64*) (A), (B)) #define my_atomic_caslong(A,B,C) my_atomic_cas64((int64*) (A), (int64*) (B), (C)) #endif diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index c6b1ec3a66d..98967b1451f 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -409,6 +409,10 @@ btr_search_disable( void btr_search_enable() { + my_atomic_loadlint_explicit(&srv_buf_pool_old_size, + MY_MEMORY_ORDER_ACQUIRE); + my_atomic_loadlint_explicit(&srv_buf_pool_size, + MY_MEMORY_ORDER_RELAXED); if (srv_buf_pool_old_size != srv_buf_pool_size) { return; } diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 14e089c889e..8a81fa57081 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -1733,9 +1733,12 @@ buf_pool_set_sizes(void) curr_size += buf_pool->curr_pool_size; } - srv_buf_pool_curr_size = curr_size; - srv_buf_pool_old_size = srv_buf_pool_size; - srv_buf_pool_base_size = srv_buf_pool_size; + my_atomic_storelint_explicit(&srv_buf_pool_curr_size, curr_size, + MY_MEMORY_ORDER_RELAXED); + my_atomic_storelint_explicit(&srv_buf_pool_old_size, srv_buf_pool_size, + MY_MEMORY_ORDER_RELAXED); + my_atomic_storelint_explicit(&srv_buf_pool_base_size, srv_buf_pool_size, + MY_MEMORY_ORDER_RELAXED); } /** Initialize a buffer pool instance. @@ -2645,10 +2648,13 @@ buf_pool_resize() buf_flush_list_mutex_exit(buf_pool); #endif - buf_pool->curr_size = new_instance_size; - - buf_pool->n_chunks_new = new_instance_size * UNIV_PAGE_SIZE - / srv_buf_pool_chunk_unit; + my_atomic_storelint_explicit(&buf_pool->curr_size, + new_instance_size, + MY_MEMORY_ORDER_RELAXED); + my_atomic_storelint_explicit(&buf_pool->n_chunks_new, + (new_instance_size * UNIV_PAGE_SIZE + / srv_buf_pool_chunk_unit), + MY_MEMORY_ORDER_RELEASE); } #ifdef BTR_CUR_HASH_ADAPT @@ -3080,7 +3086,9 @@ calc_buf_pool_size: ib::info() << "Completed to resize buffer pool from " << srv_buf_pool_old_size << " to " << srv_buf_pool_size << "."; - srv_buf_pool_old_size = srv_buf_pool_size; + my_atomic_storelint_explicit(&srv_buf_pool_old_size, + srv_buf_pool_size, + MY_MEMORY_ORDER_RELEASE); } #ifdef BTR_CUR_HASH_ADAPT @@ -3127,6 +3135,11 @@ DECLARE_THREAD(buf_resize_thread)(void*) break; } + my_atomic_loadlint_explicit(&srv_buf_pool_old_size, + MY_MEMORY_ORDER_ACQUIRE); + my_atomic_loadlint_explicit(&srv_buf_pool_size, + MY_MEMORY_ORDER_RELAXED); + if (srv_buf_pool_old_size == srv_buf_pool_size) { std::ostringstream sout; sout << "Size did not change (old size = new size = " @@ -6799,7 +6812,8 @@ buf_get_n_pending_read_ios(void) ulint pend_ios = 0; for (ulint i = 0; i < srv_buf_pool_instances; i++) { - pend_ios += buf_pool_from_array(i)->n_pend_reads; + pend_ios += my_atomic_loadlint( + &buf_pool_from_array(i)->n_pend_reads); } return(pend_ios); diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index 984bc783f35..f51290c4a9c 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -1176,7 +1176,10 @@ loop: MONITOR_INC( MONITOR_LRU_GET_FREE_LOOPS ); freed = false; - if (buf_pool->try_LRU_scan || n_iterations > 0) { + + if (my_atomic_loadptr_explicit(&buf_pool->try_LRU_scan, + MY_MEMORY_ORDER_ACQUIRE) + || n_iterations > 0) { /* If no block was in the free list, search from the end of the LRU list and try to free a block there. If we are doing for the first time we'll scan only @@ -1190,8 +1193,9 @@ loop: in scanning the LRU list. This flag is set to TRUE again when we flush a batch from this buffer pool. */ - buf_pool->try_LRU_scan = FALSE; - + my_atomic_storeptr_explicit( + &buf_pool->try_LRU_scan, + FALSE, MY_MEMORY_ORDER_RELEASE); /* Also tell the page_cleaner thread that there is work for it to do. */ os_event_set(buf_flush_event); @@ -2361,6 +2365,8 @@ buf_LRU_stat_update(void) /* Update the index. */ item = &buf_LRU_stat_arr[buf_LRU_stat_arr_ind]; + my_atomic_addptr_explicit(&buf_LRU_stat_arr_ind, 1, + MY_MEMORY_ORDER_RELEASE); buf_LRU_stat_arr_ind++; buf_LRU_stat_arr_ind %= BUF_LRU_STAT_N_INTERVAL; @@ -2380,7 +2386,10 @@ buf_LRU_stat_update(void) func_exit: /* Clear the current entry. */ - memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur); + my_atomic_storelint_explicit(&(buf_LRU_stat_cur.io), 0, + MY_MEMORY_ORDER_RELAXED); + my_atomic_storelint_explicit(&(buf_LRU_stat_cur.unzip), 0, + MY_MEMORY_ORDER_RELEASE); } #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc index 6a06b97f5c0..0701a601afd 100644 --- a/storage/innobase/buf/buf0rea.cc +++ b/storage/innobase/buf/buf0rea.cc @@ -621,8 +621,9 @@ buf_read_ahead_linear( return(0); } - if (buf_pool->n_pend_reads - > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) { + if (my_atomic_loadlint(&buf_pool->n_pend_reads) + > (my_atomic_loadlint(&buf_pool->curr_size) + / BUF_READ_AHEAD_PEND_LIMIT)) { return(0); } @@ -871,8 +872,9 @@ tablespace_deleted: buf_pool_t* buf_pool = buf_pool_get(page_id); - while (buf_pool->n_pend_reads - > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) { + while (my_atomic_loadlint(&buf_pool->n_pend_reads) + > ((my_atomic_loadlint(&buf_pool->curr_size) + / BUF_READ_AHEAD_PEND_LIMIT))) { os_thread_sleep(500000); } @@ -942,7 +944,9 @@ buf_read_recv_pages( ulint count = 0; buf_pool = buf_pool_get(cur_page_id); - while (buf_pool->n_pend_reads >= recv_n_pool_free_frames / 2) { + + while (my_atomic_loadlint(&buf_pool->n_pend_reads) + >= (lint) recv_n_pool_free_frames / 2) { os_aio_simulated_wake_handler_threads(); os_thread_sleep(10000); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 8d22144d186..8d3fc5e1c5d 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -21916,6 +21916,10 @@ innodb_buffer_pool_size_validate( } #endif /* UNIV_DEBUG */ + my_atomic_loadlint_explicit(&srv_buf_pool_old_size, + MY_MEMORY_ORDER_ACQUIRE); + my_atomic_loadlint_explicit(&srv_buf_pool_size, + MY_MEMORY_ORDER_RELAXED); if (srv_buf_pool_old_size != srv_buf_pool_size) { my_printf_error(ER_WRONG_ARGUMENTS, @@ -21953,7 +21957,8 @@ innodb_buffer_pool_size_validate( return(0); } - srv_buf_pool_size = requested_buf_pool_size; + my_atomic_storelint_explicit(&srv_buf_pool_size, requested_buf_pool_size, + MY_MEMORY_ORDER_RELEASE); if (intbuf != static_cast(requested_buf_pool_size)) { char buf[64]; diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h index 491e9e94c8b..bd53ee38a11 100644 --- a/storage/innobase/include/sync0types.h +++ b/storage/innobase/include/sync0types.h @@ -1182,14 +1182,28 @@ static inline lint my_atomic_loadlint(const lint *A) return lint(my_atomic_load64((volatile int64*)A)); } +static inline lint my_atomic_loadlint_explicit(const lint *A, int O) +{ + return lint(my_atomic_load64_explicit((volatile int64*)A, O)); +} + static inline void my_atomic_storelint(ulint *A, ulint B) { my_atomic_store64((volatile int64*)A, B); } + +static inline void my_atomic_storelint_explicit(ulint *A, ulint B, int O) +{ + my_atomic_store64_explicit((volatile int64*)A, B, O); +} + #else #define my_atomic_addlint my_atomic_addlong #define my_atomic_loadlint my_atomic_loadlong +#define my_atomic_loadlint_explicit my_atomic_loadlong_explicit #define my_atomic_storelint my_atomic_storelong +#define my_atomic_storelint_explicit my_atomic_storelong_explicit + #endif /** Simple counter aligned to CACHE_LINE_SIZE -- cgit v1.2.1