Commit 9df32c34 authored by simonmar's avatar simonmar
Browse files

[project @ 2005-11-24 14:21:33 by simonmar]

unlockClosure() requires a write barrier for the compiler - write
barriers aren't required for the CPU, but gcc re-orders non-aliasing
writes unless we use an explicit barrier.

This only just showed up when we started compiling the RTS with -O2.
parent 2d4e9216
......@@ -25,7 +25,7 @@
/*
* XCHG - the atomic exchange instruction. Used for locking closures
* during updates (see LOCK_CLOSURE below) and the MVar primops.
* during updates (see lockClosure() below) and the MVar primops.
*
* NB: the xchg instruction is implicitly locked, so we do not need
* a lock prefix here.
......@@ -57,14 +57,43 @@ cas(StgVolatilePtr p, StgWord o, StgWord n)
return o;
}
/*
* Write barrier - ensure that all preceding writes have happened
* before all following writes.
*
* We need to tell both the compiler AND the CPU about the barrier.
* This is a brute force solution; better results might be obtained by
* using volatile type declarations to get fine-grained ordering
* control in C, and optionally a memory barrier instruction on CPUs
* that require it (not x86 or x86_64).
*/
INLINE_HEADER void
wb(void) {
#if i386_HOST_ARCH || x86_64_HOST_ARCH
__asm__ __volatile__ ("" : : : "memory");
#else
#error memory barriers unimplemented on this architecture
#endif
}
/*
* Locking/unlocking closures
*
* This is used primarily in the implementation of MVars.
*/
#define SPIN_COUNT 4000
INLINE_HEADER StgInfoTable *
lockClosure(StgClosure *p)
{
#if i386_HOST_ARCH || x86_64_HOST_ARCH
StgWord info;
do {
info = xchg((P_)&p->header.info, (W_)&stg_WHITEHOLE_info);
if (info != (W_)&stg_WHITEHOLE_info) return (StgInfoTable *)info;
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
......@@ -76,7 +105,8 @@ INLINE_HEADER void
unlockClosure(StgClosure *p, StgInfoTable *info)
{
#if i386_HOST_ARCH || x86_64_HOST_ARCH
// This is safe enough, because lockClosure() does the memory barrier:
// This is a strictly ordered write, so we need a wb():
wb();
p->header.info = info;
#else
RELEASE_SM_LOCK;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment