List:Commits« Previous MessageNext Message »
From:guilhem Date:May 24 2007 10:23pm
Subject:bk commit into 5.1 tree (guilhem:1.2579)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of . When  does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-05-24 22:23:20+02:00, guilhem@mysqlwin32. +21 -0
  Making libmytap compile under Windows.
  Making all unit tests (mysys, examples) compile and pass under Windows.
  Using Interlocked* intrinsics to implement my_atomic functions under
  Windows.
  Speed stats when running my_atomic-t in Release build:
  Interlocked* is 150-200 times faster than rwlocks,
  and 17-60% slower than hand-written assembler on Linux (same machine).
  It has not been said where this would be pushed:
  - does not have to be 5.1 as only online backup uses my_atomic
  - but having unit tests working on Windows is interesting even in 5.1
  as 5.1 uses my_bitmap and base64 modules which are covered in these
  unit tests. When this patch is approved I can ask authorities.
  And when it is pushed, unit tests can be enabled in pushbuild's
  Win32 hosts, and also Win64 hosts (I don't have Win64).

  CMakeLists.txt@stripped, 2007-05-24 22:23:10+02:00, guilhem@mysqlwin32. +10 -0
    Pass /Oi to Visual Studio so that it considers inlining intrinsics
    (used in my_atomic).
    We now build unit tests under Windows.

  include/atomic/dummy.h@stripped, 2007-05-24 22:23:16+02:00, guilhem@mysqlwin32. +22 -0
    file with definitions common between MY_ATOMIC_MODE_DUMMY and
    MY_ATOMIC_MODE_RWLOCKS atomic mode (after all both modes can use the
    same code, whether it is wrapped with rwlocks or not).
    Note the "#ifndef make_..." as for example x86-gcc.h defines some bodies
    itself even in MY_ATOMIC_MODE_DUMMY mode.

  include/atomic/dummy.h@stripped, 2007-05-24 22:23:16+02:00, guilhem@mysqlwin32. +0 -0

  include/atomic/nolock.h@stripped, 2007-05-24 22:23:10+02:00, guilhem@mysqlwin32. +2 -16
    As we're using compiler intrinsics on Windows (and not asm), no need
    to define LOCK. And no need to limit to _M_IX86 as it should also
    work fine on 64-bit.
    Empty struct does not compile on Windows, using char instead.

  include/atomic/rwlock.h@stripped, 2007-05-24 22:23:11+02:00, guilhem@mysqlwin32. +10 -28
    pthread_rwlock_t does not exist on Windows; using rw_lock_t instead.
    Now we don't enter rwlock.h if MY_ATOMIC_MODE_DUMMY is defined.

  include/atomic/x86-msvc.h@stripped, 2007-05-24 22:23:11+02:00, guilhem@mysqlwin32. +43 -71
    Implementing my_atomic operations using inline compiler intrinsics
    offered by Visual Studio at least 2003 and 2005.

  include/my_atomic.h@stripped, 2007-05-24 22:23:10+02:00, guilhem@mysqlwin32. +47 -15
    comments.
    Changing the logic of the file: the old logic required that if an
    implementation defined at least one primitive in MY_ATOMIC_MODE_DUMMY
    then it defines all of them (case of x86-gcc.h). So some identical dummy
    code was found in x86-gcc.h and rwlocks.h (my_atomic_add). Also,
    identical code to define my_atomic_rwlock_* macros as empty was found in
    nolock.h and rwlocks.h. To reduce code duplication, the new logic is:
    - unless rwlocks are requested, try nolocks.h (no change)
    - then create the missing primitives:
      * if in dummy mode or my_atomic_cas was created, rwlocks won't be
      used, so define my_atomic_wrlock_* as empty.
      * if in dummy mode, create the missing primitives (0 or more: "all"
      for x86-msvc.h, "0 or 1" (my_atomic_add) for x86-gcc.h) using dummy
      code
      * otherwise, if my_atomic_cas was created, create the missing
      primitives (0 or more) using already created my_atomic_ primitives. 
      * otherwise, use rwlocks (no change); rwlocks.h is not responsible
      anymore for handling dummy primitives' creation.
    8-bit and 16-bit variants of atomic operations are not available
    as compiler intrinsics on Windows (only 32, 64 and Pointer are),
    so we don't try to define them (we're not using them anywhere).

  mysys/CMakeLists.txt@stripped, 2007-05-24 22:23:11+02:00, guilhem@mysqlwin32. +2 -1
    my_atomic.c and my_getncpus.c were missing from mysys on Windows

  mysys/my_atomic.c@stripped, 2007-05-24 22:23:11+02:00, guilhem@mysqlwin32. +6 -1
    to have my_getncpus() it needs my_sys.h

  mysys/my_getncpus.c@stripped, 2007-05-24 22:23:12+02:00, guilhem@mysqlwin32. +16 -3
    implementation of my_getncpus() under Windows (thanks Miguel and Shane,
    who gave solutions a few seconds after I asked!)

  unittest/examples/CMakeLists.txt@stripped, 2007-05-24 22:23:16+02:00, guilhem@mysqlwin32. +40
