3 <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
4 <title>The GHC Commentary - The Multi-threaded runtime, and multiprocessor execution</title>
8 <h1>The GHC Commentary - The Multi-threaded runtime, and multiprocessor execution</h1>
10 <p>This section of the commentary explains the structure of the runtime system
11 when used in threaded or SMP mode.</p>
13 <p>The <em>threaded</em> version of the runtime supports
14 bound threads and non-blocking foreign calls, and an overview of its
15 design can be found in the paper <a
16 href="http://www.haskell.org/~simonmar/papers/conc-ffi.pdf">Extending
17 the Haskell Foreign Function Interface with Concurrency</a>. To
18 compile the runtime with threaded support, add the line
20 <pre>GhcRTSWays += thr</pre>
22 to <tt>mk/build.mk</tt>. When building C code in the runtime for the threaded way,
23 the symbol <tt>THREADED_RTS</tt> is defined (this is arranged by the
24 build system when building for way <tt>thr</tt>, see
25 <tt>mk/config.mk</tt>). To build a Haskell program
26 with the threaded runtime, pass the flag <tt>-threaded</tt> to GHC (this
27 can be used in conjunction with <tt>-prof</tt>, and possibly
28 <tt>-debug</tt> and others depending on which versions of the RTS have
31 <p>The <em>SMP</em> version runtime supports the same facilities as the
32 threaded version, and in addition supports execution of Haskell code by
33 multiple simultaneous OS threads. For SMP support, both the runtime and
34 the libraries must be built a special way: add the lines
40 to <tt>mk/build.mk</tt>. To build Haskell code for
41 SMP execution, use the flag <tt>-smp</tt> to GHC (this can be used in
42 conjunction with <tt>-debug</tt>, but no other way-flags at this time).
43 When building C code in the runtime for SMP
44 support, the symbol <tt>SMP</tt> is defined (this is arranged by the
45 compiler when the <tt>-smp</tt> flag is given, see
46 <tt>ghc/compiler/main/StaticFlags.hs</tt>).</p>
48 <p>When building the runtime in either the threaded or SMP ways, the symbol
49 <tt>RTS_SUPPORTS_THREADS</tt> will be defined (see <tt>Rts.h</tt>).</p>
51 <h2>Overall design</h2>
53 <p>The system is based around the notion of a <tt>Capability</tt>. A
54 <tt>Capability</tt> is an object that represents both the permission to
55 execute some Haskell code, and the state required to do so. In order
56 to execute some Haskell code, a thread must therefore hold a
57 <tt>Capability</tt>. The available pool of capabilities is managed by
58 the <tt>Capability</tt> API, described below.</p>
60 <p>In the threaded runtime, there is only a single <tt>Capabililty</tt> in the
61 system, indicating that only a single thread can be executing Haskell
62 code at any one time. In the SMP runtime, there can be an arbitrary
63 number of capabilities selectable at runtime with the <tt>+RTS -N<em>n</em></tt>
64 flag; in practice the number is best chosen to be the same as the number of
65 processors on the host machine.</p>
67 <p>There are a number of OS threads running code in the runtime. We call
68 these <em>tasks</em> to avoid confusion with Haskell <em>threads</em>.
69 Tasks are managed by the <tt>Task</tt> subsystem, which is mainly
70 concerned with keeping track of statistics such as how much time each
71 task spends executing Haskell code, and also keeping track of how many
72 tasks are around when we want to shut down the runtime.</p>
74 <p>Some tasks are created by the runtime itself, and some may be here
75 as a result of a call to Haskell from foreign code (we
76 call this an in-call). The
77 runtime can support any number of concurrent foreign in-calls, but the
78 number of these calls that will actually run Haskell code in parallel is
79 determined by the number of available capabilities. Each in-call creates
80 a <em>bound thread</em>, as described in the FFI/Concurrency paper (cited
83 <p>In the future we may want to bind a <tt>Capability</tt> to a particular
84 processor, so that we can support a notion of affinity - avoiding
85 accidental migration of work from one CPU to another, so that we can make
86 best use of a CPU's local cache. For now, the design ignores this
89 <h2>The <tt>OSThreads</tt> interface</h2>
91 <p>This interface is merely an abstraction layer over the OS-specific APIs
92 for managing threads. It has two main implementations: Win32 and
95 <p>This is the entirety of the interface:</p>
98 /* Various abstract types */
103 extern OSThreadId osThreadId ( void );
104 extern void shutdownThread ( void );
105 extern void yieldThread ( void );
106 extern int createOSThread ( OSThreadId* tid,
107 void (*startProc)(void) );
109 extern void initCondition ( Condition* pCond );
110 extern void closeCondition ( Condition* pCond );
111 extern rtsBool broadcastCondition ( Condition* pCond );
112 extern rtsBool signalCondition ( Condition* pCond );
113 extern rtsBool waitCondition ( Condition* pCond,
116 extern void initMutex ( Mutex* pMut );
119 <h2>The Task interface</h2>
121 <h2>The Capability interface</h2>
123 <h2>Multiprocessor Haskell Execution</h2>