diff options
author | Sergei Golubchik <serg@mariadb.org> | 2015-01-12 17:03:45 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2015-01-13 10:15:21 +0100 |
commit | e695db0f2d97cbba2832e0f3dc25af5add1f16ac (patch) | |
tree | 7c03822a83a0b16ae513b22659b9ac43068b0411 | |
parent | 1f0ad6c6b3421a815ea6373c66aaf693852342cf (diff) | |
download | mariadb-git-e695db0f2d97cbba2832e0f3dc25af5add1f16ac.tar.gz |
MDEV-7437 remove suport for "atomics" with rwlocks
40 files changed, 143 insertions, 740 deletions
diff --git a/config.h.cmake b/config.h.cmake index eadedb41c01..a82d9d49233 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -473,7 +473,6 @@ #cmakedefine HAVE_SOLARIS_STYLE_GETHOST 1 #cmakedefine MY_ATOMIC_MODE_DUMMY 1 -#cmakedefine MY_ATOMIC_MODE_RWLOCKS 1 #cmakedefine HAVE_GCC_ATOMIC_BUILTINS 1 #cmakedefine HAVE_SOLARIS_ATOMIC 1 #cmakedefine HAVE_DECL_SHM_HUGETLB 1 diff --git a/configure.cmake b/configure.cmake index 5fb86acad70..e0dc4be2783 100644 --- a/configure.cmake +++ b/configure.cmake @@ -964,8 +964,6 @@ MARK_AS_ADVANCED(NO_ALARM) IF(CMAKE_COMPILER_IS_GNUCXX) IF(WITH_ATOMIC_OPS STREQUAL "up") SET(MY_ATOMIC_MODE_DUMMY 1 CACHE BOOL "Assume single-CPU mode, no concurrency") -ELSEIF(WITH_ATOMIC_OPS STREQUAL "rwlocks") - SET(MY_ATOMIC_MODE_RWLOCKS 1 CACHE BOOL "Use pthread rwlocks for atomic ops") ELSEIF(WITH_ATOMIC_OPS STREQUAL "smp") ELSEIF(NOT WITH_ATOMIC_OPS) CHECK_CXX_SOURCE_COMPILES(" @@ -997,12 +995,8 @@ ELSE() ENDIF() ENDIF() -SET(WITH_ATOMIC_OPS "${WITH_ATOMIC_OPS}" CACHE STRING - "Implement atomic operations using pthread rwlocks (rwlocks); or atomic CPU -instructions for multi-processor (smp) or uniprocessor (up) -configuration. By default gcc built-in sync functions are used, -if available and 'smp' configuration otherwise.") -MARK_AS_ADVANCED(WITH_ATOMIC_OPS MY_ATOMIC_MODE_RWLOCK MY_ATOMIC_MODE_DUMMY) +SET(WITH_ATOMIC_OPS "${WITH_ATOMIC_OPS}" CACHE STRING "Implement atomic operations using atomic CPU instructions for multi-processor (smp) or uniprocessor (up) configuration. By default gcc built-in sync functions are used, if available and 'smp' configuration otherwise.") +MARK_AS_ADVANCED(WITH_ATOMIC_OPS MY_ATOMIC_MODE_DUMMY) IF(WITH_VALGRIND) SET(HAVE_valgrind 1) diff --git a/include/atomic/nolock.h b/include/atomic/nolock.h index 56f37644f96..2137445a075 100644 --- a/include/atomic/nolock.h +++ b/include/atomic/nolock.h @@ -51,19 +51,4 @@ # endif #endif -#if defined(make_atomic_cas_body) -/* - Type not used so minimal size (emptry struct has different size between C - and C++, zero-length array is gcc-specific). -*/ -typedef char my_atomic_rwlock_t __attribute__ ((unused)); -#define my_atomic_rwlock_destroy(name) -#define my_atomic_rwlock_init(name) -#define my_atomic_rwlock_rdlock(name) -#define my_atomic_rwlock_wrlock(name) -#define my_atomic_rwlock_rdunlock(name) -#define my_atomic_rwlock_wrunlock(name) - -#endif - #endif /* ATOMIC_NOLOCK_INCLUDED */ diff --git a/include/atomic/rwlock.h b/include/atomic/rwlock.h deleted file mode 100644 index 2ffdd384cc5..00000000000 --- a/include/atomic/rwlock.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef ATOMIC_RWLOCK_INCLUDED -#define ATOMIC_RWLOCK_INCLUDED - -/* Copyright (c) 2006 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -#define MY_ATOMIC_MODE_RWLOCKS 1 - -#ifdef MY_ATOMIC_MODE_DUMMY -/* - the following can never be enabled by ./configure, one need to put #define in - a source to trigger the following warning. The resulting code will be broken, - it only makes sense to do it to see now test_atomic detects broken - implementations (another way is to run a UP build on an SMP box). -*/ -#warning MY_ATOMIC_MODE_DUMMY and MY_ATOMIC_MODE_RWLOCKS are incompatible - -typedef char my_atomic_rwlock_t; - -#define my_atomic_rwlock_destroy(name) -#define my_atomic_rwlock_init(name) -#define my_atomic_rwlock_rdlock(name) -#define my_atomic_rwlock_wrlock(name) -#define my_atomic_rwlock_rdunlock(name) -#define my_atomic_rwlock_wrunlock(name) -#define MY_ATOMIC_MODE "dummy (non-atomic)" -#else /* not MY_ATOMIC_MODE_DUMMY */ - -typedef struct {pthread_mutex_t rw;} my_atomic_rwlock_t; - -#define my_atomic_rwlock_destroy(name) pthread_mutex_destroy(& (name)->rw) -#define my_atomic_rwlock_init(name) pthread_mutex_init(& (name)->rw, 0) -#define my_atomic_rwlock_rdlock(name) pthread_mutex_lock(& (name)->rw) -#define my_atomic_rwlock_wrlock(name) pthread_mutex_lock(& (name)->rw) -#define my_atomic_rwlock_rdunlock(name) pthread_mutex_unlock(& (name)->rw) -#define my_atomic_rwlock_wrunlock(name) pthread_mutex_unlock(& (name)->rw) - -#define MY_ATOMIC_MODE "mutex" -#ifndef MY_ATOMIC_MODE_RWLOCKS -#define MY_ATOMIC_MODE_RWLOCKS 1 -#endif -#endif - -#define make_atomic_add_body(S) int ## S sav; sav= *a; *a+= v; v=sav; -#define make_atomic_fas_body(S) int ## S sav; sav= *a; *a= v; v=sav; -#define make_atomic_cas_body(S) if ((ret= (*a == *cmp))) *a= set; else *cmp=*a; -#define make_atomic_load_body(S) ret= *a; -#define make_atomic_store_body(S) *a= v; - -#endif /* ATOMIC_RWLOCK_INCLUDED */ diff --git a/include/lf.h b/include/lf.h index b776c152ee5..dcd38ed9f6e 100644 --- a/include/lf.h +++ b/include/lf.h @@ -13,53 +13,14 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef _lf_h -#define _lf_h +#ifndef INCLUDE_LF_INCLUDED +#define INCLUDE_LF_INCLUDED #include <my_atomic.h> C_MODE_START /* - Helpers to define both func() and _func(), where - func() is a _func() protected by my_atomic_rwlock_wrlock() -*/ - -#define lock_wrap(f, t, proto_args, args, lock) \ -t _ ## f proto_args; \ -static inline t f proto_args \ -{ \ - t ret; \ - my_atomic_rwlock_wrlock(lock); \ - ret= _ ## f args; \ - my_atomic_rwlock_wrunlock(lock); \ - return ret; \ -} - -#define lock_wrap_void(f, proto_args, args, lock) \ -void _ ## f proto_args; \ -static inline void f proto_args \ -{ \ - my_atomic_rwlock_wrlock(lock); \ - _ ## f args; \ - my_atomic_rwlock_wrunlock(lock); \ -} - -#define nolock_wrap(f, t, proto_args, args) \ -t _ ## f proto_args; \ -static inline t f proto_args \ -{ \ - return _ ## f args; \ -} - -#define nolock_wrap_void(f, proto_args, args) \ -void _ ## f proto_args; \ -static inline void f proto_args \ -{ \ - _ ## f args; \ -} - -/* wait-free dynamic array, see lf_dynarray.c 4 levels of 256 elements each mean 4311810304 elements in an array - it @@ -71,7 +32,6 @@ static inline void f proto_args \ typedef struct { void * volatile level[LF_DYNARRAY_LEVELS]; uint size_of_element; - my_atomic_rwlock_t lock; } LF_DYNARRAY; typedef int (*lf_dynarray_func)(void *, void *); @@ -79,16 +39,9 @@ typedef int (*lf_dynarray_func)(void *, void *); void lf_dynarray_init(LF_DYNARRAY *array, uint element_size); void lf_dynarray_destroy(LF_DYNARRAY *array); -nolock_wrap(lf_dynarray_value, void *, - (LF_DYNARRAY *array, uint idx), - (array, idx)) -lock_wrap(lf_dynarray_lvalue, void *, - (LF_DYNARRAY *array, uint idx), - (array, idx), - &array->lock) -nolock_wrap(lf_dynarray_iterate, int, - (LF_DYNARRAY *array, lf_dynarray_func func, void *arg), - (array, func, arg)) +void *lf_dynarray_value(LF_DYNARRAY *array, uint idx); +void *lf_dynarray_lvalue(LF_DYNARRAY *array, uint idx); +int lf_dynarray_iterate(LF_DYNARRAY *array, lf_dynarray_func func, void *arg); /* pin manager for memory allocator, lf_alloc-pin.c @@ -122,49 +75,25 @@ typedef struct { -sizeof(void *)*(LF_PINBOX_PINS+1)]; } LF_PINS; -/* - shortcut macros to do an atomic_wrlock on a structure that uses pins - (e.g. lf_hash). -*/ -#define lf_rwlock_by_pins(PINS) \ - my_atomic_rwlock_wrlock(&(PINS)->pinbox->pinarray.lock) -#define lf_rwunlock_by_pins(PINS) \ - my_atomic_rwlock_wrunlock(&(PINS)->pinbox->pinarray.lock) - /* compile-time assert to make sure we have enough pins. */ -#define _lf_pin(PINS, PIN, ADDR) \ +#define lf_pin(PINS, PIN, ADDR) \ do { \ compile_time_assert(PIN < LF_PINBOX_PINS); \ my_atomic_storeptr(&(PINS)->pin[PIN], (ADDR)); \ } while(0) -#define _lf_unpin(PINS, PIN) _lf_pin(PINS, PIN, NULL) -#define lf_pin(PINS, PIN, ADDR) \ - do { \ - lf_rwlock_by_pins(PINS); \ - _lf_pin(PINS, PIN, ADDR); \ - lf_rwunlock_by_pins(PINS); \ - } while (0) -#define lf_unpin(PINS, PIN) lf_pin(PINS, PIN, NULL) -#define _lf_assert_pin(PINS, PIN) assert((PINS)->pin[PIN] != 0) -#define _lf_assert_unpin(PINS, PIN) assert((PINS)->pin[PIN] == 0) +#define lf_unpin(PINS, PIN) lf_pin(PINS, PIN, NULL) +#define lf_unpin(PINS, PIN) lf_pin(PINS, PIN, NULL) +#define lf_assert_pin(PINS, PIN) assert((PINS)->pin[PIN] != 0) +#define lf_assert_unpin(PINS, PIN) assert((PINS)->pin[PIN] == 0) void lf_pinbox_init(LF_PINBOX *pinbox, uint free_ptr_offset, lf_pinbox_free_func *free_func, void * free_func_arg); void lf_pinbox_destroy(LF_PINBOX *pinbox); -lock_wrap(lf_pinbox_get_pins, LF_PINS *, - (LF_PINBOX *pinbox), - (pinbox), - &pinbox->pinarray.lock) -lock_wrap_void(lf_pinbox_put_pins, - (LF_PINS *pins), - (pins), - &pins->pinbox->pinarray.lock) -lock_wrap_void(lf_pinbox_free, - (LF_PINS *pins, void *addr), - (pins, addr), - &pins->pinbox->pinarray.lock) +LF_PINS *lf_pinbox_get_pins(LF_PINBOX *pinbox); +void lf_pinbox_put_pins(LF_PINS *pins); +void lf_pinbox_free(LF_PINS *pins, void *addr); /* memory allocator, lf_alloc-pin.c @@ -184,20 +113,14 @@ void lf_alloc_destroy(LF_ALLOCATOR *allocator); uint lf_alloc_pool_count(LF_ALLOCATOR *allocator); /* shortcut macros to access underlying pinbox functions from an LF_ALLOCATOR - see _lf_pinbox_get_pins() and _lf_pinbox_put_pins() + see lf_pinbox_get_pins() and lf_pinbox_put_pins() */ -#define _lf_alloc_free(PINS, PTR) _lf_pinbox_free((PINS), (PTR)) #define lf_alloc_free(PINS, PTR) lf_pinbox_free((PINS), (PTR)) -#define _lf_alloc_get_pins(A) _lf_pinbox_get_pins(&(A)->pinbox) #define lf_alloc_get_pins(A) lf_pinbox_get_pins(&(A)->pinbox) -#define _lf_alloc_put_pins(PINS) _lf_pinbox_put_pins(PINS) #define lf_alloc_put_pins(PINS) lf_pinbox_put_pins(PINS) #define lf_alloc_direct_free(ALLOC, ADDR) my_free((ADDR)) -lock_wrap(lf_alloc_new, void *, - (LF_PINS *pins), - (pins), - &pins->pinbox->pinarray.lock) +void *lf_alloc_new(LF_PINS *pins); C_MODE_END @@ -239,22 +162,15 @@ int lf_hash_iterate(LF_HASH *hash, LF_PINS *pins, my_hash_walk_action action, void *argument); /* shortcut macros to access underlying pinbox functions from an LF_HASH - see _lf_pinbox_get_pins() and _lf_pinbox_put_pins() + see lf_pinbox_get_pins() and lf_pinbox_put_pins() */ -#define _lf_hash_get_pins(HASH) _lf_alloc_get_pins(&(HASH)->alloc) #define lf_hash_get_pins(HASH) lf_alloc_get_pins(&(HASH)->alloc) -#define _lf_hash_put_pins(PINS) _lf_pinbox_put_pins(PINS) #define lf_hash_put_pins(PINS) lf_pinbox_put_pins(PINS) #define lf_hash_search_unpin(PINS) lf_unpin((PINS), 2) /* cleanup */ -#undef lock_wrap_void -#undef lock_wrap -#undef nolock_wrap_void -#undef nolock_wrap - C_MODE_END #endif diff --git a/include/my_atomic.h b/include/my_atomic.h index da075303578..c75b65db38d 100644 --- a/include/my_atomic.h +++ b/include/my_atomic.h @@ -100,20 +100,10 @@ acquire-release operation, and additionally has sequentially-consistent operation ordering. - NOTE This operations are not always atomic, so they always must be - enclosed in my_atomic_rwlock_rdlock(lock)/my_atomic_rwlock_rdunlock(lock) - or my_atomic_rwlock_wrlock(lock)/my_atomic_rwlock_wrunlock(lock). - Hint: if a code block makes intensive use of atomic ops, it make sense - to take/release rwlock once for the whole block, not for every statement. - - On architectures where these operations are really atomic, rwlocks will - be optimized away. 8- and 16-bit atomics aren't implemented for windows (see generic-msvc.h), but can be added, if necessary. */ -#ifndef my_atomic_rwlock_init - #define intptr void * /** Currently we don't support 8-bit and 16-bit operations. @@ -121,16 +111,14 @@ */ #undef MY_ATOMIC_HAS_8_16 -#ifndef MY_ATOMIC_MODE_RWLOCKS /* * Attempt to do atomic ops without locks */ #include "atomic/nolock.h" -#endif #ifndef make_atomic_cas_body /* nolock.h was not able to generate even a CAS function, fall back */ -#include "atomic/rwlock.h" +#error atomic ops for this platform are not implemented #endif /* define missing functions by using the already generated ones */ @@ -340,8 +328,6 @@ make_atomic_store(ptr) #define MY_ATOMIC_NOT_1CPU 1 extern int my_atomic_initialize(); -#endif - #ifdef __ATOMIC_SEQ_CST #define MY_MEMORY_ORDER_RELAXED __ATOMIC_RELAXED #define MY_MEMORY_ORDER_CONSUME __ATOMIC_CONSUME diff --git a/mysys/lf_alloc-pin.c b/mysys/lf_alloc-pin.c index b599b455ff5..f8a15829fb1 100644 --- a/mysys/lf_alloc-pin.c +++ b/mysys/lf_alloc-pin.c @@ -105,7 +105,7 @@ #define LF_PINBOX_MAX_PINS 65536 -static void _lf_pinbox_real_free(LF_PINS *pins); +static void lf_pinbox_real_free(LF_PINS *pins); /* Initialize a pinbox. Normally called from lf_alloc_init. @@ -144,7 +144,7 @@ void lf_pinbox_destroy(LF_PINBOX *pinbox) It is assumed that pins belong to a thread and are not transferable between threads. */ -LF_PINS *_lf_pinbox_get_pins(LF_PINBOX *pinbox) +LF_PINS *lf_pinbox_get_pins(LF_PINBOX *pinbox) { struct st_my_thread_var *var; uint32 pins, next, top_ver; @@ -171,12 +171,12 @@ LF_PINS *_lf_pinbox_get_pins(LF_PINBOX *pinbox) note that the first allocated element has index 1 (pins==1). index 0 is reserved to mean "NULL pointer" */ - el= (LF_PINS *)_lf_dynarray_lvalue(&pinbox->pinarray, pins); + el= (LF_PINS *)lf_dynarray_lvalue(&pinbox->pinarray, pins); if (unlikely(!el)) return 0; break; } - el= (LF_PINS *)_lf_dynarray_value(&pinbox->pinarray, pins); + el= (LF_PINS *)lf_dynarray_value(&pinbox->pinarray, pins); next= el->link; } while (!my_atomic_cas32((int32 volatile*) &pinbox->pinstack_top_ver, (int32*) &top_ver, @@ -206,7 +206,7 @@ LF_PINS *_lf_pinbox_get_pins(LF_PINBOX *pinbox) empty the purgatory (XXX deadlock warning below!), push LF_PINS structure to a stack */ -void _lf_pinbox_put_pins(LF_PINS *pins) +void lf_pinbox_put_pins(LF_PINS *pins) { LF_PINBOX *pinbox= pins->pinbox; uint32 top_ver, nr; @@ -223,19 +223,15 @@ void _lf_pinbox_put_pins(LF_PINS *pins) /* XXX this will deadlock if other threads will wait for - the caller to do something after _lf_pinbox_put_pins(), + the caller to do something after lf_pinbox_put_pins(), and they would have pinned addresses that the caller wants to free. Thus: only free pins when all work is done and nobody can wait for you!!! */ while (pins->purgatory_count) { - _lf_pinbox_real_free(pins); + lf_pinbox_real_free(pins); if (pins->purgatory_count) - { - my_atomic_rwlock_wrunlock(&pins->pinbox->pinarray.lock); pthread_yield(); - my_atomic_rwlock_wrlock(&pins->pinbox->pinarray.lock); - } } top_ver= pinbox->pinstack_top_ver; do @@ -265,14 +261,14 @@ static int ptr_cmp(void **a, void **b) Free an object allocated via pinbox allocator DESCRIPTION - add an object to purgatory. if necessary, call _lf_pinbox_real_free() + add an object to purgatory. if necessary, calllf_pinbox_real_free() to actually free something. */ -void _lf_pinbox_free(LF_PINS *pins, void *addr) +void lf_pinbox_free(LF_PINS *pins, void *addr) { add_to_purgatory(pins, addr); if (pins->purgatory_count % LF_PURGATORY_SIZE == 0) - _lf_pinbox_real_free(pins); + lf_pinbox_real_free(pins); } struct st_harvester { @@ -281,7 +277,7 @@ struct st_harvester { }; /* - callback for _lf_dynarray_iterate: + callback forlf_dynarray_iterate: scan all pins of all threads and accumulate all pins */ static int harvest_pins(LF_PINS *el, struct st_harvester *hv) @@ -308,7 +304,7 @@ static int harvest_pins(LF_PINS *el, struct st_harvester *hv) } /* - callback for _lf_dynarray_iterate: + callback forlf_dynarray_iterate: scan all pins of all threads and see if addr is present there */ static int match_pins(LF_PINS *el, void *addr) @@ -334,7 +330,7 @@ static int match_pins(LF_PINS *el, void *addr) /* Scan the purgatory and free everything that can be freed */ -static void _lf_pinbox_real_free(LF_PINS *pins) +static void lf_pinbox_real_free(LF_PINS *pins) { int npins; void *list; @@ -356,7 +352,7 @@ static void _lf_pinbox_real_free(LF_PINS *pins) hv.granary= addr; hv.npins= npins; /* scan the dynarray and accumulate all pinned addresses */ - _lf_dynarray_iterate(&pinbox->pinarray, + lf_dynarray_iterate(&pinbox->pinarray, (lf_dynarray_func)harvest_pins, &hv); npins= hv.granary-addr; @@ -391,7 +387,7 @@ static void _lf_pinbox_real_free(LF_PINS *pins) } else /* no alloca - no cookie. linear search here */ { - if (_lf_dynarray_iterate(&pinbox->pinarray, + if (lf_dynarray_iterate(&pinbox->pinarray, (lf_dynarray_func)match_pins, cur)) goto found; } @@ -413,7 +409,7 @@ found: /* lock-free memory allocator for fixed-size objects */ /* - callback for _lf_pinbox_real_free to free a list of unpinned objects - + callback forlf_pinbox_real_free to free a list of unpinned objects - add it back to the allocator stack DESCRIPTION @@ -495,7 +491,7 @@ void lf_alloc_destroy(LF_ALLOCATOR *allocator) Pop an unused object from the stack or malloc it is the stack is empty. pin[0] is used, it's removed on return. */ -void *_lf_alloc_new(LF_PINS *pins) +void *lf_alloc_new(LF_PINS *pins) { LF_ALLOCATOR *allocator= (LF_ALLOCATOR *)(pins->pinbox->free_func_arg); uchar *node; @@ -504,7 +500,7 @@ void *_lf_alloc_new(LF_PINS *pins) do { node= allocator->top; - _lf_pin(pins, 0, node); + lf_pin(pins, 0, node); } while (node != allocator->top && LF_BACKOFF); if (!node) { @@ -521,7 +517,7 @@ void *_lf_alloc_new(LF_PINS *pins) (void *)&node, anext_node(node))) break; } - _lf_unpin(pins, 0); + lf_unpin(pins, 0); return node; } diff --git a/mysys/lf_dynarray.c b/mysys/lf_dynarray.c index 16a77c0fa1a..bb6cbcefc49 100644 --- a/mysys/lf_dynarray.c +++ b/mysys/lf_dynarray.c @@ -44,7 +44,6 @@ void lf_dynarray_init(LF_DYNARRAY *array, uint element_size) { bzero(array, sizeof(*array)); array->size_of_element= element_size; - my_atomic_rwlock_init(&array->lock); } static void recursive_free(void **alloc, int level) @@ -68,7 +67,6 @@ void lf_dynarray_destroy(LF_DYNARRAY *array) int i; for (i= 0; i < LF_DYNARRAY_LEVELS; i++) recursive_free(array->level[i], i); - my_atomic_rwlock_destroy(&array->lock); } static const ulong dynarray_idxes_in_prev_levels[LF_DYNARRAY_LEVELS]= @@ -95,7 +93,7 @@ static const ulong dynarray_idxes_in_prev_level[LF_DYNARRAY_LEVELS]= Returns a valid lvalue pointer to the element number 'idx'. Allocates memory if necessary. */ -void *_lf_dynarray_lvalue(LF_DYNARRAY *array, uint idx) +void *lf_dynarray_lvalue(LF_DYNARRAY *array, uint idx) { void * ptr, * volatile * ptr_ptr= 0; int i; @@ -148,7 +146,7 @@ void *_lf_dynarray_lvalue(LF_DYNARRAY *array, uint idx) Returns a pointer to the element number 'idx' or NULL if an element does not exists */ -void *_lf_dynarray_value(LF_DYNARRAY *array, uint idx) +void *lf_dynarray_value(LF_DYNARRAY *array, uint idx) { void * ptr, * volatile * ptr_ptr= 0; int i; @@ -189,14 +187,14 @@ static int recursive_iterate(LF_DYNARRAY *array, void *ptr, int level, DESCRIPTION lf_dynarray consists of a set of arrays, LF_DYNARRAY_LEVEL_LENGTH elements - each. _lf_dynarray_iterate() calls user-supplied function on every array + each. lf_dynarray_iterate() calls user-supplied function on every array from the set. It is the fastest way to scan the array, faster than - for (i=0; i < N; i++) { func(_lf_dynarray_value(dynarray, i)); } + for (i=0; i < N; i++) { func(lf_dynarray_value(dynarray, i)); } NOTE if func() returns non-zero, the scan is aborted */ -int _lf_dynarray_iterate(LF_DYNARRAY *array, lf_dynarray_func func, void *arg) +int lf_dynarray_iterate(LF_DYNARRAY *array, lf_dynarray_func func, void *arg) { int i, res; for (i= 0; i < LF_DYNARRAY_LEVELS; i++) diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c index d487bb9a8c2..b08cdc2b4c6 100644 --- a/mysys/lf_hash.c +++ b/mysys/lf_hash.c @@ -100,7 +100,7 @@ retry: cursor->prev= (intptr *)head; do { /* PTR() isn't necessary below, head is a dummy node */ cursor->curr= (LF_SLIST *)(*cursor->prev); - _lf_pin(pins, 1, cursor->curr); + lf_pin(pins, 1, cursor->curr); } while (*cursor->prev != (intptr)cursor->curr && LF_BACKOFF); for (;;) @@ -115,7 +115,7 @@ retry: do { link= cursor->curr->link; cursor->next= PTR(link); - _lf_pin(pins, 0, cursor->next); + lf_pin(pins, 0, cursor->next); } while (link != cursor->curr->link && LF_BACKOFF); if (!DELETED(link)) @@ -135,7 +135,7 @@ retry: cursor->prev= &(cursor->curr->link); if (!(cur_hashnr & 1)) /* dummy node */ head= (LF_SLIST **)cursor->prev; - _lf_pin(pins, 2, cursor->curr); + lf_pin(pins, 2, cursor->curr); } else { @@ -145,12 +145,12 @@ retry: */ if (my_atomic_casptr((void **) cursor->prev, (void **) &cursor->curr, cursor->next) && LF_BACKOFF) - _lf_alloc_free(pins, cursor->curr); + lf_alloc_free(pins, cursor->curr); else goto retry; } cursor->curr= cursor->next; - _lf_pin(pins, 1, cursor->curr); + lf_pin(pins, 1, cursor->curr); } } @@ -195,9 +195,9 @@ static LF_SLIST *linsert(LF_SLIST * volatile *head, CHARSET_INFO *cs, } } } - _lf_unpin(pins, 0); - _lf_unpin(pins, 1); - _lf_unpin(pins, 2); + lf_unpin(pins, 0); + lf_unpin(pins, 1); + lf_unpin(pins, 2); /* Note that cursor.curr is not pinned here and the pointer is unreliable, the object may dissapear anytime. But if it points to a dummy node, the @@ -242,7 +242,7 @@ static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, /* and remove it from the list */ if (my_atomic_casptr((void **)cursor.prev, (void **)(char*)&cursor.curr, cursor.next)) - _lf_alloc_free(pins, cursor.curr); + lf_alloc_free(pins, cursor.curr); else { /* @@ -258,9 +258,9 @@ static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, } } } - _lf_unpin(pins, 0); - _lf_unpin(pins, 1); - _lf_unpin(pins, 2); + lf_unpin(pins, 0); + lf_unpin(pins, 1); + lf_unpin(pins, 2); return res; } @@ -284,11 +284,11 @@ static LF_SLIST *lsearch(LF_SLIST * volatile *head, CHARSET_INFO *cs, CURSOR cursor; int res= lfind(head, cs, hashnr, key, keylen, &cursor, pins, 0); if (res) - _lf_pin(pins, 2, cursor.curr); + lf_pin(pins, 2, cursor.curr); else - _lf_unpin(pins, 2); - _lf_unpin(pins, 1); - _lf_unpin(pins, 0); + lf_unpin(pins, 2); + lf_unpin(pins, 1); + lf_unpin(pins, 0); return res ? cursor.curr : 0; } @@ -352,7 +352,7 @@ void lf_hash_init(LF_HASH *hash, uint element_size, uint flags, void lf_hash_destroy(LF_HASH *hash) { - LF_SLIST *el, **head= (LF_SLIST **)_lf_dynarray_value(&hash->array, 0); + LF_SLIST *el, **head= (LF_SLIST **)lf_dynarray_value(&hash->array, 0); if (head) { @@ -389,15 +389,14 @@ int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data) int csize, bucket, hashnr; LF_SLIST *node, * volatile *el; - lf_rwlock_by_pins(pins); - node= (LF_SLIST *)_lf_alloc_new(pins); + node= (LF_SLIST *)lf_alloc_new(pins); if (unlikely(!node)) return -1; memcpy(node+1, data, hash->element_size); node->key= hash_key(hash, (uchar *)(node+1), &node->keylen); hashnr= calc_hash(hash, node->key, node->keylen); bucket= hashnr % hash->size; - el= _lf_dynarray_lvalue(&hash->array, bucket); + el= lf_dynarray_lvalue(&hash->array, bucket); if (unlikely(!el)) return -1; if (*el == NULL && unlikely(initialize_bucket(hash, el, bucket, pins))) @@ -405,14 +404,12 @@ int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data) node->hashnr= my_reverse_bits(hashnr) | 1; /* normal node */ if (linsert(el, hash->charset, node, pins, hash->flags)) { - _lf_alloc_free(pins, node); - lf_rwunlock_by_pins(pins); + lf_alloc_free(pins, node); return 1; } csize= hash->size; if ((my_atomic_add32(&hash->count, 1)+1.0) / csize > MAX_LOAD) my_atomic_cas32(&hash->size, &csize, csize*2); - lf_rwunlock_by_pins(pins); return 0; } @@ -432,11 +429,10 @@ int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen) LF_SLIST * volatile *el; uint bucket, hashnr= calc_hash(hash, (uchar *)key, keylen); - lf_rwlock_by_pins(pins); /* hide OOM errors - if we cannot initalize a bucket, try the previous one */ for (bucket= hashnr % hash->size; ;bucket= my_clear_highest_bit(bucket)) { - el= _lf_dynarray_lvalue(&hash->array, bucket); + el= lf_dynarray_lvalue(&hash->array, bucket); if (el && (*el || initialize_bucket(hash, el, bucket, pins) == 0)) break; if (unlikely(bucket == 0)) @@ -445,11 +441,9 @@ int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen) if (ldelete(el, hash->charset, my_reverse_bits(hashnr) | 1, (uchar *)key, keylen, pins)) { - lf_rwunlock_by_pins(pins); return 1; } my_atomic_add32(&hash->count, -1); - lf_rwunlock_by_pins(pins); return 0; } @@ -469,11 +463,10 @@ void *lf_hash_search_using_hash_value(LF_HASH *hash, LF_PINS *pins, LF_SLIST * volatile *el, *found; uint bucket; - lf_rwlock_by_pins(pins); /* hide OOM errors - if we cannot initalize a bucket, try the previous one */ for (bucket= hashnr % hash->size; ;bucket= my_clear_highest_bit(bucket)) { - el= _lf_dynarray_lvalue(&hash->array, bucket); + el= lf_dynarray_lvalue(&hash->array, bucket); if (el && (*el || initialize_bucket(hash, el, bucket, pins) == 0)) break; if (unlikely(bucket == 0)) @@ -481,7 +474,6 @@ void *lf_hash_search_using_hash_value(LF_HASH *hash, LF_PINS *pins, } found= lsearch(el, hash->charset, my_reverse_bits(hashnr) | 1, (uchar *)key, keylen, pins); - lf_rwunlock_by_pins(pins); return found ? found+1 : 0; } @@ -504,8 +496,7 @@ int lf_hash_iterate(LF_HASH *hash, LF_PINS *pins, int res; LF_SLIST * volatile *el; - lf_rwlock_by_pins(pins); - el= _lf_dynarray_lvalue(&hash->array, bucket); + el= lf_dynarray_lvalue(&hash->array, bucket); if (unlikely(!el)) return 0; /* if there's no bucket==0, the hash is empty */ if (*el == NULL && unlikely(initialize_bucket(hash, el, bucket, pins))) @@ -513,10 +504,9 @@ int lf_hash_iterate(LF_HASH *hash, LF_PINS *pins, res= lfind(el, 0, 0, (uchar*)argument, 0, &cursor, pins, action); - _lf_unpin(pins, 2); - _lf_unpin(pins, 1); - _lf_unpin(pins, 0); - lf_rwunlock_by_pins(pins); + lf_unpin(pins, 2); + lf_unpin(pins, 1); + lf_unpin(pins, 0); return res; } @@ -540,7 +530,7 @@ static int initialize_bucket(LF_HASH *hash, LF_SLIST * volatile *node, uint parent= my_clear_highest_bit(bucket); LF_SLIST *dummy= (LF_SLIST *)my_malloc(sizeof(LF_SLIST), MYF(MY_WME)); LF_SLIST **tmp= 0, *cur; - LF_SLIST * volatile *el= _lf_dynarray_lvalue(&hash->array, parent); + LF_SLIST * volatile *el= lf_dynarray_lvalue(&hash->array, parent); if (unlikely(!el || !dummy)) return -1; if (*el == NULL && bucket && diff --git a/mysys/waiting_threads.c b/mysys/waiting_threads.c index 1fe6a0f9a1c..23b4026b8f1 100644 --- a/mysys/waiting_threads.c +++ b/mysys/waiting_threads.c @@ -192,19 +192,12 @@ uint32 wt_wait_stats[WT_WAIT_STATS+1]; uint32 wt_cycle_stats[2][WT_CYCLE_STATS+1]; uint32 wt_success_stats; -static my_atomic_rwlock_t cycle_stats_lock, wait_stats_lock, success_stats_lock; - #ifdef HAVE_PSI_INTERFACE extern PSI_cond_key key_WT_RESOURCE_cond; #endif #ifdef SAFE_STATISTICS -#define incr(VAR, LOCK) \ - do { \ - my_atomic_rwlock_wrlock(&(LOCK)); \ - my_atomic_add32(&(VAR), 1); \ - my_atomic_rwlock_wrunlock(&(LOCK)); \ - } while(0) +#define incr(VAR, LOCK) do { my_atomic_add32(&(VAR), 1); } while(0) #else #define incr(VAR,LOCK) do { (VAR)++; } while(0) #endif @@ -458,9 +451,6 @@ void wt_init() DBUG_ASSERT(i == 0 || wt_wait_table[i-1] != wt_wait_table[i]); } } - my_atomic_rwlock_init(&cycle_stats_lock); - my_atomic_rwlock_init(&success_stats_lock); - my_atomic_rwlock_init(&wait_stats_lock); wt_init_done= 1; DBUG_VOID_RETURN; } @@ -473,9 +463,6 @@ void wt_end() DBUG_ASSERT(reshash.count == 0); lf_hash_destroy(&reshash); - my_atomic_rwlock_destroy(&cycle_stats_lock); - my_atomic_rwlock_destroy(&success_stats_lock); - my_atomic_rwlock_destroy(&wait_stats_lock); reshash.alloc.constructor= NULL; wt_init_done= 0; DBUG_VOID_RETURN; diff --git a/plugin/query_response_time/query_response_time.cc b/plugin/query_response_time/query_response_time.cc index 2c426b0ce5c..10b9391d9da 100644 --- a/plugin/query_response_time/query_response_time.cc +++ b/plugin/query_response_time/query_response_time.cc @@ -149,34 +149,22 @@ class time_collector { public: time_collector(utility& u) : m_utility(&u) - { - my_atomic_rwlock_init(&time_collector_lock); - } + { } ~time_collector() - { - my_atomic_rwlock_destroy(&time_collector_lock); - } + { } uint32 count(uint index) { - my_atomic_rwlock_rdlock(&time_collector_lock); - uint32 result= my_atomic_load32((int32*)&m_count[index]); - my_atomic_rwlock_rdunlock(&time_collector_lock); - return result; + return my_atomic_load32((int32*)&m_count[index]); } uint64 total(uint index) { - my_atomic_rwlock_rdlock(&time_collector_lock); - uint64 result= my_atomic_load64((int64*)&m_total[index]); - my_atomic_rwlock_rdunlock(&time_collector_lock); - return result; + return my_atomic_load64((int64*)&m_total[index]); } public: void flush() { - my_atomic_rwlock_wrlock(&time_collector_lock); memset((void*)&m_count,0,sizeof(m_count)); memset((void*)&m_total,0,sizeof(m_total)); - my_atomic_rwlock_wrunlock(&time_collector_lock); } void collect(uint64 time) { @@ -185,20 +173,14 @@ public: { if(m_utility->bound(i) > time) { - my_atomic_rwlock_wrlock(&time_collector_lock); my_atomic_add32((int32*)(&m_count[i]), 1); my_atomic_add64((int64*)(&m_total[i]), time); - my_atomic_rwlock_wrunlock(&time_collector_lock); break; } } } private: utility* m_utility; - /* The lock for atomic operations on m_count and m_total. Only actually - used on architectures that do not have atomic implementation of atomic - operations. */ - my_atomic_rwlock_t time_collector_lock; uint32 m_count[OVERALL_POWER_COUNT + 1]; uint64 m_total[OVERALL_POWER_COUNT + 1]; }; diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index f2b3a77f414..89a92e95a91 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -134,7 +134,7 @@ post_init_event_thread(THD *thd) return TRUE; } - thread_safe_increment32(&thread_count, &thread_count_lock); + thread_safe_increment32(&thread_count); mysql_mutex_lock(&LOCK_thread_count); threads.append(thd); mysql_mutex_unlock(&LOCK_thread_count); diff --git a/sql/log.cc b/sql/log.cc index bae3a968f6e..e226b593566 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4187,7 +4187,6 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included) included= 1; to_purge_if_included= my_strdup(ir->name, MYF(0)); } - my_atomic_rwlock_destroy(&ir->inuse_relaylog_atomic_lock); my_free(ir); ir= next; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ed1e67d5883..ea53e475192 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -507,11 +507,6 @@ ulonglong query_cache_size=0; ulong query_cache_limit=0; ulong executed_events=0; query_id_t global_query_id; -my_atomic_rwlock_t global_query_id_lock; -my_atomic_rwlock_t thread_running_lock; -my_atomic_rwlock_t thread_count_lock; -my_atomic_rwlock_t statistics_lock; -my_atomic_rwlock_t slave_executed_entries_lock; ulong aborted_threads, aborted_connects; ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size; ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use; @@ -2152,11 +2147,6 @@ void clean_up(bool print_message) /* Tell main we are ready */ logger.cleanup_end(); sys_var_end(); - my_atomic_rwlock_destroy(&global_query_id_lock); - my_atomic_rwlock_destroy(&thread_running_lock); - my_atomic_rwlock_destroy(&thread_count_lock); - my_atomic_rwlock_destroy(&statistics_lock); - my_atomic_rwlock_destroy(&slave_executed_entries_lock); free_charsets(); mysql_mutex_lock(&LOCK_thread_count); DBUG_PRINT("quit", ("got thread count lock")); @@ -2829,7 +2819,7 @@ void delete_running_thd(THD *thd) delete thd; dec_thread_running(); - thread_safe_decrement32(&thread_count, &thread_count_lock); + thread_safe_decrement32(&thread_count); if (!thread_count) { mysql_mutex_lock(&LOCK_thread_count); @@ -2871,7 +2861,7 @@ void unlink_thd(THD *thd) mysql_mutex_unlock(&LOCK_thread_count); delete thd; - thread_safe_decrement32(&thread_count, &thread_count_lock); + thread_safe_decrement32(&thread_count); DBUG_VOID_RETURN; } @@ -6221,7 +6211,7 @@ void create_thread_to_handle_connection(THD *thd) thd->unlink(); mysql_mutex_unlock(&LOCK_thread_count); delete thd; - thread_safe_decrement32(&thread_count, &thread_count_lock); + thread_safe_decrement32(&thread_count); return; /* purecov: end */ } @@ -6275,7 +6265,7 @@ static void create_new_thread(THD *thd) mysql_mutex_unlock(&LOCK_connection_count); - thread_safe_increment32(&thread_count, &thread_count_lock); + thread_safe_increment32(&thread_count); /* Start a new thread to handle connection. */ mysql_mutex_lock(&LOCK_thread_count); @@ -8477,11 +8467,6 @@ static int mysql_init_variables(void) denied_connections= 0; executed_events= 0; global_query_id= thread_id= 1L; - my_atomic_rwlock_init(&global_query_id_lock); - my_atomic_rwlock_init(&thread_running_lock); - my_atomic_rwlock_init(&thread_count_lock); - my_atomic_rwlock_init(&statistics_lock); - my_atomic_rwlock_init(&slave_executed_entries_lock); strmov(server_version, MYSQL_SERVER_VERSION); threads.empty(); thread_cache.empty(); diff --git a/sql/mysqld.h b/sql/mysqld.h index 6bddfc665fa..8bd2759b5d0 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -20,7 +20,7 @@ #include "sql_bitmap.h" /* Bitmap */ #include "my_decimal.h" /* my_decimal */ #include "mysql_com.h" /* SERVER_VERSION_LENGTH */ -#include "my_atomic.h" /* my_atomic_rwlock_t */ +#include "my_atomic.h" #include "mysql/psi/mysql_file.h" /* MYSQL_FILE */ #include "sql_list.h" /* I_List */ #include "sql_cmd.h" @@ -538,8 +538,6 @@ extern mysql_cond_t COND_manager; extern mysql_cond_t COND_slave_init; extern int32 thread_running; extern int32 thread_count; -extern my_atomic_rwlock_t thread_running_lock, thread_count_lock; -extern my_atomic_rwlock_t slave_executed_entries_lock; extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher, *opt_ssl_key, *opt_ssl_crl, *opt_ssl_crlpath; @@ -627,28 +625,18 @@ enum enum_query_type /* query_id */ typedef int64 query_id_t; extern query_id_t global_query_id; -extern my_atomic_rwlock_t global_query_id_lock; -extern my_atomic_rwlock_t statistics_lock; void unireg_end(void) __attribute__((noreturn)); /* increment query_id and return it. */ inline __attribute__((warn_unused_result)) query_id_t next_query_id() { - query_id_t id; - my_atomic_rwlock_wrlock(&global_query_id_lock); - id= my_atomic_add64_explicit(&global_query_id, 1, MY_MEMORY_ORDER_RELAXED); - my_atomic_rwlock_wrunlock(&global_query_id_lock); - return (id); + return my_atomic_add64_explicit(&global_query_id, 1, MY_MEMORY_ORDER_RELAXED); } inline query_id_t get_query_id() { - query_id_t id; - my_atomic_rwlock_wrlock(&global_query_id_lock); - id= my_atomic_load64_explicit(&global_query_id, MY_MEMORY_ORDER_RELAXED); - my_atomic_rwlock_wrunlock(&global_query_id_lock); - return id; + return my_atomic_load64_explicit(&global_query_id, MY_MEMORY_ORDER_RELAXED); } @@ -669,44 +657,34 @@ inline void table_case_convert(char * name, uint length) name, length, name, length); } -inline void thread_safe_increment32(int32 *value, my_atomic_rwlock_t *lock) +inline void thread_safe_increment32(int32 *value) { - my_atomic_rwlock_wrlock(lock); (void) my_atomic_add32_explicit(value, 1, MY_MEMORY_ORDER_RELAXED); - my_atomic_rwlock_wrunlock(lock); } -inline void thread_safe_decrement32(int32 *value, my_atomic_rwlock_t *lock) +inline void thread_safe_decrement32(int32 *value) { - my_atomic_rwlock_wrlock(lock); (void) my_atomic_add32_explicit(value, -1, MY_MEMORY_ORDER_RELAXED); - my_atomic_rwlock_wrunlock(lock); } -inline void thread_safe_increment64(int64 *value, my_atomic_rwlock_t *lock) +inline void thread_safe_increment64(int64 *value) { - my_atomic_rwlock_wrlock(lock); (void) my_atomic_add64_explicit(value, 1, MY_MEMORY_ORDER_RELAXED); - my_atomic_rwlock_wrunlock(lock); } -inline void thread_safe_decrement64(int64 *value, my_atomic_rwlock_t *lock) +inline void thread_safe_decrement64(int64 *value) { - my_atomic_rwlock_wrlock(lock); (void) my_atomic_add64_explicit(value, -1, MY_MEMORY_ORDER_RELAXED); - my_atomic_rwlock_wrunlock(lock); } -inline void -inc_thread_running() +inline void inc_thread_running() { - thread_safe_increment32(&thread_running, &thread_running_lock); + thread_safe_increment32(&thread_running); } -inline void -dec_thread_running() +inline void dec_thread_running() { - thread_safe_decrement32(&thread_running, &thread_running_lock); + thread_safe_decrement32(&thread_running); } void set_server_version(void); diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 89d9289d166..62842810797 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -47,8 +47,7 @@ rpt_handle_event(rpl_parallel_thread::queued_event *qev, /* Mutex will be released in apply_event_and_update_pos(). */ err= apply_event_and_update_pos(ev, thd, rgi, rpt); - thread_safe_increment64(&rli->executed_entries, - &slave_executed_entries_lock); + thread_safe_increment64(&rli->executed_entries); /* ToDo: error handling. */ return err; } @@ -1193,9 +1192,7 @@ rpl_parallel_thread::inuse_relaylog_refcount_update() inuse_relaylog *ir= accumulated_ir_last; if (ir) { - my_atomic_rwlock_wrlock(&ir->rli->inuse_relaylog_atomic_lock); my_atomic_add64(&ir->dequeued_count, accumulated_ir_count); - my_atomic_rwlock_wrunlock(&ir->rli->inuse_relaylog_atomic_lock); accumulated_ir_count= 0; accumulated_ir_last= NULL; } diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 6822388e206..ad33541b5ab 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -108,7 +108,6 @@ Relay_log_info::~Relay_log_info() { DBUG_ASSERT(cur->queued_count == cur->dequeued_count); inuse_relaylog *next= cur->next; - my_atomic_rwlock_destroy(&cur->inuse_relaylog_atomic_lock); my_free(cur); cur= next; } @@ -1401,7 +1400,6 @@ Relay_log_info::alloc_inuse_relaylog(const char *name) last_inuse_relaylog->next= ir; } last_inuse_relaylog= ir; - my_atomic_rwlock_init(&ir->inuse_relaylog_atomic_lock); return 0; } diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index ddf6c2ccc71..d8a30e75724 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -504,8 +504,6 @@ struct inuse_relaylog { /* Set when all events have been read from a relaylog. */ bool completed; char name[FN_REFLEN]; - /* Lock used to protect inuse_relaylog::dequeued_count */ - my_atomic_rwlock_t inuse_relaylog_atomic_lock; }; diff --git a/sql/slave.cc b/sql/slave.cc index e59f59f8a22..f193659b170 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3652,8 +3652,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, serial_rgi->trans_retries)); } } - thread_safe_increment64(&rli->executed_entries, - &slave_executed_entries_lock); + thread_safe_increment64(&rli->executed_entries); DBUG_RETURN(exec_res); } mysql_mutex_unlock(&rli->data_lock); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index ca6e6f63594..70529b207b1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1732,7 +1732,7 @@ void close_temporary_table(THD *thd, TABLE *table, { /* natural invariant of temporary_tables */ DBUG_ASSERT(slave_open_temp_tables || !thd->temporary_tables); - thread_safe_decrement32(&slave_open_temp_tables, &thread_running_lock); + thread_safe_decrement32(&slave_open_temp_tables); table->in_use= 0; // No statistics } thd->unlock_temporary_tables(); @@ -5721,7 +5721,7 @@ TABLE *open_table_uncached(THD *thd, handlerton *hton, thd->temporary_tables->prev= 0; if (thd->rgi_slave) { - thread_safe_increment32(&slave_open_temp_tables, &thread_running_lock); + thread_safe_increment32(&slave_open_temp_tables); } thd->unlock_temporary_tables(); } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 050e28f98b4..2680019e3e2 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2061,7 +2061,7 @@ public: thd.security_ctx->user= thd.security_ctx->host=0; delayed_insert_threads--; mysql_mutex_unlock(&LOCK_thread_count); - thread_safe_decrement32(&thread_count, &thread_count_lock); + thread_safe_decrement32(&thread_count); mysql_cond_broadcast(&COND_thread_count); /* Tell main we are ready */ } @@ -2197,7 +2197,7 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request, if (!(di= new Delayed_insert())) goto end_create; - thread_safe_increment32(&thread_count, &thread_count_lock); + thread_safe_increment32(&thread_count); /* Annotating delayed inserts is not supported. diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e9553993794..e4e5f0adfd5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -840,7 +840,7 @@ end: delete thd; #ifndef EMBEDDED_LIBRARY - thread_safe_decrement32(&thread_count, &thread_count_lock); + thread_safe_decrement32(&thread_count); in_bootstrap= FALSE; mysql_mutex_lock(&LOCK_thread_count); diff --git a/sql/table_cache.cc b/sql/table_cache.cc index f12c031f91a..9a75cafb30e 100644 --- a/sql/table_cache.cc +++ b/sql/table_cache.cc @@ -82,7 +82,6 @@ static int32 tc_count; /**< Number of TABLE objects in table cache. */ */ static mysql_mutex_t LOCK_unused_shares; -my_atomic_rwlock_t LOCK_tdc_atomics; /**< Protects tdc_version. */ #ifdef HAVE_PSI_INTERFACE PSI_mutex_key key_LOCK_unused_shares, key_TABLE_SHARE_LOCK_table_share; @@ -136,11 +135,7 @@ static int fix_thd_pins(THD *thd) uint tc_records(void) { - uint count; - my_atomic_rwlock_rdlock(&LOCK_tdc_atomics); - count= my_atomic_load32_explicit(&tc_count, MY_MEMORY_ORDER_RELAXED); - my_atomic_rwlock_rdunlock(&LOCK_tdc_atomics); - return count; + return my_atomic_load32_explicit(&tc_count, MY_MEMORY_ORDER_RELAXED); } @@ -153,9 +148,7 @@ uint tc_records(void) static void tc_remove_table(TABLE *table) { - my_atomic_rwlock_wrlock(&LOCK_tdc_atomics); my_atomic_add32_explicit(&tc_count, -1, MY_MEMORY_ORDER_RELAXED); - my_atomic_rwlock_wrunlock(&LOCK_tdc_atomics); table->s->tdc->all_tables.remove(table); } @@ -262,10 +255,8 @@ void tc_add_table(THD *thd, TABLE *table) mysql_mutex_unlock(&table->s->tdc->LOCK_table_share); /* If we have too many TABLE instances around, try to get rid of them */ - my_atomic_rwlock_wrlock(&LOCK_tdc_atomics); need_purge= my_atomic_add32_explicit(&tc_count, 1, MY_MEMORY_ORDER_RELAXED) >= (int32) tc_size; - my_atomic_rwlock_wrunlock(&LOCK_tdc_atomics); if (need_purge) { @@ -435,7 +426,6 @@ void tdc_init(void) tdc_inited= true; mysql_mutex_init(key_LOCK_unused_shares, &LOCK_unused_shares, MY_MUTEX_INIT_FAST); - my_atomic_rwlock_init(&LOCK_tdc_atomics); tdc_version= 1L; /* Increments on each reload */ lf_hash_init(&tdc_hash, sizeof(TDC_element), LF_HASH_UNIQUE, 0, 0, (my_hash_get_key) TDC_element::key, @@ -484,7 +474,6 @@ void tdc_deinit(void) { tdc_inited= false; lf_hash_destroy(&tdc_hash); - my_atomic_rwlock_destroy(&LOCK_tdc_atomics); mysql_mutex_destroy(&LOCK_unused_shares); } DBUG_VOID_RETURN; @@ -1000,18 +989,13 @@ int tdc_wait_for_old_version(THD *thd, const char *db, const char *table_name, ulong tdc_refresh_version(void) { - my_atomic_rwlock_rdlock(&LOCK_tdc_atomics); - ulong v= my_atomic_load64_explicit(&tdc_version, MY_MEMORY_ORDER_RELAXED); - my_atomic_rwlock_rdunlock(&LOCK_tdc_atomics); - return v; + return my_atomic_load64_explicit(&tdc_version, MY_MEMORY_ORDER_RELAXED); } ulong tdc_increment_refresh_version(void) { - my_atomic_rwlock_wrlock(&LOCK_tdc_atomics); ulong v= my_atomic_add64_explicit(&tdc_version, 1, MY_MEMORY_ORDER_RELAXED); - my_atomic_rwlock_wrunlock(&LOCK_tdc_atomics); DBUG_PRINT("tcache", ("incremented global refresh_version to: %lu", v)); return v + 1; } @@ -1154,9 +1138,7 @@ void tdc_assign_new_table_id(TABLE_SHARE *share) */ do { - my_atomic_rwlock_wrlock(&LOCK_tdc_atomics); tid= my_atomic_add64_explicit(&last_table_id, 1, MY_MEMORY_ORDER_RELAXED); - my_atomic_rwlock_wrunlock(&LOCK_tdc_atomics); } while (unlikely(tid == ~0UL)); share->table_map_id= tid; diff --git a/storage/maria/lockman.c b/storage/maria/lockman.c index aa030b6f57a..f319fea1e0e 100644 --- a/storage/maria/lockman.c +++ b/storage/maria/lockman.c @@ -264,10 +264,10 @@ retry: compatible= TRUE; upgrading= FALSE; cursor->blocker= cursor->upgrade_from= 0; - _lf_unpin(pins, 3); + lf_unpin(pins, 3); do { cursor->curr= PTR(*cursor->prev); - _lf_pin(pins, 1, cursor->curr); + lf_pin(pins, 1, cursor->curr); } while(*cursor->prev != (intptr)cursor->curr && LF_BACKOFF); for (;;) { @@ -276,7 +276,7 @@ retry: do { cur_link= cursor->curr->link; cursor->next= PTR(cur_link); - _lf_pin(pins, 0, cursor->next); + lf_pin(pins, 0, cursor->next); } while (cur_link != cursor->curr->link && LF_BACKOFF); cur_hashnr= cursor->curr->hashnr; cur_resource= cursor->curr->resource; @@ -316,7 +316,7 @@ retry: if (prev_active && !cur_active) { cursor->blocker= cursor->curr; - _lf_pin(pins, 3, cursor->curr); + lf_pin(pins, 3, cursor->curr); } if (cur_loid == loid) { @@ -329,7 +329,7 @@ retry: if (cur_active) { cursor->blocker= cursor->curr; /* loose-locks! */ - _lf_unpin(pins, 3); /* loose-locks! */ + lf_unpin(pins, 3); /* loose-locks! */ return ALREADY_HAVE_THE_LOCK; } else @@ -345,7 +345,7 @@ retry: { compatible= FALSE; cursor->blocker= cursor->curr; - _lf_pin(pins, 3, cursor->curr); + lf_pin(pins, 3, cursor->curr); } } prev_lock= lock_combining_matrix[prev_lock][cur_lock]; @@ -353,13 +353,13 @@ retry: } } cursor->prev= &(cursor->curr->link); - _lf_pin(pins, 2, cursor->curr); + lf_pin(pins, 2, cursor->curr); } else { if (my_atomic_casptr((void **)cursor->prev, (void **)(char*) &cursor->curr, cursor->next)) - _lf_alloc_free(pins, cursor->curr); + lf_alloc_free(pins, cursor->curr); else { (void)LF_BACKOFF; @@ -367,7 +367,7 @@ retry: } } cursor->curr= cursor->next; - _lf_pin(pins, 1, cursor->curr); + lf_pin(pins, 1, cursor->curr); } /* either the end of lock list - no more locks for this resource, @@ -435,9 +435,9 @@ static int lockinsert(LOCK * volatile *head, LOCK *node, LF_PINS *pins, } } while (res == REPEAT_ONCE_MORE); - _lf_unpin(pins, 0); - _lf_unpin(pins, 1); - _lf_unpin(pins, 2); + lf_unpin(pins, 0); + lf_unpin(pins, 1); + lf_unpin(pins, 2); /* note that blocker is not necessarily pinned here (when it's == curr). this is ok as in such a case it's either a dummy node for @@ -461,9 +461,9 @@ static int lockpeek(LOCK * volatile *head, LOCK *node, LF_PINS *pins, res= lockfind(head, node, &cursor, pins); - _lf_unpin(pins, 0); - _lf_unpin(pins, 1); - _lf_unpin(pins, 2); + lf_unpin(pins, 0); + lf_unpin(pins, 1); + lf_unpin(pins, 2); if (blocker) *blocker= cursor.blocker; return res; @@ -502,7 +502,7 @@ static int lockdelete(LOCK * volatile *head, LOCK *node, LF_PINS *pins) { if (my_atomic_casptr((void **)cursor.prev, (void **)(char*)&cursor.curr, cursor.next)) - _lf_alloc_free(pins, cursor.curr); + lf_alloc_free(pins, cursor.curr); else lockfind(head, node, &cursor, pins); } @@ -513,10 +513,10 @@ static int lockdelete(LOCK * volatile *head, LOCK *node, LF_PINS *pins) cursor.upgrade_from->flags|= IGNORE_ME; } } while (res == REPEAT_ONCE_MORE); - _lf_unpin(pins, 0); - _lf_unpin(pins, 1); - _lf_unpin(pins, 2); - _lf_unpin(pins, 3); + lf_unpin(pins, 0); + lf_unpin(pins, 1); + lf_unpin(pins, 2); + lf_unpin(pins, 3); return res; } @@ -532,7 +532,7 @@ void lockman_init(LOCKMAN *lm, loid_to_lo_func *func, uint timeout) void lockman_destroy(LOCKMAN *lm) { - LOCK *el= *(LOCK **)_lf_dynarray_lvalue(&lm->array, 0); + LOCK *el= *(LOCK **)lf_dynarray_lvalue(&lm->array, 0); while (el) { intptr next= el->link; @@ -556,7 +556,7 @@ static void initialize_bucket(LOCKMAN *lm, LOCK * volatile *node, uint parent= my_clear_highest_bit(bucket); LOCK *dummy= (LOCK *)my_malloc(sizeof(LOCK), MYF(MY_WME)); LOCK **tmp= 0, *cur; - LOCK * volatile *el= _lf_dynarray_lvalue(&lm->array, parent); + LOCK * volatile *el= lf_dynarray_lvalue(&lm->array, parent); if (*el == NULL && bucket) initialize_bucket(lm, el, parent, pins); @@ -604,15 +604,14 @@ enum lockman_getlock_result lockman_getlock(LOCKMAN *lm, LOCK_OWNER *lo, enum lockman_lock_type old_lock; DBUG_ASSERT(lo->loid); - lf_rwlock_by_pins(pins); - node= (LOCK *)_lf_alloc_new(pins); + node= (LOCK *)lf_alloc_new(pins); node->flags= 0; node->lock= lock; node->loid= lo->loid; node->resource= resource; hashnr= calc_hash(resource); bucket= hashnr % lm->size; - el= _lf_dynarray_lvalue(&lm->array, bucket); + el= lf_dynarray_lvalue(&lm->array, bucket); if (*el == NULL) initialize_bucket(lm, el, bucket, pins); node->hashnr= my_reverse_bits(hashnr) | 1; @@ -621,8 +620,7 @@ enum lockman_getlock_result lockman_getlock(LOCKMAN *lm, LOCK_OWNER *lo, { int r; old_lock= blocker->lock; - _lf_alloc_free(pins, node); - lf_rwunlock_by_pins(pins); + lf_alloc_free(pins, node); r= getlock_result[old_lock][lock]; DBUG_ASSERT(r); return r; @@ -639,7 +637,7 @@ enum lockman_getlock_result lockman_getlock(LOCKMAN *lm, LOCK_OWNER *lo, ulonglong deadline; struct timespec timeout; - _lf_assert_pin(pins, 3); /* blocker must be pinned here */ + lf_assert_pin(pins, 3); /* blocker must be pinned here */ wait_for_lo= lm->loid_to_lo(blocker->loid); /* @@ -652,7 +650,7 @@ enum lockman_getlock_result lockman_getlock(LOCKMAN *lm, LOCK_OWNER *lo, if (lock_compatibility_matrix[blocker->lock][lock]) { blocker= wait_for_lo->all_locks; - _lf_pin(pins, 3, blocker); + lf_pin(pins, 3, blocker); if (blocker != wait_for_lo->all_locks) continue; wait_for_lo= wait_for_lo->waiting_for; @@ -667,7 +665,6 @@ enum lockman_getlock_result lockman_getlock(LOCKMAN *lm, LOCK_OWNER *lo, continue; lo->waiting_for= wait_for_lo; - lf_rwunlock_by_pins(pins); /* We lock a mutex - it may belong to a wrong LOCK_OWNER, but it must @@ -683,7 +680,6 @@ enum lockman_getlock_result lockman_getlock(LOCKMAN *lm, LOCK_OWNER *lo, the lock was rolled back. Either way - the lock was removed */ pthread_mutex_unlock(wait_for_lo->mutex); - lf_rwlock_by_pins(pins); continue; } @@ -695,7 +691,6 @@ enum lockman_getlock_result lockman_getlock(LOCKMAN *lm, LOCK_OWNER *lo, pthread_cond_timedwait(wait_for_lo->cond, wait_for_lo->mutex, &timeout); } while (!DELETED(blocker->link) && my_hrtime().val < deadline/1000); pthread_mutex_unlock(wait_for_lo->mutex); - lf_rwlock_by_pins(pins); if (!DELETED(blocker->link)) { /* @@ -704,14 +699,12 @@ enum lockman_getlock_result lockman_getlock(LOCKMAN *lm, LOCK_OWNER *lo, Instead we're relying on the caller to abort the transaction, and release all locks at once - see lockman_release_locks() */ - _lf_unpin(pins, 3); - lf_rwunlock_by_pins(pins); + lf_unpin(pins, 3); return DIDNT_GET_THE_LOCK; } } lo->waiting_for= 0; - _lf_assert_unpin(pins, 3); /* unpin should not be needed */ - lf_rwunlock_by_pins(pins); + lf_assert_unpin(pins, 3); /* unpin should not be needed */ return getlock_result[lock][lock]; } @@ -729,18 +722,16 @@ int lockman_release_locks(LOCKMAN *lm, LOCK_OWNER *lo) LF_PINS *pins= lo->pins; pthread_mutex_lock(lo->mutex); - lf_rwlock_by_pins(pins); for (node= lo->all_locks; node; node= next) { next= node->lonext; bucket= calc_hash(node->resource) % lm->size; - el= _lf_dynarray_lvalue(&lm->array, bucket); + el= lf_dynarray_lvalue(&lm->array, bucket); if (*el == NULL) initialize_bucket(lm, el, bucket, pins); lockdelete(el, node, pins); my_atomic_add32(&lm->count, -1); } - lf_rwunlock_by_pins(pins); lo->all_locks= 0; /* now signal all waiters */ pthread_cond_broadcast(lo->cond); @@ -757,7 +748,7 @@ static const char *lock2str[]= */ void print_lockhash(LOCKMAN *lm) { - LOCK *el= *(LOCK **)_lf_dynarray_lvalue(&lm->array, 0); + LOCK *el= *(LOCK **)lf_dynarray_lvalue(&lm->array, 0); printf("hash: size %u count %u\n", lm->size, lm->count); while (el) { diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 2538deeb27d..a4901332088 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -419,8 +419,6 @@ static ulonglong flush_start= 0; #include <my_atomic.h> /* an array that maps id of a MARIA_SHARE to this MARIA_SHARE */ static MARIA_SHARE **id_to_share= NULL; -/* lock for id_to_share */ -static my_atomic_rwlock_t LOCK_id_to_share; static my_bool translog_dummy_callback(uchar *page, pgcache_page_no_t page_no, @@ -4042,7 +4040,6 @@ my_bool translog_init_with_table(const char *directory, Log records will refer to a MARIA_SHARE by a unique 2-byte id; set up structures for generating 2-byte ids: */ - my_atomic_rwlock_init(&LOCK_id_to_share); id_to_share= (MARIA_SHARE **) my_malloc(SHARE_ID_MAX * sizeof(MARIA_SHARE*), MYF(MY_WME | MY_ZEROFILL)); if (unlikely(!id_to_share)) @@ -4286,7 +4283,6 @@ void translog_destroy() if (log_descriptor.directory_fd >= 0) mysql_file_close(log_descriptor.directory_fd, MYF(MY_WME)); - my_atomic_rwlock_destroy(&LOCK_id_to_share); if (id_to_share != NULL) my_free(id_to_share + 1); DBUG_VOID_RETURN; @@ -8125,7 +8121,6 @@ int translog_assign_id_to_share(MARIA_HA *tbl_info, TRN *trn) id= 0; do { - my_atomic_rwlock_wrlock(&LOCK_id_to_share); for ( ; i <= SHARE_ID_MAX ; i++) /* the range is [1..SHARE_ID_MAX] */ { void *tmp= NULL; @@ -8136,7 +8131,6 @@ int translog_assign_id_to_share(MARIA_HA *tbl_info, TRN *trn) break; } } - my_atomic_rwlock_wrunlock(&LOCK_id_to_share); i= 1; /* scan the whole array */ } while (id == 0); DBUG_PRINT("info", ("id_to_share: 0x%lx -> %u", (ulong)share, id)); @@ -8199,9 +8193,7 @@ void translog_deassign_id_from_share(MARIA_SHARE *share) mutex: */ mysql_mutex_assert_owner(&share->intern_lock); - my_atomic_rwlock_rdlock(&LOCK_id_to_share); my_atomic_storeptr((void **)&id_to_share[share->id], 0); - my_atomic_rwlock_rdunlock(&LOCK_id_to_share); share->id= 0; /* useless but safety: */ share->lsn_of_file_id= LSN_IMPOSSIBLE; diff --git a/storage/maria/trnman.c b/storage/maria/trnman.c index daccf3550c2..3ada502988a 100644 --- a/storage/maria/trnman.c +++ b/storage/maria/trnman.c @@ -60,7 +60,6 @@ static LF_HASH trid_to_trn; static TRN **short_trid_to_active_trn; /* locks for short_trid_to_active_trn and pool */ -static my_atomic_rwlock_t LOCK_short_trid_to_trn, LOCK_pool; static my_bool default_trnman_end_trans_hook(TRN *, my_bool, my_bool); static void trnman_free_trn(TRN *); @@ -191,8 +190,6 @@ int trnman_init(TrID initial_trid) 0, 0, trn_get_hash_key, 0); DBUG_PRINT("info", ("mysql_mutex_init LOCK_trn_list")); mysql_mutex_init(key_LOCK_trn_list, &LOCK_trn_list, MY_MUTEX_INIT_FAST); - my_atomic_rwlock_init(&LOCK_short_trid_to_trn); - my_atomic_rwlock_init(&LOCK_pool); DBUG_RETURN(0); } @@ -226,8 +223,6 @@ void trnman_destroy() lf_hash_destroy(&trid_to_trn); DBUG_PRINT("info", ("mysql_mutex_destroy LOCK_trn_list")); mysql_mutex_destroy(&LOCK_trn_list); - my_atomic_rwlock_destroy(&LOCK_short_trid_to_trn); - my_atomic_rwlock_destroy(&LOCK_pool); my_free(short_trid_to_active_trn+1); short_trid_to_active_trn= NULL; @@ -257,7 +252,6 @@ static uint get_short_trid(TRN *trn) for ( ; !res ; i= 1) { - my_atomic_rwlock_wrlock(&LOCK_short_trid_to_trn); for ( ; i <= SHORT_TRID_MAX; i++) /* the range is [1..SHORT_TRID_MAX] */ { void *tmp= NULL; @@ -268,7 +262,6 @@ static uint get_short_trid(TRN *trn) break; } } - my_atomic_rwlock_wrunlock(&LOCK_short_trid_to_trn); } return res; } @@ -306,11 +299,9 @@ TRN *trnman_new_trn(WT_THD *wt) Popping an unused TRN from the pool (ABA isn't possible, we're behind a mutex */ - my_atomic_rwlock_wrlock(&LOCK_pool); while (tmp.trn && !my_atomic_casptr((void **)(char*) &pool, &tmp.v, (void *)tmp.trn->next)) /* no-op */; - my_atomic_rwlock_wrunlock(&LOCK_pool); /* Nothing in the pool ? Allocate a new one */ if (!(trn= tmp.trn)) @@ -493,9 +484,7 @@ my_bool trnman_end_trn(TRN *trn, my_bool commit) note that we don't own trn anymore, it may be in a shared list now. Thus, we cannot dereference it, and must use cached_short_id below. */ - my_atomic_rwlock_rdlock(&LOCK_short_trid_to_trn); my_atomic_storeptr((void **)&short_trid_to_active_trn[cached_short_id], 0); - my_atomic_rwlock_rdunlock(&LOCK_short_trid_to_trn); /* we, under the mutex, removed going-in-free_me transactions from the @@ -545,7 +534,6 @@ static void trnman_free_trn(TRN *trn) tmp.trn= pool; - my_atomic_rwlock_wrlock(&LOCK_pool); do { /* @@ -554,7 +542,6 @@ static void trnman_free_trn(TRN *trn) */ *(TRN * volatile *)&(trn->next)= tmp.trn; } while (!my_atomic_casptr((void **)(char*)&pool, &tmp.v, trn)); - my_atomic_rwlock_wrunlock(&LOCK_pool); } /* diff --git a/storage/perfschema/CMakeLists.txt b/storage/perfschema/CMakeLists.txt index 52c1d9b05d9..c5e565979e4 100644 --- a/storage/perfschema/CMakeLists.txt +++ b/storage/perfschema/CMakeLists.txt @@ -132,7 +132,6 @@ cursor_by_user.cc ha_perfschema.cc pfs.cc pfs_account.cc -pfs_atomic.cc pfs_autosize.cc pfs_column_values.cc pfs_con_slice.cc diff --git a/storage/perfschema/pfs_atomic.cc b/storage/perfschema/pfs_atomic.cc deleted file mode 100644 index 601bd94cabd..00000000000 --- a/storage/perfschema/pfs_atomic.cc +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ - -/** - @file storage/perfschema/pfs_atomic.cc - Atomic operations (implementation). -*/ - -#include <my_global.h> -#include <my_pthread.h> -#include "pfs_atomic.h" - -/* - Using SAFE_MUTEX is impossible, because of recursion. - - code locks mutex X - - P_S records the event - - P_S needs an atomic counter A - - safe mutex called for m_mutex[hash(A)] - - safe mutex allocates/free memory - - safe mutex locks THR_LOCK_malloc - - P_S records the event - - P_S needs an atomic counter B - - safe mutex called for m_mutex[hash(B)] - - When hash(A) == hash(B), safe_mutex complains rightly that - the mutex is already locked. - In some cases, A == B, in particular for events_waits_history_long_index. - - In short, the implementation of PFS_atomic should not cause events - to be recorded in the performance schema. - - Also, because SAFE_MUTEX redefines pthread_mutex_t, etc, - this code is not inlined in pfs_atomic.h, but located here in pfs_atomic.cc. - - What is needed is a plain, unmodified, pthread_mutex_t. - This is provided by my_atomic_rwlock_t. -*/ - -/** - Internal rwlock array. - Using a single rwlock for all atomic operations would be a bottleneck. - Using a rwlock per performance schema structure would be too costly in - memory, and use too many rwlock. - The PFS_atomic implementation computes a hash value from the - atomic variable, to spread the bottleneck across 256 buckets, - while still providing --transparently for the caller-- an atomic - operation. -*/ -my_atomic_rwlock_t PFS_atomic::m_rwlock_array[256]; -static int init_done; - -void PFS_atomic::init(void) -{ - uint i; - - for (i=0; i< array_elements(m_rwlock_array); i++) - my_atomic_rwlock_init(&m_rwlock_array[i]); - init_done= 1; -} - -void PFS_atomic::cleanup(void) -{ - uint i; - if (!init_done) - return; - for (i=0; i< array_elements(m_rwlock_array); i++) - my_atomic_rwlock_destroy(&m_rwlock_array[i]); -} - diff --git a/storage/perfschema/pfs_atomic.h b/storage/perfschema/pfs_atomic.h index 61b8c2b2804..31833b832cf 100644 --- a/storage/perfschema/pfs_atomic.h +++ b/storage/perfschema/pfs_atomic.h @@ -27,221 +27,106 @@ class PFS_atomic { public: - /** Initialise the PFS_atomic component. */ - static void init(); - /** Cleanup the PFS_atomic component. */ - static void cleanup(); - /** Atomic load. */ static inline int32 load_32(volatile int32 *ptr) { - int32 result; - rdlock(ptr); - result= my_atomic_load32(ptr); - rdunlock(ptr); - return result; + return my_atomic_load32(ptr); } /** Atomic load. */ static inline int64 load_64(volatile int64 *ptr) { - int64 result; - rdlock(ptr); - result= my_atomic_load64(ptr); - rdunlock(ptr); - return result; + return my_atomic_load64(ptr); } /** Atomic load. */ static inline uint32 load_u32(volatile uint32 *ptr) { - uint32 result; - rdlock(ptr); - result= (uint32) my_atomic_load32((int32*) ptr); - rdunlock(ptr); - return result; + return (uint32) my_atomic_load32((int32*) ptr); } /** Atomic load. */ static inline uint64 load_u64(volatile uint64 *ptr) { - uint64 result; - rdlock(ptr); - result= (uint64) my_atomic_load64((int64*) ptr); - rdunlock(ptr); - return result; + return (uint64) my_atomic_load64((int64*) ptr); } /** Atomic store. */ static inline void store_32(volatile int32 *ptr, int32 value) { - wrlock(ptr); my_atomic_store32(ptr, value); - wrunlock(ptr); } /** Atomic store. */ static inline void store_64(volatile int64 *ptr, int64 value) { - wrlock(ptr); my_atomic_store64(ptr, value); - wrunlock(ptr); } /** Atomic store. */ static inline void store_u32(volatile uint32 *ptr, uint32 value) { - wrlock(ptr); my_atomic_store32((int32*) ptr, (int32) value); - wrunlock(ptr); } /** Atomic store. */ static inline void store_u64(volatile uint64 *ptr, uint64 value) { - wrlock(ptr); my_atomic_store64((int64*) ptr, (int64) value); - wrunlock(ptr); } /** Atomic add. */ static inline int32 add_32(volatile int32 *ptr, int32 value) { - int32 result; - wrlock(ptr); - result= my_atomic_add32(ptr, value); - wrunlock(ptr); - return result; + return my_atomic_add32(ptr, value); } /** Atomic add. */ static inline int64 add_64(volatile int64 *ptr, int64 value) { - int64 result; - wrlock(ptr); - result= my_atomic_add64(ptr, value); - wrunlock(ptr); - return result; + return my_atomic_add64(ptr, value); } /** Atomic add. */ static inline uint32 add_u32(volatile uint32 *ptr, uint32 value) { - uint32 result; - wrlock(ptr); - result= (uint32) my_atomic_add32((int32*) ptr, (int32) value); - wrunlock(ptr); - return result; + return (uint32) my_atomic_add32((int32*) ptr, (int32) value); } /** Atomic add. */ static inline uint64 add_u64(volatile uint64 *ptr, uint64 value) { - uint64 result; - wrlock(ptr); - result= (uint64) my_atomic_add64((int64*) ptr, (int64) value); - wrunlock(ptr); - return result; + return (uint64) my_atomic_add64((int64*) ptr, (int64) value); } /** Atomic compare and swap. */ static inline bool cas_32(volatile int32 *ptr, int32 *old_value, int32 new_value) { - bool result; - wrlock(ptr); - result= my_atomic_cas32(ptr, old_value, new_value); - wrunlock(ptr); - return result; + return my_atomic_cas32(ptr, old_value, new_value); } /** Atomic compare and swap. */ static inline bool cas_64(volatile int64 *ptr, int64 *old_value, int64 new_value) { - bool result; - wrlock(ptr); - result= my_atomic_cas64(ptr, old_value, new_value); - wrunlock(ptr); - return result; + return my_atomic_cas64(ptr, old_value, new_value); } /** Atomic compare and swap. */ static inline bool cas_u32(volatile uint32 *ptr, uint32 *old_value, uint32 new_value) { - bool result; - wrlock(ptr); - result= my_atomic_cas32((int32*) ptr, (int32*) old_value, + return my_atomic_cas32((int32*) ptr, (int32*) old_value, (uint32) new_value); - wrunlock(ptr); - return result; } /** Atomic compare and swap. */ static inline bool cas_u64(volatile uint64 *ptr, uint64 *old_value, uint64 new_value) { - bool result; - wrlock(ptr); - result= my_atomic_cas64((int64*) ptr, (int64*) old_value, + return my_atomic_cas64((int64*) ptr, (int64*) old_value, (uint64) new_value); - wrunlock(ptr); - return result; - } - -private: - static my_atomic_rwlock_t m_rwlock_array[256]; - - /** - Helper used only with non native atomic implementations. - @sa MY_ATOMIC_MODE_RWLOCKS - */ - static inline my_atomic_rwlock_t *get_rwlock(volatile void *ptr) - { - /* - Divide an address by 8 to remove alignment, - modulo 256 to fall in the array. - */ - uint index= (((intptr) ptr) >> 3) & 0xFF; - my_atomic_rwlock_t *result= &m_rwlock_array[index]; - return result; - } - - /** - Helper used only with non native atomic implementations. - @sa MY_ATOMIC_MODE_RWLOCKS - */ - static inline void rdlock(volatile void *ptr) - { - my_atomic_rwlock_rdlock(get_rwlock(ptr)); - } - - /** - Helper used only with non native atomic implementations. - @sa MY_ATOMIC_MODE_RWLOCKS - */ - static inline void wrlock(volatile void *ptr) - { - my_atomic_rwlock_wrlock(get_rwlock(ptr)); - } - - /** - Helper used only with non native atomic implementations. - @sa MY_ATOMIC_MODE_RWLOCKS - */ - static inline void rdunlock(volatile void *ptr) - { - my_atomic_rwlock_rdunlock(get_rwlock(ptr)); - } - - /** - Helper used only with non native atomic implementations. - @sa MY_ATOMIC_MODE_RWLOCKS - */ - static inline void wrunlock(volatile void *ptr) - { - my_atomic_rwlock_wrunlock(get_rwlock(ptr)); } }; diff --git a/storage/perfschema/pfs_server.cc b/storage/perfschema/pfs_server.cc index 383a46785fb..9799a9c4ffc 100644 --- a/storage/perfschema/pfs_server.cc +++ b/storage/perfschema/pfs_server.cc @@ -71,7 +71,6 @@ initialize_performance_schema(PFS_global_param *param) } init_timers(); - PFS_atomic::init(); init_event_name_sizing(param); register_global_classes(); @@ -187,7 +186,6 @@ static void cleanup_performance_schema(void) cleanup_account_hash(); cleanup_digest(); cleanup_digest_hash(); - PFS_atomic::cleanup(); } void shutdown_performance_schema(void) diff --git a/storage/perfschema/unittest/pfs_account-oom-t.cc b/storage/perfschema/unittest/pfs_account-oom-t.cc index 2343e8378ad..6984fab6648 100644 --- a/storage/perfschema/unittest/pfs_account-oom-t.cc +++ b/storage/perfschema/unittest/pfs_account-oom-t.cc @@ -100,11 +100,7 @@ void test_oom() void do_all_tests() { - PFS_atomic::init(); - test_oom(); - - PFS_atomic::cleanup(); } int main(int, char **) diff --git a/storage/perfschema/unittest/pfs_host-oom-t.cc b/storage/perfschema/unittest/pfs_host-oom-t.cc index 5b823ce4eac..d12abe6f38b 100644 --- a/storage/perfschema/unittest/pfs_host-oom-t.cc +++ b/storage/perfschema/unittest/pfs_host-oom-t.cc @@ -100,11 +100,7 @@ void test_oom() void do_all_tests() { - PFS_atomic::init(); - test_oom(); - - PFS_atomic::cleanup(); } int main(int, char **) diff --git a/storage/perfschema/unittest/pfs_instr-oom-t.cc b/storage/perfschema/unittest/pfs_instr-oom-t.cc index 18c0029776d..f1df130180b 100644 --- a/storage/perfschema/unittest/pfs_instr-oom-t.cc +++ b/storage/perfschema/unittest/pfs_instr-oom-t.cc @@ -654,11 +654,7 @@ void test_oom() void do_all_tests() { - PFS_atomic::init(); - test_oom(); - - PFS_atomic::cleanup(); } int main(int argc, char **argv) diff --git a/storage/perfschema/unittest/pfs_instr-t.cc b/storage/perfschema/unittest/pfs_instr-t.cc index fab22b203d3..e0361b3a958 100644 --- a/storage/perfschema/unittest/pfs_instr-t.cc +++ b/storage/perfschema/unittest/pfs_instr-t.cc @@ -402,13 +402,9 @@ void test_with_instances() void do_all_tests() { - PFS_atomic::init(); - test_no_instruments(); test_no_instances(); test_with_instances(); - - PFS_atomic::cleanup(); } int main(int argc, char **argv) diff --git a/storage/perfschema/unittest/pfs_instr_class-oom-t.cc b/storage/perfschema/unittest/pfs_instr_class-oom-t.cc index 264d6126336..dc4f954bc8a 100644 --- a/storage/perfschema/unittest/pfs_instr_class-oom-t.cc +++ b/storage/perfschema/unittest/pfs_instr_class-oom-t.cc @@ -56,11 +56,7 @@ void test_oom() void do_all_tests() { - PFS_atomic::init(); - test_oom(); - - PFS_atomic::cleanup(); } int main(int argc, char **argv) diff --git a/storage/perfschema/unittest/pfs_instr_class-t.cc b/storage/perfschema/unittest/pfs_instr_class-t.cc index 706c5724a80..6fb2abc30a0 100644 --- a/storage/perfschema/unittest/pfs_instr_class-t.cc +++ b/storage/perfschema/unittest/pfs_instr_class-t.cc @@ -655,8 +655,6 @@ void test_instruments_reset() void do_all_tests() { - PFS_atomic::init(); - test_no_registration(); test_mutex_registration(); test_rwlock_registration(); @@ -666,8 +664,6 @@ void do_all_tests() test_socket_registration(); test_table_registration(); test_instruments_reset(); - - PFS_atomic::cleanup(); } int main(int argc, char **argv) diff --git a/storage/perfschema/unittest/pfs_timer-t.cc b/storage/perfschema/unittest/pfs_timer-t.cc index 0a2cc63f30e..8fb3a206ebf 100644 --- a/storage/perfschema/unittest/pfs_timer-t.cc +++ b/storage/perfschema/unittest/pfs_timer-t.cc @@ -106,11 +106,7 @@ void test_timers() void do_all_tests() { - PFS_atomic::init(); - test_timers(); - - PFS_atomic::cleanup(); } int main(int, char **) diff --git a/storage/perfschema/unittest/pfs_user-oom-t.cc b/storage/perfschema/unittest/pfs_user-oom-t.cc index 3cb80e1b7f9..d37d5368ee1 100644 --- a/storage/perfschema/unittest/pfs_user-oom-t.cc +++ b/storage/perfschema/unittest/pfs_user-oom-t.cc @@ -99,11 +99,7 @@ void test_oom() void do_all_tests() { - PFS_atomic::init(); - test_oom(); - - PFS_atomic::cleanup(); } int main(int, char **) diff --git a/unittest/mysys/my_atomic-t.c b/unittest/mysys/my_atomic-t.c index 35e782eb360..0f21c33455e 100644 --- a/unittest/mysys/my_atomic-t.c +++ b/unittest/mysys/my_atomic-t.c @@ -17,7 +17,6 @@ volatile uint32 b32; volatile int32 c32; -my_atomic_rwlock_t rwl; /* add and sub a random number in a loop. Must get 0 at the end */ pthread_handler_t test_atomic_add(void *arg) @@ -27,13 +26,8 @@ pthread_handler_t test_atomic_add(void *arg) for (x= ((int)(intptr)(&m)); m ; m--) { x= (x*m+0x87654321) & INT_MAX32; - my_atomic_rwlock_wrlock(&rwl); my_atomic_add32(&bad, x); - my_atomic_rwlock_wrunlock(&rwl); - - my_atomic_rwlock_wrlock(&rwl); my_atomic_add32(&bad, -x); - my_atomic_rwlock_wrunlock(&rwl); } pthread_mutex_lock(&mutex); if (!--running_threads) pthread_cond_signal(&cond); @@ -50,13 +44,8 @@ pthread_handler_t test_atomic_add64(void *arg) for (x= ((int64)(intptr)(&m)); m ; m--) { x= (x*m+0xfdecba987654321LL) & INT_MAX64; - my_atomic_rwlock_wrlock(&rwl); my_atomic_add64(&a64, x); - my_atomic_rwlock_wrunlock(&rwl); - - my_atomic_rwlock_wrlock(&rwl); my_atomic_add64(&a64, -x); - my_atomic_rwlock_wrunlock(&rwl); } pthread_mutex_lock(&mutex); if (!--running_threads) @@ -82,31 +71,17 @@ pthread_handler_t test_atomic_fas(void *arg) int m= *(int *)arg; int32 x; - my_atomic_rwlock_wrlock(&rwl); x= my_atomic_add32(&b32, 1); - my_atomic_rwlock_wrunlock(&rwl); - my_atomic_rwlock_wrlock(&rwl); my_atomic_add32(&bad, x); - my_atomic_rwlock_wrunlock(&rwl); for (; m ; m--) - { - my_atomic_rwlock_wrlock(&rwl); x= my_atomic_fas32(&c32, x); - my_atomic_rwlock_wrunlock(&rwl); - } if (!x) - { - my_atomic_rwlock_wrlock(&rwl); x= my_atomic_fas32(&c32, x); - my_atomic_rwlock_wrunlock(&rwl); - } - my_atomic_rwlock_wrlock(&rwl); my_atomic_add32(&bad, -x); - my_atomic_rwlock_wrunlock(&rwl); pthread_mutex_lock(&mutex); if (!--running_threads) pthread_cond_signal(&cond); @@ -125,19 +100,13 @@ pthread_handler_t test_atomic_cas(void *arg) int32 x, y; for (x= ((int)(intptr)(&m)); m ; m--) { - my_atomic_rwlock_wrlock(&rwl); y= my_atomic_load32(&bad); - my_atomic_rwlock_wrunlock(&rwl); x= (x*m+0x87654321) & INT_MAX32; do { - my_atomic_rwlock_wrlock(&rwl); ok= my_atomic_cas32(&bad, &y, (uint32)y+x); - my_atomic_rwlock_wrunlock(&rwl); } while (!ok) ; do { - my_atomic_rwlock_wrlock(&rwl); ok= my_atomic_cas32(&bad, &y, y-x); - my_atomic_rwlock_wrunlock(&rwl); } while (!ok) ; } pthread_mutex_lock(&mutex); @@ -154,7 +123,6 @@ void do_tests() bad= my_atomic_initialize(); ok(!bad, "my_atomic_initialize() returned %d", bad); - my_atomic_rwlock_init(&rwl); b32= c32= 0; test_concurrently("my_atomic_add32", test_atomic_add, THREADS, CYCLES); @@ -178,6 +146,4 @@ void do_tests() } a64=0; test_concurrently("my_atomic_add64", test_atomic_add64, THREADS, CYCLES); - - my_atomic_rwlock_destroy(&rwl); } diff --git a/unittest/mysys/thr_template.c b/unittest/mysys/thr_template.c index 7304eb50955..38999022da0 100644 --- a/unittest/mysys/thr_template.c +++ b/unittest/mysys/thr_template.c @@ -64,15 +64,7 @@ int main(int argc __attribute__((unused)), char **argv) pthread_attr_init(&thr_attr); pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); -#ifdef MY_ATOMIC_MODE_RWLOCKS -#if defined(HPUX11) || defined(__POWERPC__) /* showed to be very slow (scheduler-related) */ -#define CYCLES 300 -#else #define CYCLES 3000 -#endif -#else -#define CYCLES 3000 -#endif #define THREADS 30 diag("N CPUs: %d, atomic ops: %s", my_getncpus(), MY_ATOMIC_MODE); |