-0
    We now build examples unit tests on Windows

  unittest/examples/CMakeLists.txt@stripped, 2007-05-24 22:23:16+02:00, guilhem@mysqlwin32. +0
-0

  unittest/examples/core-t.c@stripped, 2007-05-24 22:23:12+02:00, guilhem@mysqlwin32. +1 -1
    my_config.h is for Unix

  unittest/examples/no_plan-t.c@stripped, 2007-05-24 22:23:13+02:00, guilhem@mysqlwin32. +1 -1
    my_config.h is for Unix

  unittest/examples/skip_all-t.c@stripped, 2007-05-24 22:23:13+02:00, guilhem@mysqlwin32. +1 -1
    my_config.h is for Unix

  unittest/examples/todo-t.c@stripped, 2007-05-24 22:23:13+02:00, guilhem@mysqlwin32. +1 -1
    my_config.h is for Unix

  unittest/mysys/CMakeLists.txt@stripped, 2007-05-24 22:23:15+02:00, guilhem@mysqlwin32. +31 -0
    We now build mysys unit tests on Windows

  unittest/mysys/CMakeLists.txt@stripped, 2007-05-24 22:23:15+02:00, guilhem@mysqlwin32. +0 -0

  unittest/mysys/bitmap-t.c@stripped, 2007-05-24 22:23:14+02:00, guilhem@mysqlwin32. +1 -0
    MY_BITMAP structure contains a mutex so needs my_sys.h

  unittest/mysys/my_atomic-t.c@stripped, 2007-05-24 22:23:14+02:00, guilhem@mysqlwin32. +1 -0
    my_atomic-t.c uses pthread_mutex* calls, which may be safemutex ones,
    so needs a MY_INIT() (which initializes safemutex library); without
    that, crash on Windows.

  unittest/mytap/CMakeLists.txt@stripped, 2007-05-24 22:23:15+02:00, guilhem@mysqlwin32. +23 -0
    we now build libmytap on Windows

  unittest/mytap/CMakeLists.txt@stripped, 2007-05-24 22:23:15+02:00, guilhem@mysqlwin32. +0 -0

  unittest/mytap/tap.c@stripped, 2007-05-24 22:23:14+02:00, guilhem@mysqlwin32. +10 -3
    my_config.h is for Unix.
    Visual Studio 2003 does not know vsprintf, so we use _vsnprintf. I don't
    put that in config-win.h because generally we should use my_vsnprintf(),
    not vsnprintf(); on the other hand, I didn't want to replace
    vsnprintf() by my_vsnprintf() in tap.c as it would have required to
    link all unit tests with mysys.
    SIGBUS not known on Windows.

  unittest/mytap/tap.h@stripped, 2007-05-24 22:23:15+02:00, guilhem@mysqlwin32. +3 -3
    Fix for compiler warnings (there were differences in prototypes
    between tap.c and tap.h).

  unittest/unit.pl@stripped, 2007-05-24 22:23:12+02:00, guilhem@mysqlwin32. +2 -2
    On Windows, our executables end in ".exe".
    That change was enough to have
    cd unittest; perl unit.pl run mysys
    work fine if using Cygwin's perl. But with Activestate's, it appeared
    that the test program was internally invoked as
    perl -e 'exec @ARGV' mysys/the_test_program
    and ' is not a string delimitor on Windows so the 'exec @ARGV' was
    interpreted as two arguments instead of one. Using " solves this.
    So now the command works with both Cygwin and Activestate.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	guilhem
# Host:	mysqlwin32.
# Root:	C:/mysql-5.1-rpl-atomic-ops
--- New file ---
+++ include/atomic/dummy.h	07/05/24 22:23:16
/* TODO copyright */

/* QQ: better name? common_to_rwlock_and_dummy.h ? */
/* Primitives for my_atomic if MY_ATOMIC_MODE_DUMMY or MY_ATOMIC_RWLOCKS mode */
#if !defined(MY_ATOMIC_MODE_DUMMY) && !defined(MY_ATOMIC_MODE_RWLOCKS)
#error wrong atomic mode
#endif
#ifndef make_atomic_add_body
#define make_atomic_add_body(S)     int ## S sav; sav= *a; *a+= v; v=sav;
#endif
#ifndef make_atomic_swap_body
#define make_atomic_swap_body(S)    int ## S sav; sav= *a; *a= v; v=sav;
#endif
#ifndef make_atomic_cas_body
#define make_atomic_cas_body(S)     if ((ret= (*a == *cmp))) *a= set; else *cmp=*a;
#endif
#ifndef make_atomic_load_body
#define make_atomic_load_body(S)    ret= *a;
#endif
#ifndef make_atomic_store_body
#define make_atomic_store_body(S)   *a= v;
#endif

--- New file ---
+++ unittest/examples/CMakeLists.txt	07/05/24 22:23:16
# Copyright (C) 2006 MySQL AB
# 
# 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

SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")

INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
                    ${CMAKE_SOURCE_DIR}/sql
                    ${CMAKE_SOURCE_DIR}/regex
                    ${CMAKE_SOURCE_DIR}/extra/yassl/include
                    ${CMAKE_SOURCE_DIR}/unittest/mytap)
ADD_EXECUTABLE(simple-t simple-t.c)
TARGET_LINK_LIBRARIES(simple-t mytap)

ADD_EXECUTABLE(skip-t skip-t.c)
TARGET_LINK_LIBRARIES(skip-t mytap)

ADD_EXECUTABLE(todo-t todo-t.c)
TARGET_LINK_LIBRARIES(todo-t mytap)

ADD_EXECUTABLE(skip_all-t skip_all-t.c)
TARGET_LINK_LIBRARIES(skip_all-t mytap)

ADD_EXECUTABLE(no_plan-t no_plan-t.c)
TARGET_LINK_LIBRARIES(no_plan-t mytap)

ADD_EXECUTABLE(core-t core-t.c)
TARGET_LINK_LIBRARIES(core-t mytap)

--- New file ---
+++ unittest/mysys/CMakeLists.txt	07/05/24 22:23:15
# Copyright (C) 2006 MySQL AB
# 
# 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

SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")

INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
                    ${CMAKE_SOURCE_DIR}/sql
                    ${CMAKE_SOURCE_DIR}/regex
                    ${CMAKE_SOURCE_DIR}/extra/yassl/include
                    ${CMAKE_SOURCE_DIR}/unittest/mytap)
ADD_EXECUTABLE(bitmap-t bitmap-t.c)
TARGET_LINK_LIBRARIES(bitmap-t mytap mysys dbug strings)

ADD_EXECUTABLE(base64-t base64-t.c)
TARGET_LINK_LIBRARIES(base64-t mytap mysys dbug strings)

ADD_EXECUTABLE(my_atomic-t my_atomic-t.c)
TARGET_LINK_LIBRARIES(my_atomic-t mytap mysys dbug strings wsock32)

