diff options
author | simonmar <unknown> | 1999-11-02 15:06:05 +0000 |
---|---|---|
committer | simonmar <unknown> | 1999-11-02 15:06:05 +0000 |
commit | f6692611aad945e46ffb615bde1df7def3fc742f (patch) | |
tree | 04e2e2af9c43eba1b60312b89eb3ac8f34209e2c /ghc/includes/SMP.h | |
parent | 947d2e363f75e9e230d535c876ecdafba45174b5 (diff) | |
download | haskell-f6692611aad945e46ffb615bde1df7def3fc742f.tar.gz |
[project @ 1999-11-02 15:05:38 by simonmar]
This commit adds in the current state of our SMP support. Notably,
this allows the new way 's' to be built, providing support for running
multiple Haskell threads simultaneously on top of any pthreads
implementation, the idea being to take advantage of commodity SMP
boxes.
Don't expect to get much of a speedup yet; due to the excessive
locking required to synchronise access to mutable heap objects, you'll
see a slowdown in most cases, even on a UP machine. The best I've
seen is a 1.6-1.7 speedup on an example that did no locking (two
optimised nfibs in parallel).
- new RTS -N flag specifies how many pthreads to start.
- new driver -smp flag, tells the driver to use way 's'.
- new compiler -fsmp option (not for user comsumption)
tells the compiler not to generate direct jumps to
thunk entry code.
- largely rewritten scheduler
- _ccall_GC is now done by handing back a "token" to the
RTS before executing the ccall; it should now be possible
to execute blocking ccalls in the current thread while
allowing the RTS to continue running Haskell threads as
normal.
- you can only call thread-safe C libraries from a way 's'
build, of course.
Pthread support is still incomplete, and weird things (including
deadlocks) are likely to happen.
Diffstat (limited to 'ghc/includes/SMP.h')
-rw-r--r-- | ghc/includes/SMP.h | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/ghc/includes/SMP.h b/ghc/includes/SMP.h new file mode 100644 index 0000000000..fa247988cf --- /dev/null +++ b/ghc/includes/SMP.h @@ -0,0 +1,91 @@ +/* ---------------------------------------------------------------------------- + * $Id: SMP.h,v 1.1 1999/11/02 15:05:52 simonmar Exp $ + * + * (c) The GHC Team, 1999 + * + * Macros for SMP support + * + * -------------------------------------------------------------------------- */ + +#ifndef SMP_H +#define SMP_H + +/* SMP is currently not compatible with the following options: + * + * INTERPRETER + * PROFILING + * TICKY_TICKY + * and unregisterised builds. + */ + +#if defined(SMP) + +#if defined(INTERPRETER) \ + || defined(PROFILING) \ + || defined(TICKY_TICKY) +#error Build options incompatible with SMP. +#endif + +/* + * CMPXCHG - this instruction is the standard "test & set". We use it + * for locking closures in the thunk and blackhole entry code. If the + * closure is already locked, or has an unexpected info pointer + * (because another thread is altering it in parallel), we just jump + * to the new entry point. + */ +#if defined(i386_TARGET_ARCH) && defined(TABLES_NEXT_TO_CODE) +#define CMPXCHG(p, cmp, new) \ + __asm__ __volatile__ ( \ + "lock ; cmpxchg %1, %0\n" \ + "\tje 1f\n" \ + "\tjmp *%%eax\n" \ + "\t1:\n" \ + : /* no outputs */ \ + : "m" (p), "r" (new), "r" (cmp) \ + ) + +/* + * XCHG - the atomic exchange instruction. Used for locking closures + * during updates (see LOCK_CLOSURE below) and the MVar primops. + */ +#define XCHG(reg, obj) \ + __asm__ __volatile__ ( \ + "xchgl %1,%0" \ + :"+r" (reg), "+m" (obj) \ + : /* no input-only operands */ \ + ) + +#else +#error SMP macros not defined for this architecture +#endif + +/* + * LOCK_CLOSURE locks the specified closure, busy waiting for any + * existing locks to be cleared. + */ +#define LOCK_CLOSURE(c) \ + ({ \ + const StgInfoTable *__info; \ + __info = &WHITEHOLE_info; \ + do { \ + XCHG(__info,((StgClosure *)(c))->header.info); \ + } while (__info == &WHITEHOLE_info); \ + __info; \ + }) + +#define LOCK_THUNK(__info) \ + CMPXCHG(R1.cl->header.info, __info, &WHITEHOLE_info); + +#define ACQUIRE_LOCK(mutex) pthread_mutex_lock(mutex); +#define RELEASE_LOCK(mutex) pthread_mutex_unlock(mutex); + +#else /* !SMP */ + +#define LOCK_CLOSURE(c) /* nothing */ +#define LOCK_THUNK(__info) /* nothing */ +#define ACQUIRE_LOCK(mutex) /* nothing */ +#define RELEASE_LOCK(mutex) /* nothing */ + +#endif /* SMP */ + +#endif /* SMP_H */ |