3448 kevin.lewis@stripped 2011-01-20
This is a fix for the Windows vs2008 compile problem that was introduced by rev 3423 (rb://563) of mysql-trunk-innodb. The additional use of os_increment_counter_by_amount() and os_decrement_counter_by_amount() in ha_innodb.cc was rejected in vs2008 since the value being changed is a ulint while the Windows atomics function uses LONG or __int64 depending on whether the OS is 32 or 64 bit. The type ulint is either unsigned __int64 or unsigned long int depending on the OS as well. Since the definition of os_(in/de)crement_counter_by_amount did not have a typedef on the value being changed, it did not compile.
This same error was encountered by RB://538 at one point when similar Windows defines became inline for the first time.
This change is a comprehensive fix for all windows atomic calls so that they are type casted correctly within a UNIV_INLINE function. Type-casting in an inline function is better than typecasting in a macro because the input types are checked by the compiler.
modified:
storage/innobase/include/os0sync.h
storage/innobase/include/os0sync.ic
storage/innobase/include/os0thread.h
3447 Marko Mäkelä 2011-01-21
Move a misplaced debug assertion to the correct function.
This mistake was introduced in bzr revision id
marko.makela@strippedhg.
modified:
storage/innobase/lock/lock0lock.c
=== modified file 'storage/innobase/include/os0sync.h'
--- a/storage/innobase/include/os0sync.h revid:marko.makela@stripped
+++ b/storage/innobase/include/os0sync.h revid:kevin.lewis@strippedm-20110121042226-qv80tfh40uxc7x1f
@@ -398,28 +398,66 @@ Returns the old value of *ptr, atomicall
#define HAVE_ATOMIC_BUILTINS
-/* On Windows, use Windows atomics / interlocked */
-# ifdef _WIN64
-# define win_cmp_and_xchg InterlockedCompareExchange64
-# define win_xchg_and_add InterlockedExchangeAdd64
-# else /* _WIN64 */
-# define win_cmp_and_xchg InterlockedCompareExchange
-# define win_xchg_and_add InterlockedExchangeAdd
-# endif
+/**********************************************************//**
+Atomic compare and exchange of signed integers (both 32 and 64 bit).
+@return value found before the exchange.
+If it is not equal to old_value the exchange did not happen. */
+UNIV_INLINE
+lint
+win_cmp_and_xchg_lint(
+/*==================*/
+ volatile lint* ptr, /*!< in/out: source/destination */
+ lint new_val, /*!< in: exchange value */
+ lint old_val); /*!< in: value to compare to */
+
+/**********************************************************//**
+Atomic addition of signed integers.
+@return Initial value of the variable pointed to by ptr */
+UNIV_INLINE
+lint
+win_xchg_and_add(
+/*=============*/
+ volatile lint* ptr, /*!< in/out: address of destination */
+ lint val); /*!< in: number to be added */
+
+/**********************************************************//**
+Atomic compare and exchange of unsigned integers.
+@return value found before the exchange.
+If it is not equal to old_value the exchange did not happen. */
+UNIV_INLINE
+ulint
+win_cmp_and_xchg_ulint(
+/*===================*/
+ volatile ulint* ptr, /*!< in/out: source/destination */
+ ulint new_val, /*!< in: exchange value */
+ ulint old_val); /*!< in: value to compare to */
+
+/**********************************************************//**
+Atomic compare and exchange of 32 bit unsigned integers.
+@return value found before the exchange.
+If it is not equal to old_value the exchange did not happen. */
+UNIV_INLINE
+DWORD
+win_cmp_and_xchg_dword(
+/*===================*/
+ volatile DWORD* ptr, /*!< in/out: source/destination */
+ DWORD new_val, /*!< in: exchange value */
+ DWORD old_val); /*!< in: value to compare to */
/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
- (win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
+ (win_cmp_and_xchg_ulint(ptr, new_val, old_val) == old_val)
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
- (win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
+ (win_cmp_and_xchg_lint(ptr, new_val, old_val) == old_val)
/* windows thread objects can always be passed to windows atomic functions */
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
- (InterlockedCompareExchange(ptr, new_val, old_val) == old_val)
+ (win_cmp_and_xchg_dword(ptr, new_val, old_val) == old_val)
+
# define INNODB_RW_LOCKS_USE_ATOMICS
# define IB_ATOMICS_STARTUP_MSG \
"Mutexes and rw_locks use Windows interlocked functions"
@@ -432,17 +470,17 @@ amount of increment. */
(win_xchg_and_add(ptr, amount) + amount)
# define os_atomic_increment_ulint(ptr, amount) \
- ((ulint) (win_xchg_and_add(ptr, amount) + amount))
+ ((ulint) (win_xchg_and_add((lint*) ptr, (lint) amount) + amount))
/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount to decrement. There is no atomic substract function on Windows */
# define os_atomic_decrement_lint(ptr, amount) \
- (win_xchg_and_add(ptr, -(lint)amount) - amount)
+ (win_xchg_and_add(ptr, -(lint) amount) - amount)
# define os_atomic_decrement_ulint(ptr, amount) \
- ((ulint) (win_xchg_and_add(ptr, -(lint)amount) - amount))
+ ((ulint) (win_xchg_and_add((lint*) ptr, -(lint) amount) - amount))
/**********************************************************//**
Returns the old value of *ptr, atomically sets *ptr to new_val.
@@ -476,7 +514,7 @@ for synchronization */
(void) os_atomic_increment_ulint(&counter, amount)
#define os_decrement_counter_by_amount(mutex, counter, amount) \
- (void) os_atomic_increment_ulint(&counter, (-((long)(amount))))
+ (void) os_atomic_increment_ulint(&counter, (-((lint) amount)))
#else
#define os_increment_counter_by_amount(mutex, counter, amount) \
do { \
=== modified file 'storage/innobase/include/os0sync.ic'
--- a/storage/innobase/include/os0sync.ic revid:marko.makela@strippedhki0bl1bd8aapoa
+++ b/storage/innobase/include/os0sync.ic revid:kevin.lewis@stripped7x1f
@@ -55,3 +55,85 @@ os_fast_mutex_trylock(
#endif
}
+#ifdef HAVE_WINDOWS_ATOMICS
+
+/* Use inline functions to make 64 and 32 bit versions of windows atomic
+functions so that typecasts are evaluated at compile time. Take advantage
+that lint is either __int64 or long int and windows atomic functions work
+on __int64 and LONG */
+
+/**********************************************************//**
+Atomic compare and exchange of unsigned integers.
+@return value found before the exchange.
+If it is not equal to old_value the exchange did not happen. */
+UNIV_INLINE
+lint
+win_cmp_and_xchg_lint(
+/*==================*/
+ volatile lint* ptr, /*!< in/out: source/destination */
+ lint new_val, /*!< in: exchange value */
+ lint old_val) /*!< in: value to compare to */
+{
+# ifdef _WIN64
+ return(InterlockedCompareExchange64(ptr, new_val, old_val));
+# else
+ return(InterlockedCompareExchange(ptr, new_val, old_val));
+# endif
+}
+
+/**********************************************************//**
+Atomic addition of signed integers.
+@return Initial value of the variable pointed to by ptr */
+UNIV_INLINE
+lint
+win_xchg_and_add(
+/*=============*/
+ volatile lint* ptr, /*!< in/out: address of destination */
+ lint val) /*!< in: number to be added */
+{
+#ifdef _WIN64
+ return(InterlockedExchangeAdd64(ptr, val));
+#else
+ return(InterlockedExchangeAdd(ptr, val));
+#endif
+}
+
+/**********************************************************//**
+Atomic compare and exchange of unsigned integers.
+@return value found before the exchange.
+If it is not equal to old_value the exchange did not happen. */
+UNIV_INLINE
+ulint
+win_cmp_and_xchg_ulint(
+/*===================*/
+ volatile ulint* ptr, /*!< in/out: source/destination */
+ ulint new_val, /*!< in: exchange value */
+ ulint old_val) /*!< in: value to compare to */
+{
+ return((ulint) win_cmp_and_xchg_lint(
+ (volatile lint*) ptr,
+ (lint) new_val,
+ (lint) old_val));
+}
+
+/**********************************************************//**
+Atomic compare and exchange of 32-bit unsigned integers.
+@return value found before the exchange.
+If it is not equal to old_value the exchange did not happen. */
+UNIV_INLINE
+DWORD
+win_cmp_and_xchg_dword(
+/*===================*/
+ volatile DWORD* ptr, /*!< in/out: source/destination */
+ DWORD new_val, /*!< in: exchange value */
+ DWORD old_val) /*!< in: value to compare to */
+{
+ ut_ad(sizeof(DWORD) == sizeof(LONG)); /* We assume this. */
+ return(InterlockedCompareExchange(
+ (volatile LONG*) ptr,
+ (LONG) new_val,
+ (LONG) old_val));
+}
+
+#endif /* HAVE_WINDOWS_ATOMICS */
+
=== modified file 'storage/innobase/include/os0thread.h'
--- a/storage/innobase/include/os0thread.h revid:marko.makela@stripped
+++ b/storage/innobase/include/os0thread.h revid:kevin.lewis@oracle.com-20110121042226-qv80tfh40uxc7x1f
@@ -44,7 +44,7 @@ can wait inside InnoDB */
#ifdef __WIN__
typedef void* os_thread_t;
-typedef unsigned long os_thread_id_t; /*!< In Windows the thread id
+typedef DWORD os_thread_id_t; /*!< In Windows the thread id
is an unsigned long int */
#else
typedef pthread_t os_thread_t;
No bundle (reason: useless for push emails).| Thread |
|---|
| • bzr push into mysql-trunk-innodb branch (kevin.lewis:3447 to 3448) | kevin.lewis | 21 Jan |