--- New file ---
+++ unittest/mytap/CMakeLists.txt	07/05/24 22:23:15
# Copyright (C) 2006 MySQL AB
# 
# 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

SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")

INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
                    ${CMAKE_SOURCE_DIR}/sql
                    ${CMAKE_SOURCE_DIR}/regex
                    ${CMAKE_SOURCE_DIR}/extra/yassl/include)
ADD_LIBRARY(mytap tap.c)


--- 1.10/unittest/mytap/tap.c	2006-12-23 20:33:31 +01:00
+++ 1.11/unittest/mytap/tap.c	2007-05-24 22:23:14 +02:00
@@ -19,7 +19,7 @@
 
 #include "tap.h"
 
-#include "my_config.h"
+#include "my_global.h"
 
 #include <stdlib.h>
 #include <stdarg.h>
@@ -27,6 +27,11 @@
 #include <string.h>
 #include <signal.h>
 
+/* Visual Studio 2003 does not know vsnprintf but knows _vsnprintf */
+#if defined(_MSC_VER) && ( _MSC_VER == 1310 )
+#define vsnprintf _vsnprintf
+#endif
+
 /**
    @defgroup MyTAP_Internal MyTAP Internals
 
@@ -150,8 +155,10 @@
   { SIGILL,  handle_core_signal },
   { SIGABRT, handle_core_signal },
   { SIGFPE,  handle_core_signal },
-  { SIGSEGV, handle_core_signal },
-  { SIGBUS,  handle_core_signal }
+  { SIGSEGV, handle_core_signal }
+#ifdef SIGBUS
+  , { SIGBUS,  handle_core_signal }
+#endif
 #ifdef SIGXCPU
   , { SIGXCPU, handle_core_signal }
 #endif

--- 1.9/unittest/mytap/tap.h	2006-12-23 20:33:31 +01:00
+++ 1.10/unittest/mytap/tap.h	2007-05-24 22:23:15 +02:00
@@ -84,7 +84,7 @@
    @param count The planned number of tests to run. 
 */
 
-void plan(int count);
+void plan(int const count);
 
 
 /**
@@ -103,7 +103,7 @@
                which case nothing is printed.
 */
 
-void ok(int pass, char const *fmt, ...)
+void ok(int const pass, char const *fmt, ...)
   __attribute__((format(printf,2,3)));
 
 
@@ -135,7 +135,7 @@
    @param reason     A reason for skipping the tests
  */
 
-void skip(int how_many, char const *reason, ...)
+void skip(int how_many, char const *const reason, ...)
     __attribute__((format(printf,2,3)));
 
 

--- 1.5/unittest/examples/no_plan-t.c	2006-12-31 02:28:54 +01:00
+++ 1.6/unittest/examples/no_plan-t.c	2007-05-24 22:23:13 +02:00
@@ -13,7 +13,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
-#include "my_config.h"
+#include <my_global.h>
 
 #include <stdlib.h>
 #include <tap.h>

--- 1.5/unittest/examples/skip_all-t.c	2006-12-31 02:28:54 +01:00
+++ 1.6/unittest/examples/skip_all-t.c	2007-05-24 22:23:13 +02:00
@@ -13,7 +13,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
-#include "my_config.h"
+#include <my_global.h>
 
 #include <stdlib.h>
 #include <tap.h>

--- 1.4/unittest/examples/todo-t.c	2006-12-31 02:28:54 +01:00
+++ 1.5/unittest/examples/todo-t.c	2007-05-24 22:23:13 +02:00
@@ -13,7 +13,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
-#include "my_config.h"
+#include <my_global.h>
 
 #include <stdlib.h>
 #include <tap.h>

--- 1.5/unittest/mysys/bitmap-t.c	2006-12-23 20:33:31 +01:00
+++ 1.6/unittest/mysys/bitmap-t.c	2007-05-24 22:23:14 +02:00
@@ -21,6 +21,7 @@
 #include <tap.h>
 
 #include <my_global.h>
+#include <my_sys.h>
 #include <my_bitmap.h>
 
 #include <string.h>

