Make js_CompareAndSwap visible outside jslock.cpp.
authorAndreas Gal <gal@uci.edu>
Tue, 03 Jun 2008 10:06:28 -0700
changeset 17203 25c9be07232c76c60aa3b7608f6feb7e0fcb7c53
parent 17202 16ffabb5defbb8c5480573e57764c580bef26876
child 17205 acac4e2f37133db3f91904aac9c2aa5eb5d59317
push idunknown
push userunknown
push dateunknown
milestone1.9.1a1pre
Make js_CompareAndSwap visible outside jslock.cpp.
js/src/jslock.cpp
js/src/jslock.h
--- a/js/src/jslock.cpp
+++ b/js/src/jslock.cpp
@@ -79,116 +79,16 @@ js_LockGlobal(void *id)
 
 static void
 js_UnlockGlobal(void *id)
 {
     uint32 i = GLOBAL_LOCK_INDEX(id);
     PR_Unlock(global_locks[i]);
 }
 
-/* Exclude Alpha NT. */
-#if defined(_WIN32) && defined(_M_IX86)
-#pragma warning( disable : 4035 )
-JS_BEGIN_EXTERN_C
-extern long __cdecl
-_InterlockedCompareExchange(long *volatile dest, long exchange, long comp);
-JS_END_EXTERN_C
-#pragma intrinsic(_InterlockedCompareExchange)
-
-static JS_INLINE int
-js_CompareAndSwapHelper(jsword *w, jsword ov, jsword nv)
-{
-    _InterlockedCompareExchange(w, nv, ov);
-    __asm {
-        sete al
-    }
-}
-
-static JS_INLINE int
-js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
-{
-    return (js_CompareAndSwapHelper(w, ov, nv) & 1);
-}
-
-#elif defined(XP_MACOSX) || defined(DARWIN)
-
-#include <libkern/OSAtomic.h>
-
-static JS_INLINE int
-js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
-{
-    /* Details on these functions available in the manpage for atomic */
-#if JS_BYTES_PER_WORD == 8 && JS_BYTES_PER_LONG != 8
-    return OSAtomicCompareAndSwap64Barrier(ov, nv, (int64_t*) w);
-#else
-    return OSAtomicCompareAndSwap32Barrier(ov, nv, (int32_t*) w);
-#endif
-}
-
-#elif defined(__GNUC__) && defined(__i386__)
-
-/* Note: This fails on 386 cpus, cmpxchgl is a >= 486 instruction */
-static JS_INLINE int
-js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
-{
-    unsigned int res;
-
-    __asm__ __volatile__ (
-                          "lock\n"
-                          "cmpxchgl %2, (%1)\n"
-                          "sete %%al\n"
-                          "andl $1, %%eax\n"
-                          : "=a" (res)
-                          : "r" (w), "r" (nv), "a" (ov)
-                          : "cc", "memory");
-    return (int)res;
-}
-
-#elif defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)
-
-static JS_INLINE int
-js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
-{
-#if defined(__GNUC__)
-    unsigned int res;
-    JS_ASSERT(ov != nv);
-    asm volatile ("\
-stbar\n\
-cas [%1],%2,%3\n\
-cmp %2,%3\n\
-be,a 1f\n\
-mov 1,%0\n\
-mov 0,%0\n\
-1:"
-                  : "=r" (res)
-                  : "r" (w), "r" (ov), "r" (nv));
-    return (int)res;
-#else /* !__GNUC__ */
-    extern int compare_and_swap(jsword*, jsword, jsword);
-    JS_ASSERT(ov != nv);
-    return compare_and_swap(w, ov, nv);
-#endif
-}
-
-#elif defined(AIX)
-
-#include <sys/atomic_op.h>
-
-static JS_INLINE int
-js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
-{
-    return !_check_lock((atomic_p)w, ov, nv);
-}
-
-#else
-
-#error "Define NSPR_LOCK if your platform lacks a compare-and-swap instruction."
-
-#endif /* arch-tests */
-
 #endif /* !NSPR_LOCK */
 
 void
 js_InitLock(JSThinLock *tl)
 {
 #ifdef NSPR_LOCK
     tl->owner = 0;
     tl->fat = (JSFatLock*)JS_NEW_LOCK();
--- a/js/src/jslock.h
+++ b/js/src/jslock.h
@@ -110,16 +110,116 @@ struct JSTitle {
  * Atomic increment and decrement for a reference counter, given jsrefcount *p.
  * NB: jsrefcount is int32, aka PRInt32, so that pratom.h functions work.
  */
 #define JS_ATOMIC_INCREMENT(p)      PR_AtomicIncrement((PRInt32 *)(p))
 #define JS_ATOMIC_DECREMENT(p)      PR_AtomicDecrement((PRInt32 *)(p))
 #define JS_ATOMIC_ADD(p,v)          PR_AtomicAdd((PRInt32 *)(p), (PRInt32)(v))
 #define JS_ATOMIC_SET(p,v)          PR_AtomicSet((PRInt32 *)(p), (PRInt32)(v))
 
+/* Exclude Alpha NT. */
+#if defined(_WIN32) && defined(_M_IX86)
+#pragma warning( disable : 4035 )
+JS_BEGIN_EXTERN_C
+extern long __cdecl
+_InterlockedCompareExchange(long *volatile dest, long exchange, long comp);
+JS_END_EXTERN_C
+#pragma intrinsic(_InterlockedCompareExchange)
+
+static JS_INLINE int
+js_CompareAndSwapHelper(jsword *w, jsword ov, jsword nv)
+{
+    _InterlockedCompareExchange(w, nv, ov);
+    __asm {
+        sete al
+    }
+}
+
+static JS_INLINE int
+js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
+{
+    return (js_CompareAndSwapHelper(w, ov, nv) & 1);
+}
+
+#elif defined(XP_MACOSX) || defined(DARWIN)
+
+#include <libkern/OSAtomic.h>
+
+static JS_INLINE int
+js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
+{
+    /* Details on these functions available in the manpage for atomic */
+#if JS_BYTES_PER_WORD == 8 && JS_BYTES_PER_LONG != 8
+    return OSAtomicCompareAndSwap64Barrier(ov, nv, (int64_t*) w);
+#else
+    return OSAtomicCompareAndSwap32Barrier(ov, nv, (int32_t*) w);
+#endif
+}
+
+#elif defined(__GNUC__) && defined(__i386__)
+
+/* Note: This fails on 386 cpus, cmpxchgl is a >= 486 instruction */
+static JS_INLINE int
+js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
+{
+    unsigned int res;
+
+    __asm__ __volatile__ (
+                          "lock\n"
+                          "cmpxchgl %2, (%1)\n"
+                          "sete %%al\n"
+                          "andl $1, %%eax\n"
+                          : "=a" (res)
+                          : "r" (w), "r" (nv), "a" (ov)
+                          : "cc", "memory");
+    return (int)res;
+}
+
+#elif defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)
+
+static JS_INLINE int
+js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
+{
+#if defined(__GNUC__)
+    unsigned int res;
+    JS_ASSERT(ov != nv);
+    asm volatile ("\
+stbar\n\
+cas [%1],%2,%3\n\
+cmp %2,%3\n\
+be,a 1f\n\
+mov 1,%0\n\
+mov 0,%0\n\
+1:"
+                  : "=r" (res)
+                  : "r" (w), "r" (ov), "r" (nv));
+    return (int)res;
+#else /* !__GNUC__ */
+    extern int compare_and_swap(jsword*, jsword, jsword);
+    JS_ASSERT(ov != nv);
+    return compare_and_swap(w, ov, nv);
+#endif
+}
+
+#elif defined(AIX)
+
+#include <sys/atomic_op.h>
+
+static JS_INLINE int
+js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
+{
+    return !_check_lock((atomic_p)w, ov, nv);
+}
+
+#else
+
+#error "Your platform lacks a compare-and-swap instruction."
+
+#endif /* arch-tests */
+
 #define js_CurrentThreadId()        (jsword)PR_GetCurrentThread()
 #define JS_NEW_LOCK()               PR_NewLock()
 #define JS_DESTROY_LOCK(l)          PR_DestroyLock(l)
 #define JS_ACQUIRE_LOCK(l)          PR_Lock(l)
 #define JS_RELEASE_LOCK(l)          PR_Unlock(l)
 #define JS_LOCK0(P,M)               js_Lock(P,M)
 #define JS_UNLOCK0(P,M)             js_Unlock(P,M)
 
@@ -255,16 +355,25 @@ static inline int32 js_NotThreadsafeAtom
     return r;
 }
 
 #define JS_ATOMIC_INCREMENT(p)      (++*(p))
 #define JS_ATOMIC_DECREMENT(p)      (--*(p))
 #define JS_ATOMIC_ADD(p,v)          (*(p) += (v))
 #define JS_ATOMIC_SET(p,v)          (js_NotThreadsafeAtomicAdd((int32*)p, (int32)v))
 
+static JS_INLINE int
+js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
+{
+    if (*w != ov)
+        return 0;
+    *w = nv;
+    return 1;
+}
+
 #define JS_CurrentThreadId() 0
 #define JS_NEW_LOCK()               NULL
 #define JS_DESTROY_LOCK(l)          ((void)0)
 #define JS_ACQUIRE_LOCK(l)          ((void)0)
 #define JS_RELEASE_LOCK(l)          ((void)0)
 #define JS_LOCK0(P,M)               ((void)0)
 #define JS_UNLOCK0(P,M)             ((void)0)