X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=includes%2Fstg%2FSMP.h;h=52fd6f1bc69b99dfc39c168e3e2d55451fb57cfe;hb=9c23f06f3eb925dca063d5102b0ced4a9afe795e;hp=8297f5711c32e1f09ff3151f438da7f4ff72a43c;hpb=d20d32d788e2d6c088e6b03776c428df5bb004d3;p=ghc-hetmet.git diff --git a/includes/stg/SMP.h b/includes/stg/SMP.h index 8297f57..52fd6f1 100644 --- a/includes/stg/SMP.h +++ b/includes/stg/SMP.h @@ -64,6 +64,13 @@ EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p); */ EXTERN_INLINE StgWord atomic_dec(StgVolatilePtr p); +/* + * Busy-wait nop: this is a hint to the CPU that we are currently in a + * busy-wait loop waiting for another CPU to change something. On a + * hypertreaded CPU it should yield to another thread, for example. + */ +EXTERN_INLINE void busy_wait_nop(void); + #endif // !IN_STG_CODE /* @@ -216,6 +223,17 @@ atomic_dec(StgVolatilePtr p) #endif } +EXTERN_INLINE void +busy_wait_nop(void) +{ +#if defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH) + __asm__ __volatile__ ("rep; nop"); + // +#else + // nothing +#endif +} + #endif // !IN_STG_CODE /* @@ -275,6 +293,12 @@ load_load_barrier(void) { #endif } +// Load a pointer from a memory location that might be being modified +// concurrently. This prevents the compiler from optimising away +// multiple loads of the memory location, as it might otherwise do in +// a busy wait loop for example. +#define VOLATILE_LOAD(p) (*((StgVolatilePtr)(p))) + /* ---------------------------------------------------------------------- */ #else /* !THREADED_RTS */ @@ -282,6 +306,7 @@ load_load_barrier(void) { #define store_load_barrier() /* nothing */ #define load_load_barrier() /* nothing */ +#if !IN_STG_CODE || IN_STGCRUN INLINE_HEADER StgWord xchg(StgPtr p, StgWord w) { @@ -290,7 +315,8 @@ xchg(StgPtr p, StgWord w) return old; } -STATIC_INLINE StgWord +EXTERN_INLINE StgWord cas(StgVolatilePtr p, StgWord o, StgWord n); +EXTERN_INLINE StgWord cas(StgVolatilePtr p, StgWord o, StgWord n) { StgWord result; @@ -312,6 +338,9 @@ atomic_dec(StgVolatilePtr p) { return --(*p); } +#endif + +#define VOLATILE_LOAD(p) ((StgWord)*((StgWord*)(p))) #endif /* !THREADED_RTS */