--- 1.7/unittest/unit.pl	2006-12-31 02:28:54 +01:00
+++ 1.8/unittest/unit.pl	2007-05-24 22:23:12 +02:00
@@ -56,7 +56,7 @@
     my @files;
     find sub { 
         $File::Find::prune = 1 if /^SCCS$/;
-        push(@files, $File::Find::name) if -x _ && /-t\z/;
+        push(@files, $File::Find::name) if -x _ && (/-t\z/ || /-t\.exe\z/);
     }, @dirs;
     return @files;
 }
@@ -92,7 +92,7 @@
     if (@files > 0) {
         # Removing the first './' from the file names
         foreach (@files) { s!^\./!! }
-        $ENV{'HARNESS_PERL_SWITCHES'} .= q" -e 'exec @ARGV'";
+        $ENV{'HARNESS_PERL_SWITCHES'} .= q' -e "exec @ARGV"';
         runtests @files;
     }
 }

--- 1.2/unittest/examples/core-t.c	2006-12-31 02:28:54 +01:00
+++ 1.3/unittest/examples/core-t.c	2007-05-24 22:23:12 +02:00
@@ -13,7 +13,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
-#include "my_config.h"
+#include <my_global.h>
 
 #include <stdlib.h>
 #include <tap.h>

--- 1.27/CMakeLists.txt	2007-04-10 12:51:42 +02:00
+++ 1.28/CMakeLists.txt	2007-05-24 22:23:10 +02:00
@@ -129,6 +129,13 @@
 	       ${CMAKE_CXX_FLAGS_INIT})
 	STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS_DEBUG_INIT 
 	       ${CMAKE_CXX_FLAGS_DEBUG_INIT})
+
+	# enable intrisic functions for my_atomic
+	SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Oi")
+	SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi")
+	SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Oi")
+	SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Oi")
+
 ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR 
       CMAKE_GENERATOR MATCHES "Visual Studio 8")
 
@@ -169,6 +176,9 @@
 ADD_SUBDIRECTORY(server-tools/instance-manager)
 ADD_SUBDIRECTORY(libmysql)
 ADD_SUBDIRECTORY(tests)
+ADD_SUBDIRECTORY(unittest/mytap)
+ADD_SUBDIRECTORY(unittest/examples)
+ADD_SUBDIRECTORY(unittest/mysys)
 
 # disable libmysqld until it's fixed, so we can use Cmake 2.2 and 2.4
 #ADD_SUBDIRECTORY(libmysqld)

--- 1.12/mysys/CMakeLists.txt	2007-03-12 14:55:33 +01:00
+++ 1.13/mysys/CMakeLists.txt	2007-05-24 22:23:11 +02:00
@@ -41,4 +41,5 @@
 				my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
 				my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c
 				rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
-				thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c)
+				thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c
+				my_atomic.c my_getncpus.c)

--- 1.4/include/atomic/nolock.h	2006-12-23 20:33:28 +01:00
+++ 1.5/include/atomic/nolock.h	2007-05-24 22:23:10 +02:00
@@ -13,7 +13,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
-#if defined(__i386__) || defined(_M_IX86)
+#if defined(__i386__) && defined(__GNUC__)
 
 #ifdef MY_ATOMIC_MODE_DUMMY
 #  define LOCK ""
@@ -21,22 +21,8 @@
 #  define LOCK "lock"
 #endif
 
-#ifdef __GNUC__
 #include "x86-gcc.h"
+
 #elif defined(_MSC_VER)
 #include "x86-msvc.h"
 #endif
-#endif
-
-#ifdef make_atomic_cas_body
-
-typedef struct { } 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)
-
-#endif
-

--- 1.3/include/atomic/rwlock.h	2006-12-23 20:33:28 +01:00
+++ 1.4/include/atomic/rwlock.h	2007-05-24 22:23:11 +02:00
@@ -13,36 +13,18 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
-typedef struct {pthread_rwlock_t rw;} my_atomic_rwlock_t;
+typedef struct {rw_lock_t rw;} my_atomic_rwlock_t;
 
 #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
