List:Commits« Previous MessageNext Message »
From:kevin.lewis Date:January 21 2011 4:22am
Subject:bzr commit into mysql-trunk-innodb branch (kevin.lewis:3448)
View as plain text  
#At file:///Users/kevinlewis/Work/Mysql/58629/mysql-trunk-innodb/ based on revid:marko.makela@stripped

 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
=== 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@stripped
@@ -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@stripped
+++ b/storage/innobase/include/os0sync.ic	revid:kevin.lewis@stripped
@@ -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@stripped
@@ -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;


Attachment: [text/bzr-bundle] bzr/kevin.lewis@oracle.com-20110121042226-qv80tfh40uxc7x1f.bundle
Thread
bzr commit into mysql-trunk-innodb branch (kevin.lewis:3448) kevin.lewis21 Jan