From 3ae8b40f4b2b12337f04a492f351fd3adbe1f750 Mon Sep 17 00:00:00 2001
From: Yoni Fogel <yoni@tokutek.com>
Date: Wed, 2 Jun 2010 00:21:23 +0000
Subject: [PATCH] Fix windows compile. Poison __sync_fetch_and_add and
 __sync_add_and_fetch, wrote toku wrappers and windows equivalents fix bug in
 toku_sync_fetch_and_(in|de)crement_int32 where it returned result instead of
 original

git-svn-id: file:///svn/toku/tokudb@20848 c7de825b-a66e-492c-adef-691d508d4ae1
---
 newbrt/backwards_11.c                         |  5 ++-
 newbrt/tests/brtloader-error-injector.h       | 12 +++---
 .../tests/brtloader-test-merge-files-dbufio.c |  2 +-
 toku_include/toku_atomic.h                    | 39 ++++++++++++++++++-
 toku_include/toku_portability.h               |  6 +++
 windows/inttypes.h                            |  5 +++
 6 files changed, 60 insertions(+), 9 deletions(-)

diff --git a/newbrt/backwards_11.c b/newbrt/backwards_11.c
index 61775119eb..572ce796f2 100644
--- a/newbrt/backwards_11.c
+++ b/newbrt/backwards_11.c
@@ -429,7 +429,10 @@ decompress_work_init_11(struct decompress_work_11 *dw,
 // decompress one block
 static void 
 decompress_block(struct decompress_work_11 *dw) {
-    if (0) printf("%s:%d %x %p\n", __FUNCTION__, __LINE__, (int) toku_pthread_self(), dw);
+    if (0) {
+        toku_pthread_t self = toku_pthread_self();
+        printf("%s:%d %x %p\n", __FUNCTION__, __LINE__, *(int*) &self, dw);
+    }
     uLongf destlen = dw->uncompress_size;
     int r = uncompress(dw->uncompress_ptr, &destlen, dw->compress_ptr, dw->compress_size);
     assert(destlen == dw->uncompress_size);
diff --git a/newbrt/tests/brtloader-error-injector.h b/newbrt/tests/brtloader-error-injector.h
index 12082228cb..b7d87a7eea 100644
--- a/newbrt/tests/brtloader-error-injector.h
+++ b/newbrt/tests/brtloader-error-injector.h
@@ -13,6 +13,8 @@ extern "C" {
 #endif
 #endif
 
+#include "toku_atomic.h"
+
 static int event_count, event_count_trigger;
 
 __attribute__((__unused__))
@@ -26,7 +28,7 @@ static void event_hit(void) {
 
 __attribute__((__unused__))
 static int event_add_and_fetch(void) {
-    return __sync_add_and_fetch(&event_count, 1);
+    return toku_sync_increment_and_fetch_int32(&event_count);
 }
 
 static int do_user_errors = 0;
@@ -103,9 +105,9 @@ static void *my_malloc(size_t n) {
     void *caller = __builtin_return_address(0);
     if (!((void*)toku_malloc <= caller && caller <= (void*)toku_free))
         goto skip;
-    (void) __sync_fetch_and_add(&my_malloc_count, 1); // my_malloc_count++;
+    (void) toku_sync_fetch_and_increment_int32(&my_malloc_count); // my_malloc_count++;
     if (n >= my_big_malloc_limit) {
-        (void) __sync_fetch_and_add(&my_big_malloc_count, 1); // my_big_malloc_count++;
+        (void) toku_sync_fetch_and_increment_int32(&my_big_malloc_count); // my_big_malloc_count++;
         if (do_malloc_errors) {
             caller = __builtin_return_address(1);
             if ((void*)toku_xmalloc <= caller && caller <= (void*)toku_malloc_report)
@@ -128,9 +130,9 @@ static void *my_realloc(void *p, size_t n) {
     void *caller = __builtin_return_address(0);
     if (!((void*)toku_realloc <= caller && caller <= (void*)toku_free))
         goto skip;
-    (void) __sync_add_and_fetch(&my_realloc_count, 1); // my_realloc_count++;
+    (void) toku_sync_increment_and_fetch_int32(&my_realloc_count); // my_realloc_count++;
     if (n >= my_big_malloc_limit) {
-        (void) __sync_add_and_fetch(&my_big_realloc_count, 1); // my_big_realloc_count++;
+        (void) toku_sync_increment_and_fetch_int32(&my_big_realloc_count); // my_big_realloc_count++;
         if (do_realloc_errors) {
             caller = __builtin_return_address(1);
             if ((void*)toku_xrealloc <= caller && caller <= (void*)toku_malloc_report)
diff --git a/newbrt/tests/brtloader-test-merge-files-dbufio.c b/newbrt/tests/brtloader-test-merge-files-dbufio.c
index 758dc9e8a3..1ea2deae97 100644
--- a/newbrt/tests/brtloader-test-merge-files-dbufio.c
+++ b/newbrt/tests/brtloader-test-merge-files-dbufio.c
@@ -286,7 +286,7 @@ static void test (const char *directory, BOOL is_error) {
 	n_records_in_fd[fdi]++;
     }
     for (int i=0; i<N_SOURCES; i++) {
-	off_t r = lseek(fds[i], 0, SEEK_SET);
+	toku_off_t r = lseek(fds[i], 0, SEEK_SET);
 	assert(r==0);
     }
 
diff --git a/toku_include/toku_atomic.h b/toku_include/toku_atomic.h
index 482bc38cf2..5ba73a487b 100644
--- a/toku_include/toku_atomic.h
+++ b/toku_include/toku_atomic.h
@@ -35,14 +35,37 @@ toku_sync_fetch_and_add_int32(volatile int32_t *a, int32_t b) {
 
 static inline int32_t
 toku_sync_fetch_and_increment_int32(volatile int32_t *a) {
-    return _InterlockedIncrement((LONG*)a);
+    int32_t r = _InterlockedIncrement((LONG*)a);
+    //InterlockedIncrement returns the result, not original.
+    //Return the original.
+    return r - 1;
 }
 
 static inline int32_t
 toku_sync_fetch_and_decrement_int32(volatile int32_t *a) {
-    return _InterlockedDecrement((LONG*)a);
+    int32_t r = _InterlockedDecrement((LONG*)a);
+    //InterlockedDecrement returns the result, not original.
+    //Return the original.
+    return r + 1;
+}
+
+static inline int32_t
+toku_sync_increment_and_fetch_int32(volatile int32_t *a) {
+    int32_t r = _InterlockedIncrement((LONG*)a);
+    //InterlockedIncrement returns the result, not original.
+    //Return the result.
+    return r;
+}
+
+static inline int32_t
+toku_sync_decrement_and_fetch_int32(volatile int32_t *a) {
+    int32_t r = _InterlockedDecrement((LONG*)a);
+    //InterlockedDecrement returns the result, not original.
+    //Return the result.
+    return r;
 }
 
+
 #define TOKU_WINDOWS_MIN_SUPPORTED_IS_VISTA 0
 
 //Vista has 64 bit atomic instruction functions.
@@ -110,6 +133,15 @@ static inline int32_t toku_sync_fetch_and_decrement_int32(volatile int32_t *a) {
     return toku_sync_fetch_and_add_int32(a, -1);
 }
 
+static inline int32_t toku_sync_increment_and_fetch_int32(volatile int32_t *a) {
+    return toku_sync_add_and_fetch_int32(a, 1);
+}
+
+static inline int32_t toku_sync_decrement_and_fetch_int32(volatile int32_t *a) {
+    return toku_sync_add_and_fetch_int32(a, -1);
+}
+
+
 #if __GNUC__ && __i386__
 
 // workaround for a gcc 4.1.2 bug on 32 bit platforms.
@@ -129,6 +161,9 @@ static inline uint64_t toku_sync_fetch_and_increment_uint64(volatile uint64_t *a
 
 #endif
 
+DO_GCC_PRAGMA(GCC __sync_fetch_and_add __sync_add_and_fetch)
+
+
 #if defined(__cplusplus) || defined(__cilkplusplus)
 };
 #endif
diff --git a/toku_include/toku_portability.h b/toku_include/toku_portability.h
index eb55e36974..c0cc2da892 100644
--- a/toku_include/toku_portability.h
+++ b/toku_include/toku_portability.h
@@ -33,6 +33,8 @@ extern "C" {
 #if TOKU_WINDOWS
 // Windows
 
+#define DO_GCC_PRAGMA(x)      /* Nothing */
+
 #if defined(__ICL)
 #define __attribute__(x)      /* Nothing */
 #endif
@@ -56,6 +58,8 @@ typedef int64_t toku_off_t;
 
 #elif defined(__INTEL_COMPILER)
 
+#define DO_GCC_PRAGMA(x)      /* Nothing */
+
 #if defined(__ICC)
 // Intel linux
 
@@ -71,6 +75,8 @@ typedef int64_t toku_off_t;
 #elif defined(__GNUC__)
 // GCC linux
 
+#define DO_GCC_PRAGMA(x) _Pragma (#x)
+
 #include <toku_stdint.h>
 #include <unistd.h>
 #include <sys/types.h>
diff --git a/windows/inttypes.h b/windows/inttypes.h
index d0e9dcda76..99696d726e 100644
--- a/windows/inttypes.h
+++ b/windows/inttypes.h
@@ -4,6 +4,11 @@
 #include <stdint.h>
 
 //Define printf types.
+#define SCNd64 "I64d"
+#define SCNu64 "I64u"
+#define SCNd32 "d"
+#define SCNu32 "u"
+
 #define PRId64 "I64d"
 #define PRIu64 "I64u"
 #define PRIx64 "I64x"
-- 
2.30.9