calling arbitrary IO procedures in some part of the program.)
</para>
<para>The Haskell FFI already specifies that arguments and results of
-foreign imports and exports will be automatically unwrapped if they are
+foreign imports and exports will be automatically unwrapped if they are
newtypes (Section 3.2 of the FFI addendum). GHC extends the FFI by automatically unwrapping any newtypes that
wrap the IO monad itself.
More precisely, wherever the FFI specification requires an IO type, GHC will
the time, then the program will not respond to the user
interrupt.
</para>
-
+
<para>
The problem is that it is not possible in general to
interrupt a foreign call safely. However, GHC does provide
of <literal>safe</literal> or <literal>unsafe</literal>:
<programlisting>
-foreign import ccall interruptible
+foreign import ccall interruptible
"sleep" :: CUint -> IO CUint
</programlisting>
- <literal>interruptble</literal> behaves exactly as
+ <literal>interruptible</literal> behaves exactly as
<literal>safe</literal>, except that when
a <literal>throwTo</literal> is directed at a thread in an
interruptible foreign call, an OS-specific mechanism will be
</indexterm>
<para>When GHC compiles a module (say <filename>M.hs</filename>)
- which uses <literal>foreign export</literal> or
+ which uses <literal>foreign export</literal> or
<literal>foreign import "wrapper"</literal>, it generates two
additional files, <filename>M_stub.c</filename> and
<filename>M_stub.h</filename>. GHC will automatically compile
––make</literal>, as GHC will automatically link in the
correct bits).</para>
- <sect3 id="using-own-main">
+ <sect3 id="using-own-main">
<title>Using your own <literal>main()</literal></title>
<para>Normally, GHC's runtime system provides a
#include "foo_stub.h"
#endif
-#ifdef __GLASGOW_HASKELL__
-extern void __stginit_Foo ( void );
-#endif
-
int main(int argc, char *argv[])
{
int i;
hs_init(&argc, &argv);
-#ifdef __GLASGOW_HASKELL__
- hs_add_root(__stginit_Foo);
-#endif
for (i = 0; i < 5; i++) {
printf("%d\n", foo(2500));
(i.e. those arguments between
<literal>+RTS...-RTS</literal>).</para>
- <para>Next, we call
- <function>hs_add_root</function><indexterm><primary><function>hs_add_root</function></primary>
- </indexterm>, a GHC-specific interface which is required to
- initialise the Haskell modules in the program. The argument
- to <function>hs_add_root</function> should be the name of the
- initialization function for the "root" module in your program
- - in other words, the module which directly or indirectly
- imports all the other Haskell modules in the program. In a
- standalone Haskell program the root module is normally
- <literal>Main</literal>, but when you are using Haskell code
- from a library it may not be. If your program has multiple
- root modules, then you can call
- <function>hs_add_root</function> multiple times, one for each
- root. The name of the initialization function for module
- <replaceable>M</replaceable> is
- <literal>__stginit_<replaceable>M</replaceable></literal>, and
- it may be declared as an external function symbol as in the
- code above. Note that the symbol name should be transformed
- according to the Z-encoding:</para>
-
<informaltable>
<tgroup cols="2" align="left" colsep="1" rowsep="1">
<thead>
// Initialize Haskell runtime
hs_init(&argc, &argv);
- // Tell Haskell about all root modules
- hs_add_root(__stginit_Foo);
-
// do any other initialization here and
// return false if there was a problem
return HS_BOOL_TRUE;
</programlisting>
<para>The initialisation routine, <literal>mylib_init</literal>, calls
- <literal>hs_init()</literal> and <literal>hs_add_root()</literal> as
+ <literal>hs_init()</literal> as
normal to initialise the Haskell runtime, and the corresponding
deinitialisation function <literal>mylib_end()</literal> calls
<literal>hs_exit()</literal> to shut down the runtime.</para>
</sect3>
</sect2>
-
+
<sect2 id="glasgow-foreign-headers">
<title>Using header files</title>
available when compiling an inlined version of a foreign call,
so the compiler is free to inline foreign calls in any
context.</para>
-
+
<para>The <literal>-#include</literal> option is now
deprecated, and the <literal>include-files</literal> field
in a Cabal package specification is ignored.</para>
</varlistentry>
</variablelist>
</sect2>
-
+
<sect2 id="ffi-threads">
<title>Multi-threading and the FFI</title>
-
+
<para>In order to use the FFI in a multi-threaded setting, you must
use the <option>-threaded</option> option
(see <xref linkend="options-linker" />).</para>
-
+
<sect3>
<title>Foreign imports and multi-threading</title>
-
+
<para>When you call a <literal>foreign import</literal>ed
function that is annotated as <literal>safe</literal> (the
default), and the program was linked
program was linked without <option>-threaded</option>,
then the other Haskell threads will be blocked until the
call returns.</para>
-
+
<para>This means that if you need to make a foreign call to
a function that takes a long time or blocks indefinitely,
then you should mark it <literal>safe</literal> and
<sect3 id="haskell-threads-and-os-threads">
<title>The relationship between Haskell threads and OS
threads</title>
-
+
<para>Normally there is no fixed relationship between Haskell
threads and OS threads. This means that when you make a
foreign call, that call may take place in an unspecified OS
for the <ulink url="&libraryBaseLocation;/Control-Concurrent.html"><literal>Control.Concurrent</literal></ulink>
module.</para>
</sect3>
-
+
<sect3>
<title>Foreign exports and multi-threading</title>
-
+
<para>When the program is linked
with <option>-threaded</option>, then you may
invoke <literal>foreign export</literal>ed functions from
multiple OS threads concurrently. The runtime system must
be initialised as usual by
- calling <literal>hs_init()</literal>
- and <literal>hs_add_root</literal>, and these calls must
+ calling <literal>hs_init()</literal>, and this call must
complete before invoking any <literal>foreign
export</literal>ed functions.</para>
</sect3>
isn't necessary to ensure that the threads have exited first.
(Unofficially, if you want to use this fast and loose version of
<literal>hs_exit()</literal>, then call
- <literal>shutdownHaskellAndExit()</literal> instead).</para>
+ <literal>shutdownHaskellAndExit()</literal> instead).</para>
</sect3>
</sect2>
<title>Floating point and the FFI</title>
<para>
- On POSIX systems, the <literal>fenv.h</literal> header
+ The standard C99 <literal>fenv.h</literal> header
provides operations for inspecting and modifying the state of
the floating point unit. In particular, the rounding mode
used by floating point operations can be changed, and the