mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Auto-merge from mysql-next-mr-summit0.3.
This commit is contained in:
commit
cc85fe239d
22 changed files with 445 additions and 105 deletions
|
@ -1303,7 +1303,11 @@ set_linux_configs()
|
|||
compiler_flags="$compiler_flags -m32"
|
||||
fi
|
||||
if test "x$fast_flag" != "xno" ; then
|
||||
compiler_flags="$compiler_flags -O2"
|
||||
if test "x$fast_flag" = "xyes" ; then
|
||||
compiler_flags="$compiler_flags -O3"
|
||||
else
|
||||
compiler_flags="$compiler_flags -O2"
|
||||
fi
|
||||
else
|
||||
compiler_flags="$compiler_flags -O0"
|
||||
fi
|
||||
|
|
68
configure.in
68
configure.in
|
@ -880,10 +880,74 @@ AC_CHECK_DECLS(MHA_MAPSIZE_VA,
|
|||
#include <sys/mman.h>
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
fi
|
||||
|
||||
dnl Use of ALARMs to wakeup on timeout on sockets
|
||||
dnl
|
||||
dnl This feature makes use of a mutex and is a scalability hog we
|
||||
dnl try to avoid using. However we need support for SO_SNDTIMEO and
|
||||
dnl SO_RCVTIMEO socket options for this to work. So we will check
|
||||
dnl if this feature is supported by a simple AC_RUN_IFELSE macro. However
|
||||
dnl on some OS's there is support for setting those variables but
|
||||
dnl they are silently ignored. For those OS's we will not attempt
|
||||
dnl o use SO_SNDTIMEO and SO_RCVTIMEO even if it is said to work.
|
||||
dnl See Bug#29093 for the problem with SO_SND/RCVTIMEO on HP/UX.
|
||||
dnl To use alarm is simple, simply avoid setting anything.
|
||||
|
||||
|
||||
AC_CACHE_CHECK([whether SO_SNDTIMEO and SO_RCVTIMEO work],
|
||||
[mysql_cv_socket_timeout],
|
||||
[AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM([[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
]],[[
|
||||
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
struct timeval tv;
|
||||
int ret= 0;
|
||||
tv.tv_sec= 2;
|
||||
tv.tv_usec= 0;
|
||||
ret|= setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||
ret|= setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||
return !!ret;
|
||||
]])],
|
||||
[mysql_cv_socket_timeout=yes],
|
||||
[mysql_cv_socket_timeout=no],
|
||||
[mysql_cv_socket_timeout=no
|
||||
AC_MSG_WARN([Socket timeout options disabled due to cross-compiling])])
|
||||
])
|
||||
|
||||
use_alarm=yes
|
||||
|
||||
if test "$mysql_cv_socket_timeout" = yes; then
|
||||
case $SYSTEM_TYPE in
|
||||
dnl We trust the result from the following systems
|
||||
*solaris*) use_alarm=no ;;
|
||||
*freebsd*) use_alarm=no ;;
|
||||
*darwin*) use_alarm=no ;;
|
||||
*)
|
||||
dnl We trust the result from Linux also
|
||||
if test "$TARGET_LINUX" = "true"; then
|
||||
use_alarm=no
|
||||
fi
|
||||
dnl We trust no one else for the moment
|
||||
dnl (Windows is hardcoded to not use alarms)
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(alarm,
|
||||
AS_HELP_STRING([--with-alarm], [Use alarm to implement socket timeout.]),
|
||||
[use_alarm=$withval], [])
|
||||
|
||||
AC_MSG_CHECKING(whether to use alarms to implement socket timeout)
|
||||
if test "$use_alarm" = no ; then
|
||||
AC_DEFINE([NO_ALARM], [1], [No need to use alarm for socket timeout])
|
||||
AC_DEFINE([SIGNAL_WITH_VIO_CLOSE], [1], [Need to use vio close for kill connection])
|
||||
fi
|
||||
AC_MSG_RESULT($use_alarm)
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Check for IPv6 support
|
||||
#--------------------------------------------------------------------
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
#undef MY_ATOMIC_HAS_8_16
|
||||
|
||||
#include <windows.h>
|
||||
/*
|
||||
x86 compilers (both VS2003 or VS2005) never use instrinsics, but generate
|
||||
function calls to kernel32 instead, even in the optimized build.
|
||||
|
@ -36,19 +37,17 @@
|
|||
#else
|
||||
C_MODE_START
|
||||
/*Visual Studio 2003 and earlier do not have prototypes for atomic intrinsics*/
|
||||
LONG _InterlockedExchange (LONG volatile *Target,LONG Value);
|
||||
LONG _InterlockedCompareExchange (LONG volatile *Target, LONG Value, LONG Comp);
|
||||
LONG _InterlockedExchangeAdd (LONG volatile *Addend, LONG Value);
|
||||
LONGLONG _InterlockedCompareExchange64 (LONGLONG volatile *Target,
|
||||
LONGLONG Value, LONGLONG Comp);
|
||||
C_MODE_END
|
||||
|
||||
#pragma intrinsic(_InterlockedExchangeAdd)
|
||||
#pragma intrinsic(_InterlockedCompareExchange)
|
||||
#pragma intrinsic(_InterlockedExchange)
|
||||
#pragma intrinsic(_InterlockedCompareExchange64)
|
||||
#endif
|
||||
|
||||
#define InterlockedExchange _InterlockedExchange
|
||||
#define InterlockedExchangeAdd _InterlockedExchangeAdd
|
||||
#define InterlockedCompareExchange _InterlockedCompareExchange
|
||||
#define InterlockedCompareExchange64 _InterlockedCompareExchange64
|
||||
/*
|
||||
No need to do something special for InterlockedCompareExchangePointer
|
||||
as it is a #define to InterlockedCompareExchange. The same applies to
|
||||
|
@ -57,23 +56,39 @@ C_MODE_END
|
|||
#endif /*_M_IX86*/
|
||||
|
||||
#define MY_ATOMIC_MODE "msvc-intrinsics"
|
||||
#define IL_EXCHG_ADD32(X,Y) InterlockedExchangeAdd((volatile LONG *)(X),(Y))
|
||||
#define IL_COMP_EXCHG32(X,Y,Z) InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z))
|
||||
/* Implement using CAS on WIN32 */
|
||||
#define IL_COMP_EXCHG32(X,Y,Z) \
|
||||
InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z))
|
||||
#define IL_COMP_EXCHG64(X,Y,Z) \
|
||||
InterlockedCompareExchange64((volatile LONGLONG *)(X), \
|
||||
(LONGLONG)(Y),(LONGLONG)(Z))
|
||||
#define IL_COMP_EXCHGptr InterlockedCompareExchangePointer
|
||||
#define IL_EXCHG32(X,Y) InterlockedExchange((volatile LONG *)(X),(Y))
|
||||
#define IL_EXCHGptr InterlockedExchangePointer
|
||||
#define make_atomic_add_body(S) \
|
||||
v= IL_EXCHG_ADD ## S (a, v)
|
||||
|
||||
#define make_atomic_cas_body(S) \
|
||||
int ## S initial_cmp= *cmp; \
|
||||
int ## S initial_a= IL_COMP_EXCHG ## S (a, set, initial_cmp); \
|
||||
if (!(ret= (initial_a == initial_cmp))) *cmp= initial_a;
|
||||
|
||||
#ifndef _M_IX86
|
||||
/* Use full set of optimised functions on WIN64 */
|
||||
#define IL_EXCHG_ADD32(X,Y) \
|
||||
InterlockedExchangeAdd((volatile LONG *)(X),(Y))
|
||||
#define IL_EXCHG_ADD64(X,Y) \
|
||||
InterlockedExchangeAdd64((volatile LONGLONG *)(X),(LONGLONG)(Y))
|
||||
#define IL_EXCHG32(X,Y) \
|
||||
InterlockedExchange((volatile LONG *)(X),(Y))
|
||||
#define IL_EXCHG64(X,Y) \
|
||||
InterlockedExchange64((volatile LONGLONG *)(X),(LONGLONG)(Y))
|
||||
#define IL_EXCHGptr InterlockedExchangePointer
|
||||
|
||||
#define make_atomic_add_body(S) \
|
||||
v= IL_EXCHG_ADD ## S (a, v)
|
||||
#define make_atomic_swap_body(S) \
|
||||
v= IL_EXCHG ## S (a, v)
|
||||
#define make_atomic_load_body(S) \
|
||||
ret= 0; /* avoid compiler warning */ \
|
||||
ret= IL_COMP_EXCHG ## S (a, ret, ret);
|
||||
|
||||
#endif
|
||||
/*
|
||||
my_yield_processor (equivalent of x86 PAUSE instruction) should be used
|
||||
to improve performance on hyperthreaded CPUs. Intel recommends to use it in
|
||||
|
@ -108,9 +123,12 @@ static __inline int my_yield_processor()
|
|||
#else /* cleanup */
|
||||
|
||||
#undef IL_EXCHG_ADD32
|
||||
#undef IL_EXCHG_ADD64
|
||||
#undef IL_COMP_EXCHG32
|
||||
#undef IL_COMP_EXCHG64
|
||||
#undef IL_COMP_EXCHGptr
|
||||
#undef IL_EXCHG32
|
||||
#undef IL_EXCHG64
|
||||
#undef IL_EXCHGptr
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,6 +22,12 @@
|
|||
architectures support double-word (128-bit) cas.
|
||||
*/
|
||||
|
||||
/*
|
||||
No special support of 8 and 16 bit operations are implemented here
|
||||
currently.
|
||||
*/
|
||||
#undef MY_ATOMIC_HAS_8_AND_16
|
||||
|
||||
#ifdef __x86_64__
|
||||
# ifdef MY_ATOMIC_NO_XADD
|
||||
# define MY_ATOMIC_MODE "gcc-amd64" LOCK_prefix "-no-xadd"
|
||||
|
@ -42,29 +48,79 @@
|
|||
#endif
|
||||
|
||||
#ifndef MY_ATOMIC_NO_XADD
|
||||
#define make_atomic_add_body(S) \
|
||||
asm volatile (LOCK_prefix "; xadd %0, %1;" : "+r" (v) , "+m" (*a))
|
||||
#define make_atomic_add_body(S) make_atomic_add_body ## S
|
||||
#define make_atomic_cas_body(S) make_atomic_cas_body ## S
|
||||
#endif
|
||||
#define make_atomic_fas_body(S) \
|
||||
asm volatile ("xchg %0, %1;" : "+q" (v) , "+m" (*a))
|
||||
#define make_atomic_cas_body(S) \
|
||||
|
||||
#define make_atomic_add_body32 \
|
||||
asm volatile (LOCK_prefix "; xadd %0, %1;" : "+r" (v) , "+m" (*a))
|
||||
|
||||
#define make_atomic_cas_body32 \
|
||||
asm volatile (LOCK_prefix "; cmpxchg %3, %0; setz %2;" \
|
||||
: "+m" (*a), "+a" (*cmp), "=q" (ret): "r" (set))
|
||||
|
||||
#ifdef MY_ATOMIC_MODE_DUMMY
|
||||
#define make_atomic_load_body(S) ret=*a
|
||||
#define make_atomic_store_body(S) *a=v
|
||||
#else
|
||||
#ifdef __x86_64__
|
||||
#define make_atomic_add_body64 make_atomic_add_body32
|
||||
#define make_atomic_cas_body64 make_atomic_cas_body32
|
||||
|
||||
#define make_atomic_fas_body(S) \
|
||||
asm volatile ("xchg %0, %1;" : "+r" (v) , "+m" (*a))
|
||||
|
||||
/*
|
||||
Actually 32-bit reads/writes are always atomic on x86
|
||||
But we add LOCK_prefix here anyway to force memory barriers
|
||||
*/
|
||||
#define make_atomic_load_body(S) \
|
||||
ret=0; \
|
||||
asm volatile (LOCK_prefix "; cmpxchg %2, %0" \
|
||||
: "+m" (*a), "+a" (ret): "r" (ret))
|
||||
#define make_atomic_store_body(S) \
|
||||
#define make_atomic_load_body(S) \
|
||||
ret=0; \
|
||||
asm volatile (LOCK_prefix "; cmpxchg %2, %0" \
|
||||
: "+m" (*a), "+a" (ret): "r" (ret))
|
||||
#define make_atomic_store_body(S) \
|
||||
asm volatile ("; xchg %0, %1;" : "+m" (*a), "+r" (v))
|
||||
|
||||
#else
|
||||
/*
|
||||
Use default implementations of 64-bit operations since we solved
|
||||
the 64-bit problem on 32-bit platforms for CAS, no need to solve it
|
||||
once more for ADD, LOAD, STORE and FAS as well.
|
||||
Since we already added add32 support, we need to define add64
|
||||
here, but we haven't defined fas, load and store at all, so
|
||||
we can fallback on default implementations.
|
||||
*/
|
||||
#define make_atomic_add_body64 \
|
||||
int64 tmp=*a; \
|
||||
while (!my_atomic_cas64(a, &tmp, tmp+v)); \
|
||||
v=tmp;
|
||||
|
||||
/*
|
||||
On some platforms (e.g. Mac OS X and Solaris) the ebx register
|
||||
is held as a pointer to the global offset table. Thus we're not
|
||||
allowed to use the b-register on those platforms when compiling
|
||||
PIC code, to avoid this we push ebx and pop ebx and add a movl
|
||||
instruction to avoid having ebx in the interface of the assembler
|
||||
instruction.
|
||||
|
||||
cmpxchg8b works on both 32-bit platforms and 64-bit platforms but
|
||||
the code here is only used on 32-bit platforms, on 64-bit
|
||||
platforms the much simpler make_atomic_cas_body32 will work
|
||||
fine.
|
||||
*/
|
||||
#define make_atomic_cas_body64 \
|
||||
int32 ebx=(set & 0xFFFFFFFF), ecx=(set >> 32); \
|
||||
asm volatile ("push %%ebx; movl %3, %%ebx;" \
|
||||
LOCK_prefix "; cmpxchg8b %0; setz %2; pop %%ebx"\
|
||||
: "+m" (*a), "+A" (*cmp), "=q" (ret) \
|
||||
:"m" (ebx), "c" (ecx))
|
||||
#endif
|
||||
|
||||
/*
|
||||
The implementation of make_atomic_cas_body32 is adaptable to
|
||||
the OS word size, so on 64-bit platforms it will automatically
|
||||
adapt to 64-bits and so it will work also on 64-bit platforms
|
||||
*/
|
||||
#define make_atomic_cas_bodyptr make_atomic_cas_body32
|
||||
|
||||
#ifdef MY_ATOMIC_MODE_DUMMY
|
||||
#define make_atomic_load_body(S) ret=*a
|
||||
#define make_atomic_store_body(S) *a=v
|
||||
#endif
|
||||
#endif /* ATOMIC_X86_GCC_INCLUDED */
|
||||
|
|
|
@ -30,6 +30,7 @@ extern "C" {
|
|||
/* flags for hash_init */
|
||||
#define HASH_UNIQUE 1 /* hash_insert fails on duplicate key */
|
||||
|
||||
typedef uint my_hash_value_type;
|
||||
typedef uchar *(*my_hash_get_key)(const uchar *,size_t*,my_bool);
|
||||
typedef void (*my_hash_free_key)(void *);
|
||||
|
||||
|
@ -60,8 +61,18 @@ void my_hash_free(HASH *tree);
|
|||
void my_hash_reset(HASH *hash);
|
||||
uchar *my_hash_element(HASH *hash, ulong idx);
|
||||
uchar *my_hash_search(const HASH *info, const uchar *key, size_t length);
|
||||
uchar *my_hash_search_using_hash_value(const HASH *info,
|
||||
my_hash_value_type hash_value,
|
||||
const uchar *key, size_t length);
|
||||
my_hash_value_type my_calc_hash(const HASH *info,
|
||||
const uchar *key, size_t length);
|
||||
uchar *my_hash_first(const HASH *info, const uchar *key, size_t length,
|
||||
HASH_SEARCH_STATE *state);
|
||||
uchar *my_hash_first_from_hash_value(const HASH *info,
|
||||
my_hash_value_type hash_value,
|
||||
const uchar *key,
|
||||
size_t length,
|
||||
HASH_SEARCH_STATE *state);
|
||||
uchar *my_hash_next(const HASH *info, const uchar *key, size_t length,
|
||||
HASH_SEARCH_STATE *state);
|
||||
my_bool my_hash_insert(HASH *info, const uchar *data);
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
my_atomic_store#(&var, what)
|
||||
store 'what' in *var
|
||||
|
||||
'#' is substituted by a size suffix - 8, 16, 32, or ptr
|
||||
'#' is substituted by a size suffix - 8, 16, 32, 64, or ptr
|
||||
(e.g. my_atomic_add8, my_atomic_fas32, my_atomic_casptr).
|
||||
|
||||
NOTE This operations are not always atomic, so they always must be
|
||||
|
@ -49,18 +49,17 @@
|
|||
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.
|
||||
but can be added, if necessary.
|
||||
*/
|
||||
|
||||
#ifndef my_atomic_rwlock_init
|
||||
|
||||
#define intptr void *
|
||||
/**
|
||||
On most platforms we implement 8-bit, 16-bit, 32-bit and "pointer"
|
||||
operations. Thus the symbol below is defined by default; platforms
|
||||
where we leave out 8-bit or 16-bit operations should undefine it.
|
||||
Currently we don't support 8-bit and 16-bit operations.
|
||||
It can be added later if needed.
|
||||
*/
|
||||
#define MY_ATOMIC_HAS_8_16 1
|
||||
#undef MY_ATOMIC_HAS_8_16
|
||||
|
||||
#ifndef MY_ATOMIC_MODE_RWLOCKS
|
||||
/*
|
||||
|
@ -129,6 +128,7 @@
|
|||
make_transparent_unions(8)
|
||||
make_transparent_unions(16)
|
||||
make_transparent_unions(32)
|
||||
make_transparent_unions(64)
|
||||
make_transparent_unions(ptr)
|
||||
#undef uintptr
|
||||
#undef make_transparent_unions
|
||||
|
@ -140,10 +140,12 @@ make_transparent_unions(ptr)
|
|||
#define U_8 int8
|
||||
#define U_16 int16
|
||||
#define U_32 int32
|
||||
#define U_64 int64
|
||||
#define U_ptr intptr
|
||||
#define Uv_8 int8
|
||||
#define Uv_16 int16
|
||||
#define Uv_32 int32
|
||||
#define Uv_64 int64
|
||||
#define Uv_ptr intptr
|
||||
#define U_a volatile *a
|
||||
#define U_cmp *cmp
|
||||
|
@ -217,6 +219,7 @@ make_atomic_cas(8)
|
|||
make_atomic_cas(16)
|
||||
#endif
|
||||
make_atomic_cas(32)
|
||||
make_atomic_cas(64)
|
||||
make_atomic_cas(ptr)
|
||||
|
||||
#ifdef MY_ATOMIC_HAS_8_16
|
||||
|
@ -224,12 +227,14 @@ make_atomic_add(8)
|
|||
make_atomic_add(16)
|
||||
#endif
|
||||
make_atomic_add(32)
|
||||
make_atomic_add(64)
|
||||
|
||||
#ifdef MY_ATOMIC_HAS_8_16
|
||||
make_atomic_load(8)
|
||||
make_atomic_load(16)
|
||||
#endif
|
||||
make_atomic_load(32)
|
||||
make_atomic_load(64)
|
||||
make_atomic_load(ptr)
|
||||
|
||||
#ifdef MY_ATOMIC_HAS_8_16
|
||||
|
@ -237,6 +242,7 @@ make_atomic_fas(8)
|
|||
make_atomic_fas(16)
|
||||
#endif
|
||||
make_atomic_fas(32)
|
||||
make_atomic_fas(64)
|
||||
make_atomic_fas(ptr)
|
||||
|
||||
#ifdef MY_ATOMIC_HAS_8_16
|
||||
|
@ -244,6 +250,7 @@ make_atomic_store(8)
|
|||
make_atomic_store(16)
|
||||
#endif
|
||||
make_atomic_store(32)
|
||||
make_atomic_store(64)
|
||||
make_atomic_store(ptr)
|
||||
|
||||
#ifdef _atomic_h_cleanup_
|
||||
|
@ -254,10 +261,12 @@ make_atomic_store(ptr)
|
|||
#undef U_8
|
||||
#undef U_16
|
||||
#undef U_32
|
||||
#undef U_64
|
||||
#undef U_ptr
|
||||
#undef Uv_8
|
||||
#undef Uv_16
|
||||
#undef Uv_32
|
||||
#undef Uv_64
|
||||
#undef Uv_ptr
|
||||
#undef a
|
||||
#undef cmp
|
||||
|
|
|
@ -876,6 +876,8 @@ typedef SOCKET_SIZE_TYPE size_socket;
|
|||
#endif
|
||||
#endif /* defined (HAVE_LONG_LONG) && !defined(ULONGLONG_MAX)*/
|
||||
|
||||
#define INT_MIN64 (~0x7FFFFFFFFFFFFFFFLL)
|
||||
#define INT_MAX64 0x7FFFFFFFFFFFFFFFLL
|
||||
#define INT_MIN32 (~0x7FFFFFFFL)
|
||||
#define INT_MAX32 0x7FFFFFFFL
|
||||
#define UINT_MAX32 0xFFFFFFFFL
|
||||
|
|
49
mysys/hash.c
49
mysys/hash.c
|
@ -33,16 +33,18 @@ typedef struct st_hash_info {
|
|||
uchar *data; /* data for current entry */
|
||||
} HASH_LINK;
|
||||
|
||||
static uint my_hash_mask(size_t hashnr, size_t buffmax, size_t maxlength);
|
||||
static uint my_hash_mask(my_hash_value_type hashnr,
|
||||
size_t buffmax, size_t maxlength);
|
||||
static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink);
|
||||
static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
|
||||
size_t length);
|
||||
|
||||
static uint calc_hash(const HASH *hash, const uchar *key, size_t length)
|
||||
static my_hash_value_type calc_hash(const HASH *hash,
|
||||
const uchar *key, size_t length)
|
||||
{
|
||||
ulong nr1=1, nr2=4;
|
||||
hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2);
|
||||
return nr1;
|
||||
return (my_hash_value_type)nr1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -179,7 +181,8 @@ my_hash_key(const HASH *hash, const uchar *record, size_t *length,
|
|||
|
||||
/* Calculate pos according to keys */
|
||||
|
||||
static uint my_hash_mask(size_t hashnr, size_t buffmax, size_t maxlength)
|
||||
static uint my_hash_mask(my_hash_value_type hashnr, size_t buffmax,
|
||||
size_t maxlength)
|
||||
{
|
||||
if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
|
||||
return (hashnr & ((buffmax >> 1) -1));
|
||||
|
@ -200,7 +203,7 @@ static
|
|||
#if !defined(__USLC__) && !defined(__sgi)
|
||||
inline
|
||||
#endif
|
||||
unsigned int rec_hashnr(HASH *hash,const uchar *record)
|
||||
my_hash_value_type rec_hashnr(HASH *hash,const uchar *record)
|
||||
{
|
||||
size_t length;
|
||||
uchar *key= (uchar*) my_hash_key(hash, record, &length, 0);
|
||||
|
@ -214,6 +217,21 @@ uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length)
|
|||
return my_hash_first(hash, key, length, &state);
|
||||
}
|
||||
|
||||
uchar* my_hash_search_using_hash_value(const HASH *hash,
|
||||
my_hash_value_type hash_value,
|
||||
const uchar *key,
|
||||
size_t length)
|
||||
{
|
||||
HASH_SEARCH_STATE state;
|
||||
return my_hash_first_from_hash_value(hash, hash_value,
|
||||
key, length, &state);
|
||||
}
|
||||
|
||||
my_hash_value_type my_calc_hash(const HASH *hash,
|
||||
const uchar *key, size_t length)
|
||||
{
|
||||
return calc_hash(hash, key, length ? length : hash->key_length);
|
||||
}
|
||||
/*
|
||||
Search after a record based on a key
|
||||
|
||||
|
@ -223,15 +241,26 @@ uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length)
|
|||
|
||||
uchar* my_hash_first(const HASH *hash, const uchar *key, size_t length,
|
||||
HASH_SEARCH_STATE *current_record)
|
||||
{
|
||||
return my_hash_first_from_hash_value(hash,
|
||||
calc_hash(hash, key, length ? length : hash->key_length),
|
||||
key, length, current_record);
|
||||
}
|
||||
|
||||
uchar* my_hash_first_from_hash_value(const HASH *hash,
|
||||
my_hash_value_type hash_value,
|
||||
const uchar *key,
|
||||
size_t length,
|
||||
HASH_SEARCH_STATE *current_record)
|
||||
{
|
||||
HASH_LINK *pos;
|
||||
uint flag,idx;
|
||||
DBUG_ENTER("my_hash_first");
|
||||
DBUG_ENTER("my_hash_first_from_hash_value");
|
||||
|
||||
flag=1;
|
||||
if (hash->records)
|
||||
{
|
||||
idx= my_hash_mask(calc_hash(hash, key, length ? length : hash->key_length),
|
||||
idx= my_hash_mask(hash_value,
|
||||
hash->blength, hash->records);
|
||||
do
|
||||
{
|
||||
|
@ -331,7 +360,8 @@ static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
|
|||
my_bool my_hash_insert(HASH *info, const uchar *record)
|
||||
{
|
||||
int flag;
|
||||
size_t idx,halfbuff,hash_nr,first_index;
|
||||
size_t idx,halfbuff,first_index;
|
||||
my_hash_value_type hash_nr;
|
||||
uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2);
|
||||
HASH_LINK *data,*empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos;
|
||||
|
||||
|
@ -467,7 +497,8 @@ my_bool my_hash_insert(HASH *info, const uchar *record)
|
|||
|
||||
my_bool my_hash_delete(HASH *hash, uchar *record)
|
||||
{
|
||||
uint blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index;
|
||||
uint blength,pos2,idx,empty_index;
|
||||
my_hash_value_type pos_hashnr, lastpos_hashnr;
|
||||
HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
|
||||
DBUG_ENTER("my_hash_delete");
|
||||
if (!hash->records)
|
||||
|
|
|
@ -22,16 +22,39 @@
|
|||
#include "mysys_priv.h"
|
||||
#include <myisampack.h>
|
||||
|
||||
#ifdef TARGET_OS_SOLARIS
|
||||
/*
|
||||
* On Solaris, memcmp() is normally faster than the unrolled ptr_compare_N
|
||||
* functions, as memcmp() is usually a platform-specific implementation
|
||||
* written in assembler, provided in /usr/lib/libc/libc_hwcap*.so.1.
|
||||
* This implementation is also usually faster than the built-in memcmp
|
||||
* supplied by GCC, so it is recommended to build with "-fno-builtin-memcmp"
|
||||
* in CFLAGS if building with GCC on Solaris.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static int native_compare(size_t *length, unsigned char **a, unsigned char **b)
|
||||
{
|
||||
return memcmp(*a, *b, *length);
|
||||
}
|
||||
|
||||
#else /* TARGET_OS_SOLARIS */
|
||||
|
||||
static int ptr_compare(size_t *compare_length, uchar **a, uchar **b);
|
||||
static int ptr_compare_0(size_t *compare_length, uchar **a, uchar **b);
|
||||
static int ptr_compare_1(size_t *compare_length, uchar **a, uchar **b);
|
||||
static int ptr_compare_2(size_t *compare_length, uchar **a, uchar **b);
|
||||
static int ptr_compare_3(size_t *compare_length, uchar **a, uchar **b);
|
||||
#endif /* TARGET_OS_SOLARIS */
|
||||
|
||||
/* Get a pointer to a optimal byte-compare function for a given size */
|
||||
|
||||
qsort2_cmp get_ptr_compare (size_t size)
|
||||
{
|
||||
#ifdef TARGET_OS_SOLARIS
|
||||
return (qsort2_cmp) native_compare;
|
||||
#else
|
||||
if (size < 4)
|
||||
return (qsort2_cmp) ptr_compare;
|
||||
switch (size & 3) {
|
||||
|
@ -41,6 +64,7 @@ qsort2_cmp get_ptr_compare (size_t size)
|
|||
case 3: return (qsort2_cmp) ptr_compare_3;
|
||||
}
|
||||
return 0; /* Impossible */
|
||||
#endif /* TARGET_OS_SOLARIS */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -132,9 +132,8 @@ post_init_event_thread(THD *thd)
|
|||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
threads.append(thd);
|
||||
thread_count++;
|
||||
thread_running++;
|
||||
inc_thread_running();
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -156,7 +155,7 @@ deinit_event_thread(THD *thd)
|
|||
DBUG_PRINT("exit", ("Event thread finishing"));
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thread_count--;
|
||||
thread_running--;
|
||||
dec_thread_running();
|
||||
delete thd;
|
||||
pthread_cond_broadcast(&COND_thread_count);
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
|
@ -417,7 +416,7 @@ Event_scheduler::start()
|
|||
net_end(&new_thd->net);
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thread_count--;
|
||||
thread_running--;
|
||||
dec_thread_running();
|
||||
delete new_thd;
|
||||
pthread_cond_broadcast(&COND_thread_count);
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
|
@ -550,7 +549,7 @@ error:
|
|||
net_end(&new_thd->net);
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thread_count--;
|
||||
thread_running--;
|
||||
dec_thread_running();
|
||||
delete new_thd;
|
||||
pthread_cond_broadcast(&COND_thread_count);
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
|
|
|
@ -3055,10 +3055,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
|
|||
rpl_filter->db_ok(thd->db))
|
||||
{
|
||||
thd->set_time((time_t)when);
|
||||
thd->set_query((char*)query_arg, q_len_arg);
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->query_id = next_query_id();
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
thd->set_query_and_id((char*)query_arg, q_len_arg, next_query_id());
|
||||
thd->variables.pseudo_thread_id= thread_id; // for temp tables
|
||||
DBUG_PRINT("query",("%s", thd->query()));
|
||||
|
||||
|
@ -4585,9 +4582,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
|
|||
if (rpl_filter->db_ok(thd->db))
|
||||
{
|
||||
thd->set_time((time_t)when);
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->query_id = next_query_id();
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
thd->set_query_id(next_query_id());
|
||||
thd->warning_info->opt_clear_warning_info(thd->query_id);
|
||||
|
||||
TABLE_LIST tables;
|
||||
|
@ -8076,9 +8071,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
|
|||
DBUG_ASSERT(rli->sql_thd == thd);
|
||||
|
||||
/* Step the query id to mark what columns that are actually used. */
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->query_id= next_query_id();
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
thd->set_query_id(next_query_id());
|
||||
|
||||
if (!(memory= my_multi_malloc(MYF(MY_WME),
|
||||
&table_list, (uint) sizeof(RPL_TABLE_LIST),
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "sql_array.h"
|
||||
#include "sql_plugin.h"
|
||||
#include "scheduler.h"
|
||||
#include <my_atomic.h>
|
||||
#include <mysql/psi/mysql_file.h>
|
||||
#ifndef __WIN__
|
||||
#include <netdb.h>
|
||||
|
@ -89,11 +90,60 @@ typedef ulong nesting_map; /* Used for flags of nesting constructs */
|
|||
typedef ulonglong nested_join_map;
|
||||
|
||||
/* query_id */
|
||||
typedef ulonglong query_id_t;
|
||||
typedef int64 query_id_t;
|
||||
extern query_id_t global_query_id;
|
||||
extern int32 thread_running;
|
||||
extern my_atomic_rwlock_t global_query_id_lock;
|
||||
extern my_atomic_rwlock_t thread_running_lock;
|
||||
|
||||
/* increment query_id and return it. */
|
||||
inline query_id_t next_query_id() { return global_query_id++; }
|
||||
inline query_id_t next_query_id()
|
||||
{
|
||||
query_id_t id;
|
||||
my_atomic_rwlock_wrlock(&global_query_id_lock);
|
||||
id= my_atomic_add64(&global_query_id, 1);
|
||||
my_atomic_rwlock_wrunlock(&global_query_id_lock);
|
||||
return (id+1);
|
||||
}
|
||||
|
||||
inline query_id_t get_query_id()
|
||||
{
|
||||
query_id_t id;
|
||||
my_atomic_rwlock_wrlock(&global_query_id_lock);
|
||||
id= my_atomic_load64(&global_query_id);
|
||||
my_atomic_rwlock_wrunlock(&global_query_id_lock);
|
||||
return id;
|
||||
}
|
||||
|
||||
inline int32
|
||||
inc_thread_running()
|
||||
{
|
||||
int32 num_thread_running;
|
||||
my_atomic_rwlock_wrlock(&thread_running_lock);
|
||||
num_thread_running= my_atomic_add32(&thread_running, 1);
|
||||
my_atomic_rwlock_wrunlock(&thread_running_lock);
|
||||
return (num_thread_running+1);
|
||||
}
|
||||
|
||||
inline int32
|
||||
dec_thread_running()
|
||||
{
|
||||
int32 num_thread_running;
|
||||
my_atomic_rwlock_wrlock(&thread_running_lock);
|
||||
num_thread_running= my_atomic_add32(&thread_running, -1);
|
||||
my_atomic_rwlock_wrunlock(&thread_running_lock);
|
||||
return (num_thread_running-1);
|
||||
}
|
||||
|
||||
inline int32
|
||||
get_thread_running()
|
||||
{
|
||||
int32 num_thread_running;
|
||||
my_atomic_rwlock_wrlock(&thread_running_lock);
|
||||
num_thread_running= my_atomic_load32(&thread_running);
|
||||
my_atomic_rwlock_wrunlock(&thread_running_lock);
|
||||
return num_thread_running;
|
||||
}
|
||||
|
||||
/* useful constants */
|
||||
extern MYSQL_PLUGIN_IMPORT const key_map key_map_empty;
|
||||
|
@ -1955,7 +2005,7 @@ extern bool opt_ignore_builtin_innodb;
|
|||
extern my_bool opt_character_set_client_handshake;
|
||||
extern bool volatile abort_loop, shutdown_in_progress;
|
||||
extern bool in_bootstrap;
|
||||
extern uint volatile thread_count, thread_running, global_read_lock;
|
||||
extern uint volatile thread_count, global_read_lock;
|
||||
extern uint connection_count;
|
||||
extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types;
|
||||
extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap;
|
||||
|
|
|
@ -524,7 +524,8 @@ uint mysqld_port_timeout;
|
|||
uint delay_key_write_options, protocol_version;
|
||||
uint lower_case_table_names;
|
||||
uint tc_heuristic_recover= 0;
|
||||
uint volatile thread_count, thread_running;
|
||||
uint volatile thread_count;
|
||||
int32 thread_running;
|
||||
ulonglong thd_startup_options;
|
||||
ulong back_log, connect_timeout, concurrency, server_id;
|
||||
ulong table_cache_size, table_def_size;
|
||||
|
@ -540,6 +541,8 @@ ulonglong max_binlog_cache_size=0;
|
|||
ulong query_cache_size=0;
|
||||
ulong refresh_version; /* Increments on each reload */
|
||||
query_id_t global_query_id;
|
||||
my_atomic_rwlock_t global_query_id_lock;
|
||||
my_atomic_rwlock_t thread_running_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;
|
||||
|
@ -1368,6 +1371,8 @@ void clean_up(bool print_message)
|
|||
DBUG_PRINT("quit", ("Error messages freed"));
|
||||
/* Tell main we are ready */
|
||||
logger.cleanup_end();
|
||||
my_atomic_rwlock_destroy(&global_query_id_lock);
|
||||
my_atomic_rwlock_destroy(&thread_running_lock);
|
||||
(void) pthread_mutex_lock(&LOCK_thread_count);
|
||||
DBUG_PRINT("quit", ("got thread count lock"));
|
||||
ready_to_exit=1;
|
||||
|
@ -7782,6 +7787,8 @@ static int mysql_init_variables(void)
|
|||
what_to_log= ~ (1L << (uint) COM_TIME);
|
||||
refresh_version= 1L; /* Increments on each reload */
|
||||
global_query_id= thread_id= 1L;
|
||||
my_atomic_rwlock_init(&global_query_id_lock);
|
||||
my_atomic_rwlock_init(&thread_running_lock);
|
||||
strmov(server_version, MYSQL_SERVER_VERSION);
|
||||
myisam_recover_options_str= sql_mode_str= "OFF";
|
||||
myisam_stats_method_str= "nulls_unequal";
|
||||
|
|
|
@ -71,8 +71,10 @@
|
|||
|
||||
#if defined(__WIN__) || !defined(MYSQL_SERVER)
|
||||
/* The following is because alarms doesn't work on windows. */
|
||||
#ifndef NO_ALARM
|
||||
#define NO_ALARM
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NO_ALARM
|
||||
#include "my_pthread.h"
|
||||
|
|
17
sql/slave.cc
17
sql/slave.cc
|
@ -1206,6 +1206,8 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
|
|||
mi->clock_diff_with_master=
|
||||
(long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));
|
||||
}
|
||||
else if (check_io_slave_killed(mi->io_thd, mi, NULL))
|
||||
goto slave_killed_err;
|
||||
else if (is_network_error(mysql_errno(mysql)))
|
||||
{
|
||||
mi->report(WARNING_LEVEL, mysql_errno(mysql),
|
||||
|
@ -1258,7 +1260,9 @@ not always make sense; please check the manual before using it).";
|
|||
}
|
||||
else if (mysql_errno(mysql))
|
||||
{
|
||||
if (is_network_error(mysql_errno(mysql)))
|
||||
if (check_io_slave_killed(mi->io_thd, mi, NULL))
|
||||
goto slave_killed_err;
|
||||
else if (is_network_error(mysql_errno(mysql)))
|
||||
{
|
||||
mi->report(WARNING_LEVEL, mysql_errno(mysql),
|
||||
"Get master SERVER_ID failed with error: %s", mysql_error(mysql));
|
||||
|
@ -1329,6 +1333,8 @@ be equal for the Statement-format replication to work";
|
|||
goto err;
|
||||
}
|
||||
}
|
||||
else if (check_io_slave_killed(mi->io_thd, mi, NULL))
|
||||
goto slave_killed_err;
|
||||
else if (is_network_error(mysql_errno(mysql)))
|
||||
{
|
||||
mi->report(WARNING_LEVEL, mysql_errno(mysql),
|
||||
|
@ -1390,6 +1396,8 @@ be equal for the Statement-format replication to work";
|
|||
goto err;
|
||||
}
|
||||
}
|
||||
else if (check_io_slave_killed(mi->io_thd, mi, NULL))
|
||||
goto slave_killed_err;
|
||||
else if (is_network_error(mysql_errno(mysql)))
|
||||
{
|
||||
mi->report(WARNING_LEVEL, mysql_errno(mysql),
|
||||
|
@ -1453,6 +1461,11 @@ network_err:
|
|||
if (master_res)
|
||||
mysql_free_result(master_res);
|
||||
DBUG_RETURN(2);
|
||||
|
||||
slave_killed_err:
|
||||
if (master_res)
|
||||
mysql_free_result(master_res);
|
||||
DBUG_RETURN(2);
|
||||
}
|
||||
|
||||
static bool wait_for_relay_log_space(Relay_log_info* rli)
|
||||
|
@ -2676,7 +2689,7 @@ connected:
|
|||
if (ret == 1)
|
||||
/* Fatal error */
|
||||
goto err;
|
||||
|
||||
|
||||
if (ret == 2)
|
||||
{
|
||||
if (check_io_slave_killed(mi->io_thd, mi, "Slave I/O thread killed"
|
||||
|
|
|
@ -1335,7 +1335,7 @@ sp_head::execute(THD *thd)
|
|||
/* To avoid wiping out thd->change_list on old_change_list destruction */
|
||||
old_change_list.empty();
|
||||
thd->lex= old_lex;
|
||||
thd->query_id= old_query_id;
|
||||
thd->set_query_id(old_query_id);
|
||||
DBUG_ASSERT(!thd->derived_tables);
|
||||
thd->derived_tables= old_derived_tables;
|
||||
thd->variables.sql_mode= save_sql_mode;
|
||||
|
@ -2745,9 +2745,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||
*/
|
||||
thd->lex= m_lex;
|
||||
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->query_id= next_query_id();
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
thd->set_query_id(next_query_id());
|
||||
|
||||
if (thd->prelocked_mode == NON_PRELOCKED)
|
||||
{
|
||||
|
|
|
@ -2555,6 +2555,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
char key[MAX_DBKEY_LENGTH];
|
||||
uint key_length;
|
||||
char *alias= table_list->alias;
|
||||
my_hash_value_type hash_value;
|
||||
HASH_SEARCH_STATE state;
|
||||
DBUG_ENTER("open_table");
|
||||
|
||||
|
@ -2741,6 +2742,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
on disk.
|
||||
*/
|
||||
|
||||
hash_value= my_calc_hash(&open_cache, (uchar*) key, key_length);
|
||||
pthread_mutex_lock(&LOCK_open);
|
||||
|
||||
/*
|
||||
|
@ -2783,8 +2785,11 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
an implicit "pending locks queue" - see
|
||||
wait_for_locked_table_names for details.
|
||||
*/
|
||||
for (table= (TABLE*) my_hash_first(&open_cache, (uchar*) key, key_length,
|
||||
&state);
|
||||
for (table= (TABLE*) my_hash_first_from_hash_value(&open_cache,
|
||||
hash_value,
|
||||
(uchar*) key,
|
||||
key_length,
|
||||
&state);
|
||||
table && table->in_use ;
|
||||
table= (TABLE*) my_hash_next(&open_cache, (uchar*) key, key_length,
|
||||
&state))
|
||||
|
|
|
@ -3273,6 +3273,26 @@ void THD::set_query(char *query_arg, uint32 query_length_arg)
|
|||
pthread_mutex_unlock(&LOCK_thd_data);
|
||||
}
|
||||
|
||||
/** Assign a new value to thd->query and thd->query_id. */
|
||||
|
||||
void THD::set_query_and_id(char *query_arg, uint32 query_length_arg,
|
||||
query_id_t new_query_id)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_thd_data);
|
||||
set_query_inner(query_arg, query_length_arg);
|
||||
query_id= new_query_id;
|
||||
pthread_mutex_unlock(&LOCK_thd_data);
|
||||
}
|
||||
|
||||
/** Assign a new value to thd->query_id. */
|
||||
|
||||
void THD::set_query_id(query_id_t new_query_id)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_thd_data);
|
||||
query_id= new_query_id;
|
||||
pthread_mutex_unlock(&LOCK_thd_data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Mark transaction to rollback and mark error as fatal to a sub-statement.
|
||||
|
|
|
@ -2321,10 +2321,13 @@ public:
|
|||
virtual void set_statement(Statement *stmt);
|
||||
|
||||
/**
|
||||
Assign a new value to thd->query.
|
||||
Assign a new value to thd->query and thd->query_id.
|
||||
Protected with LOCK_thd_data mutex.
|
||||
*/
|
||||
void set_query(char *query_arg, uint32 query_length_arg);
|
||||
void set_query_and_id(char *query_arg, uint32 query_length_arg,
|
||||
query_id_t new_query_id);
|
||||
void set_query_id(query_id_t new_query_id);
|
||||
private:
|
||||
/** The current internal error handler for this thread, or NULL. */
|
||||
Internal_error_handler *m_internal_handler;
|
||||
|
|
|
@ -438,7 +438,7 @@ Sensitive_cursor::fetch(ulong num_rows)
|
|||
thd->derived_tables= derived_tables;
|
||||
thd->open_tables= open_tables;
|
||||
thd->lock= lock;
|
||||
thd->query_id= query_id;
|
||||
thd->set_query_id(query_id);
|
||||
thd->change_list= change_list;
|
||||
/* save references to memory allocated during fetch */
|
||||
thd->set_n_backup_active_arena(this, &backup_arena);
|
||||
|
|
|
@ -482,7 +482,7 @@ static void handle_bootstrap_impl(THD *thd)
|
|||
query= (char *) thd->memdup_w_gap(buff, length + 1,
|
||||
thd->db_length + 1 +
|
||||
QUERY_CACHE_FLAGS_SIZE);
|
||||
thd->set_query(query, length);
|
||||
thd->set_query_and_id(query, length, next_query_id());
|
||||
DBUG_PRINT("query",("%-.4096s",thd->query()));
|
||||
#if defined(ENABLED_PROFILING)
|
||||
thd->profiling.start_new_query();
|
||||
|
@ -493,7 +493,6 @@ static void handle_bootstrap_impl(THD *thd)
|
|||
We don't need to obtain LOCK_thread_count here because in bootstrap
|
||||
mode we have only one thread.
|
||||
*/
|
||||
thd->query_id=next_query_id();
|
||||
thd->set_time();
|
||||
mysql_parse(thd, thd->query(), length, & found_semicolon);
|
||||
close_thread_tables(thd); // Free tables
|
||||
|
@ -915,29 +914,29 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
thd->enable_slow_log= TRUE;
|
||||
thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
|
||||
thd->set_time();
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->query_id= global_query_id;
|
||||
|
||||
switch( command ) {
|
||||
/* Ignore these statements. */
|
||||
case COM_STATISTICS:
|
||||
case COM_PING:
|
||||
break;
|
||||
/* Only increase id on these statements but don't count them. */
|
||||
case COM_STMT_PREPARE:
|
||||
case COM_STMT_CLOSE:
|
||||
case COM_STMT_RESET:
|
||||
next_query_id();
|
||||
break;
|
||||
/* Increase id and count all other statements. */
|
||||
default:
|
||||
statistic_increment(thd->status_var.questions, &LOCK_status);
|
||||
next_query_id();
|
||||
{
|
||||
query_id_t query_id;
|
||||
switch( command ) {
|
||||
/* Ignore these statements. */
|
||||
case COM_STATISTICS:
|
||||
case COM_PING:
|
||||
query_id= get_query_id();
|
||||
break;
|
||||
/* Only increase id on these statements but don't count them. */
|
||||
case COM_STMT_PREPARE:
|
||||
case COM_STMT_CLOSE:
|
||||
case COM_STMT_RESET:
|
||||
query_id= next_query_id() - 1;
|
||||
break;
|
||||
/* Increase id and count all other statements. */
|
||||
default:
|
||||
statistic_increment(thd->status_var.questions, &LOCK_status);
|
||||
query_id= next_query_id() - 1;
|
||||
}
|
||||
thd->set_query_id(query_id);
|
||||
}
|
||||
|
||||
thread_running++;
|
||||
inc_thread_running();
|
||||
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
/**
|
||||
Clear the set of flags that are expected to be cleared at the
|
||||
|
@ -1165,16 +1164,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
thd->security_ctx->priv_user,
|
||||
(char *) thd->security_ctx->host_or_ip);
|
||||
|
||||
thd->set_query(beginning_of_next_stmt, length);
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->set_query_and_id(beginning_of_next_stmt, length, next_query_id());
|
||||
/*
|
||||
Count each statement from the client.
|
||||
*/
|
||||
statistic_increment(thd->status_var.questions, &LOCK_status);
|
||||
thd->query_id= next_query_id();
|
||||
thd->set_time(); /* Reset the query start time. */
|
||||
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
|
||||
}
|
||||
|
||||
|
@ -1488,9 +1484,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
thd_proc_info(thd, "cleaning up");
|
||||
thd->set_query(NULL, 0);
|
||||
thd->command=COM_SLEEP;
|
||||
pthread_mutex_lock(&LOCK_thread_count); // For process list
|
||||
thread_running--;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
dec_thread_running();
|
||||
thd_proc_info(thd, 0);
|
||||
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
|
||||
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
|
||||
|
|
|
@ -48,6 +48,34 @@ pthread_handler_t test_atomic_add(void *arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
volatile int64 a64;
|
||||
/* add and sub a random number in a loop. Must get 0 at the end */
|
||||
pthread_handler_t test_atomic_add64(void *arg)
|
||||
{
|
||||
int m= (*(int *)arg)/2;
|
||||
GCC_BUG_WORKAROUND int64 x;
|
||||
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)
|
||||
{
|
||||
bad= (a64 != 0);
|
||||
pthread_cond_signal(&cond);
|
||||
}
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
1. generate thread number 0..N-1 from b32
|
||||
2. add it to bad
|
||||
|
@ -128,7 +156,7 @@ pthread_handler_t test_atomic_cas(void *arg)
|
|||
|
||||
void do_tests()
|
||||
{
|
||||
plan(4);
|
||||
plan(6);
|
||||
|
||||
bad= my_atomic_initialize();
|
||||
ok(!bad, "my_atomic_initialize() returned %d", bad);
|
||||
|
@ -142,5 +170,14 @@ void do_tests()
|
|||
b32= c32= 0;
|
||||
test_concurrently("my_atomic_cas32", test_atomic_cas, THREADS, CYCLES);
|
||||
|
||||
{
|
||||
int64 b=0x1000200030004000LL;
|
||||
a64=0;
|
||||
my_atomic_add64(&a64, b);
|
||||
ok(a64==b, "add64");
|
||||
}
|
||||
a64=0;
|
||||
test_concurrently("my_atomic_add64", test_atomic_add64, THREADS, CYCLES);
|
||||
|
||||
my_atomic_rwlock_destroy(&rwl);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue