Blob Blame History Raw
From 7c6b1e1f5ed08361d3926e672a5a5129ee51c6d3 Mon Sep 17 00:00:00 2001
From: Hiram Chirino <hiram@hiramchirino.com>
Date: Mon, 9 Sep 2013 11:31:08 -0400
Subject: [PATCH 5/5] Should fix issue #7.  We now do a write barrier before
 setting the 'cached' field to 1 so that reader don't see this get re-ordered
 before all the fields are readable.

---
 .../hawtjni/generator/StructsGenerator.java           |  2 ++
 hawtjni-generator/src/main/resources/hawtjni.h        | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/StructsGenerator.java b/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/StructsGenerator.java
index d8d591e..c12063c 100755
--- a/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/StructsGenerator.java
+++ b/hawtjni-generator/src/main/java/org/fusesource/hawtjni/generator/StructsGenerator.java
@@ -240,6 +240,8 @@ public class StructsGenerator extends JNIGenerator {
                 output("\"");
             outputln(");");
         }
+        // Makes sure compiler/cpu does not reorder the following write before the previous updates are done.
+        outputln("\thawtjni_w_barrier();");
         output("\t");
         output(simpleName);
         outputln("Fc.cached = 1;");
diff --git a/hawtjni-generator/src/main/resources/hawtjni.h b/hawtjni-generator/src/main/resources/hawtjni.h
index 79ae703..c8ba601 100755
--- a/hawtjni-generator/src/main/resources/hawtjni.h
+++ b/hawtjni-generator/src/main/resources/hawtjni.h
@@ -168,6 +168,25 @@ void throwOutOfMemory(JNIEnv *env);
   #endif 
 #endif /* JNI64 */
 
+#ifdef __GNUC__
+  #define hawtjni_w_barrier() __sync_synchronize()
+#elif defined(SOLARIS2) && SOLARIS2 >= 10
+  #include <mbarrier.h>
+  #define hawtjni_w_barrier() __machine_w_barrier()
+#elif defined(__APPLE__)
+  #include <libkern/OSAtomic.h>
+  #define hawtjni_w_barrier() OSMemoryBarrier()
+#elif defined(_WIN32) || defined(_WIN64)
+  #include <intrin.h>
+  #define hawtjni_w_barrier() _mm_sfence(); _WriteBarrier()
+#else
+  #pragma message ( "Don't know how to do a memory barrier on this platform" )
+  #define hawtjni_w_barrier()
+#endif
+
+void hawtjni_atomic_set(jlong *target, jlong value);
+jlong hawtjni_atomic_get(jlong *target);
+
 #ifdef __cplusplus
 }
 #endif 
-- 
1.8.1.4