-#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)"
+#error MY_ATOMIC_MODE_DUMMY and MY_ATOMIC_MODE_RWLOCKS are incompatible
 #else
-#define my_atomic_rwlock_destroy(name)     pthread_rwlock_destroy(& (name)->rw)
-#define my_atomic_rwlock_init(name)        pthread_rwlock_init(& (name)->rw, 0)
-#define my_atomic_rwlock_rdlock(name)      pthread_rwlock_rdlock(& (name)->rw)
-#define my_atomic_rwlock_wrlock(name)      pthread_rwlock_wrlock(& (name)->rw)
-#define my_atomic_rwlock_rdunlock(name)    pthread_rwlock_unlock(& (name)->rw)
-#define my_atomic_rwlock_wrunlock(name)    pthread_rwlock_unlock(& (name)->rw)
+#define my_atomic_rwlock_destroy(name)     rwlock_destroy(& (name)->rw)
+#define my_atomic_rwlock_init(name)        my_rwlock_init(& (name)->rw, 0)
+#define my_atomic_rwlock_rdlock(name)      rw_rdlock(& (name)->rw)
+#define my_atomic_rwlock_wrlock(name)      rw_wrlock(& (name)->rw)
+#define my_atomic_rwlock_rdunlock(name)    rw_unlock(& (name)->rw)
+#define my_atomic_rwlock_wrunlock(name)    rw_unlock(& (name)->rw)
 #define MY_ATOMIC_MODE "rwlocks"
-#endif
-
-#define make_atomic_add_body(S)     int ## S sav; sav= *a; *a+= v; v=sav;
-#define make_atomic_swap_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;
 
+#include "dummy.h"
+#endif

--- 1.4/include/atomic/x86-msvc.h	2006-12-23 20:33:28 +01:00
+++ 1.5/include/atomic/x86-msvc.h	2007-05-24 22:23:11 +02:00
@@ -13,84 +13,56 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
-/*
-  XXX 64-bit atomic operations can be implemented using
-  cmpxchg8b, if necessary
-*/
-
-// Would it be better to use intrinsics ?
-// (InterlockedCompareExchange, InterlockedCompareExchange16
-// InterlockedExchangeAdd, InterlockedExchange)
-
 #ifndef _atomic_h_cleanup_
 #define _atomic_h_cleanup_ "atomic/x86-msvc.h"
 
-#define MY_ATOMIC_MODE "msvc-x86" LOCK
-
-#define make_atomic_add_body(S)				\
-  _asm {						\
-    _asm mov   reg_ ## S, v				\
-    _asm LOCK  xadd *a, reg_ ## S			\
-    _asm movzx v, reg_ ## S				\
-  }
-#define make_atomic_cas_body(S)				\
-  _asm {						\
-    _asm mov    areg_ ## S, *cmp			\
-    _asm mov    reg2_ ## S, set				\
-    _asm LOCK cmpxchg *a, reg2_ ## S			\
-    _asm mov    *cmp, areg_ ## S			\
-    _asm setz   al					\
-    _asm movzx  ret, al					\
-  }
-#define make_atomic_swap_body(S)			\
-  _asm {						\
-    _asm mov    reg_ ## S, v				\
-    _asm xchg   *a, reg_ ## S				\
-    _asm mov    v, reg_ ## S				\
-  }
-
-#ifdef MY_ATOMIC_MODE_DUMMY
-#define make_atomic_load_body(S)        ret=*a
-#define make_atomic_store_body(S)       *a=v
-#else
 /*
-  Actually 32-bit reads/writes are always atomic on x86
-  But we add LOCK here anyway to force memory barriers
+  QQ Serg: this file is expected to work fine on x86-64, should it be renamed
+  to msvc.h ?
 */
