-#define LOCK_CLOSURE(c) \
- ({ \
- const StgInfoTable *__info; \
- __info = &stg_WHITEHOLE_info; \
- do { \
- XCHG(__info,((StgClosure *)(c))->header.info); \
- } while (__info == &stg_WHITEHOLE_info); \
- __info; \
- })
+#define SPIN_COUNT 4000
+
+INLINE_HEADER StgInfoTable *
+lockClosure(StgClosure *p)
+{
+#if i386_HOST_ARCH || x86_64_HOST_ARCH
+ StgWord info;
+ do {
+ nat i = 0;
+ do {
+ info = xchg((P_)&p->header.info, (W_)&stg_WHITEHOLE_info);
+ if (info != (W_)&stg_WHITEHOLE_info) return (StgInfoTable *)info;
+ } while (++i < SPIN_COUNT);
+ yieldThread();
+ } while (1);
+#else
+ ACQUIRE_SM_LOCK
+#endif
+}
+
+INLINE_HEADER void
+unlockClosure(StgClosure *p, StgInfoTable *info)
+{
+#if i386_HOST_ARCH || x86_64_HOST_ARCH
+ // This is a strictly ordered write, so we need a wb():
+ wb();
+ p->header.info = info;
+#else
+ RELEASE_SM_LOCK;
+#endif
+}