summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAlexander Nozdrin <alik@sun.com>2009-12-16 21:50:45 +0300
committerAlexander Nozdrin <alik@sun.com>2009-12-16 21:50:45 +0300
commit134fc397f81bc63508e644c12b815fba46b3d79a (patch)
tree8d7a5ef1e0a652a48c9ffbe317b3ccf832e17855 /include
parent7f6a62ef927ed117ebab2c6821a046851cd58b8f (diff)
parentfdd269ad94943253fc59dcb7b34886292e10b447 (diff)
downloadmariadb-git-134fc397f81bc63508e644c12b815fba46b3d79a.tar.gz
Auto-merge from mysql-next-mr-summit0.3.
Diffstat (limited to 'include')
-rw-r--r--include/atomic/generic-msvc.h44
-rw-r--r--include/atomic/x86-gcc.h84
-rw-r--r--include/hash.h11
-rw-r--r--include/my_atomic.h21
-rw-r--r--include/my_global.h2
5 files changed, 129 insertions, 33 deletions
diff --git a/include/atomic/generic-msvc.h b/include/atomic/generic-msvc.h
index f1e1b0e88c9..a84cde6b2c3 100644
--- a/include/atomic/generic-msvc.h
+++ b/include/atomic/generic-msvc.h
@@ -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
diff --git a/include/atomic/x86-gcc.h b/include/atomic/x86-gcc.h
index 59090bc26b7..32839e0a67d 100644
--- a/include/atomic/x86-gcc.h
+++ b/include/atomic/x86-gcc.h
@@ -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 */
diff --git a/include/hash.h b/include/hash.h
index d870e17c341..515c764214d 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -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);
diff --git a/include/my_atomic.h b/include/my_atomic.h
index 85cf87165fb..23c3dc749ab 100644
--- a/include/my_atomic.h
+++ b/include/my_atomic.h
@@ -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
diff --git a/include/my_global.h b/include/my_global.h
index 976253945aa..81ad947c6b6 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -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