-#define make_atomic_load_body(S)			\
-  _asm {						\
-    _asm mov    areg_ ## S, 0				\
-    _asm mov    reg2_ ## S, areg_ ## S			\
-    _asm LOCK cmpxchg *a, reg2_ ## S			\
-    _asm mov    ret, areg_ ## S				\
-  }
-#define make_atomic_store_body(S)			\
-  _asm {						\
-    _asm mov    reg_ ## S, v				\
-    _asm xchg   *a, reg_ ## S				\
-  }
-#endif
+/* In dummy mode we just use the generic definitions */
+#ifndef MY_ATOMIC_MODE_DUMMY
 
-#define reg_8           al
-#define reg_16          ax
-#define reg_32          eax
-#define areg_8          al
-#define areg_16         ax
-#define areg_32         eax
-#define reg2_8          bl
-#define reg2_16         bx
-#define reg2_32         ebx
+#define MY_ATOMIC_MODE "msvc-intrinsics"
+/*
+  By compiling with /Oi, we suggest the compiler to use inline versions of
+  Interlocked* functions.
+  QQ Reggie: what would it bring to additionally have #pragma intrinsic(),
+  and use _Interlocked instead of Interlocked? Reading MSDN, it is not
+  clear.
+*/
+#define IL_EXCHG_ADD32   InterlockedExchangeAdd
+#define IL_COMP_EXCHG32  InterlockedCompareExchange
+#define IL_COMP_EXCHGptr InterlockedCompareExchangePointer
+#define IL_EXCHG32       InterlockedExchange
+#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;
+#define make_atomic_swap_body(S) \
+  v= IL_EXCHG ## S (a, v)
+/*
+  We could leave my_atomic.h use its generic definition for my_atomic_load
+  (using my_atomic_cas); however, it's overkill (atomic_load does not need
+  the "if(...) *cmp=..." done in my_atomic_cas).
+  TODO: when my_atomic_load is tested in my_atomic-t.c, benchmark if using
+  my_atomic_cas is indeed slower. Also benchmark other possible
+  implementations (using InterlockedOr[64](a, 0)).
+*/
+#define make_atomic_load_body(S)       \
+  ret= 0; /* avoid compiler warning */ \
+  ret= IL_COMP_EXCHG ## S (a, ret, ret);
 
 #else /* cleanup */
 
-#undef reg_8
-#undef reg_16
-#undef reg_32
-#undef areg_8
-#undef areg_16
-#undef areg_32
-#undef reg2_8
-#undef reg2_16
-#undef reg2_32
-#endif
+#undef IL_EXCHG_ADD32
+#undef IL_COMP_EXCHG32
+#undef IL_COMP_EXCHGptr
+#undef IL_EXCHG32
+#undef IL_EXCHGptr
 
+#endif
+#endif

--- 1.6/include/my_atomic.h	2007-01-28 21:12:55 +01:00
+++ 1.7/include/my_atomic.h	2007-05-24 22:23:10 +02:00
@@ -18,13 +18,50 @@
 #define intptr         void *
 
 #ifndef MY_ATOMIC_MODE_RWLOCKS
+/* we first see if we can build primitives avoiding rwlocks */
 #include "atomic/nolock.h"
 #endif
 
-#ifndef make_atomic_cas_body
-#include "atomic/rwlock.h"
+#if defined(MY_ATOMIC_MODE_DUMMY) || defined(make_atomic_cas_body)
+/*
+  rwlocks will not be used: type my_atomic_rwlock_t and my_atomic_rwlock_*
+  can be made empty.
+  */
+typedef char my_atomic_rwlock_t; /* smallest possible type as not used */
+#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
 
+#ifdef MY_ATOMIC_MODE_DUMMY
+/*
+  This mode can never be enabled by ./configure, one needs to put #define in
+  a source. 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).
+*/
+/* Maybe nolock.h has created some primitives; create missing ones */
+#include "atomic/dummy.h"
+#define MY_ATOMIC_MODE "dummy (non-atomic)"
+
+#elif defined(make_atomic_cas_body)
+/*
+  nolock.h created at least some primitives;
+  use those to build the missing ones.
+*/
+#ifndef make_atomic_load_body
+#define make_atomic_load_body(S)        \
+  ret= 0; /* avoid compiler warning */; \
+  my_atomic_cas ## S(a, &ret, ret);
+#endif
+#ifndef make_atomic_store_body
+/* hopefully if "compare-and-swap" is available then so is "exchange"... */
+#define make_atomic_store_body(S) \
+  (void)(my_atomic_swap ## S(a, v));
+#endif
 #ifndef make_atomic_add_body
 #define make_atomic_add_body(S)					\
   int ## S tmp=*a;                                              \
@@ -32,6 +69,11 @@
   v=tmp;
 #endif
 
+#else
+/* nolock.h didn't create anything, fall back to rwlocks */
+#include "atomic/rwlock.h"
+#endif
+
 #ifdef HAVE_INLINE
 
 #define make_atomic_add(S)					\
@@ -93,29 +135,19 @@
 
 #endif
 
-make_atomic_cas( 8)
-make_atomic_cas(16)
 make_atomic_cas(32)
 make_atomic_cas(ptr)
 
-make_atomic_add( 8)
-make_atomic_add(16)
+make_atomic_swap(32)
+make_atomic_swap(ptr)
+
 make_atomic_add(32)
 
-make_atomic_load( 8)
-make_atomic_load(16)
 make_atomic_load(32)
 make_atomic_load(ptr)
 
-make_atomic_store( 8)
-make_atomic_store(16)
 make_atomic_store(32)
 make_atomic_store(ptr)
-
-make_atomic_swap( 8)
-make_atomic_swap(16)
-make_atomic_swap(32)
-make_atomic_swap(ptr)
 
 #undef make_atomic_add
 #undef make_atomic_cas

--- 1.3/mysys/my_atomic.c	2006-12-23 20:33:28 +01:00
+++ 1.4/mysys/my_atomic.c	2007-05-24 22:23:11 +02:00
@@ -14,7 +14,7 @@
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
 #include <my_global.h>
-#include <my_pthread.h>
+#include <my_sys.h>
 
 #ifndef HAVE_INLINE
 /*
@@ -38,6 +38,11 @@
   DBUG_ASSERT(sizeof(intptr) == sizeof(void *));
   /* currently the only thing worth checking is SMP/UP issue */
 #ifdef MY_ATOMIC_MODE_DUMMY
+  /*
+    QQ: even with one CPU, one thread may be pre-empted when doing the
+    simulated CAS (after seeing that *a and *cmp match, but before setting
+    a). So it's theoretically unsafe. Shouldn't we always fail below?
+  */
   return my_getncpus() == 1 ? MY_ATOMIC_OK : MY_ATOMIC_NOT_1CPU;
 #else
   return MY_ATOMIC_OK;

--- 1.2/mysys/my_getncpus.c	2006-12-23 20:33:28 +01:00
+++ 1.3/mysys/my_getncpus.c	2007-05-24 22:23:12 +02:00
@@ -16,10 +16,23 @@
 /* get the number of (online) CPUs */
 
 #include "mysys_priv.h"
-#include <unistd.h>
-
 static int ncpus=0;
 
+#ifdef __WIN__
+int my_getncpus()
+{
+  if (!ncpus)
+  {
+    SYSTEM_INFO sysinfo;
+    GetSystemInfo(&sysinfo);
+    ncpus= sysinfo.dwNumberOfProcessors;
+  }
+  return ncpus;
+}
+#else
+
+#include <unistd.h>
+
 #ifdef _SC_NPROCESSORS_ONLN
 int my_getncpus()
 {
@@ -36,4 +49,4 @@
 }
 
 #endif
-
+#endif

--- 1.10/unittest/mysys/my_atomic-t.c	2007-03-16 19:43:57 +01:00
+++ 1.11/unittest/mysys/my_atomic-t.c	2007-05-24 22:23:14 +02:00
@@ -161,6 +161,7 @@
 {
   int err;
 
+  MY_INIT("my_atomic-t");
   diag("N CPUs: %d", my_getncpus());
   err= my_atomic_initialize();
 
Thread
bk commit into 5.1 tree (guilhem:1.2579)guilhem24 May