X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=docs%2Fusers_guide%2Fffi-chap.xml;h=aea2f5eb137c9c7580bdab1b29bcd65f5acb177b;hp=a016f10901c954219c725dbc182c22e2716213d9;hb=46809fa91667e952afe016e4cd704b21274241b4;hpb=c52eb69bb2f51fed830db42f22bab74c6ff05565
diff --git a/docs/users_guide/ffi-chap.xml b/docs/users_guide/ffi-chap.xml
index a016f10..aea2f5e 100644
--- a/docs/users_guide/ffi-chap.xml
+++ b/docs/users_guide/ffi-chap.xml
@@ -6,10 +6,10 @@
Foreign function interface (FFI)
- GHC (mostly) conforms to the Haskell 98 Foreign Function Interface
- Addendum 1.0, whose definition is available from http://www.haskell.org/.
+ GHC (mostly) conforms to the Haskell Foreign Function Interface,
+ whose definition is part of the Haskell Report on http://www.haskell.org/.
- To enable FFI support in GHC, give the
+ FFI support is enabled by default, but can be enabled or disabled explicitly with the flag.GHC implements a number of GHC-specific extensions to the FFI
@@ -19,7 +19,7 @@ Foreign function interface (FFI)
The FFI libraries are documented in the accompanying library
documentation; see for example the
- Foreign module.
+ Foreign module.GHC extensions to the FFI Addendum
@@ -63,6 +63,101 @@ OK:
+
+
+ Primitive imports
+
+ GHC extends the FFI with an additional calling convention
+ prim, e.g.:
+
+ foreign import prim "foo" foo :: ByteArray# -> (# Int#, Int# #)
+
+ This is used to import functions written in Cmm code that follow an
+ internal GHC calling convention. This feature is not intended for
+ use outside of the core libraries that come with GHC. For more
+ details see the GHC developer wiki.
+
+
+
+
+ Interruptible foreign calls
+
+ This concerns the interaction of foreign calls
+ with Control.Concurrent.throwTo.
+ Normally when the target of a throwTo is
+ involved in a foreign call, the exception is not raised
+ until the call returns, and in the meantime the caller is
+ blocked. This can result in unresponsiveness, which is
+ particularly undesirable in the case of user interrupt
+ (e.g. Control-C). The default behaviour when a Control-C
+ signal is received (SIGINT on Unix) is to raise
+ the UserInterrupt exception in the main
+ thread; if the main thread is blocked in a foreign call at
+ the time, then the program will not respond to the user
+ interrupt.
+
+
+
+ The problem is that it is not possible in general to
+ interrupt a foreign call safely. However, GHC does provide
+ a way to interrupt blocking system calls which works for
+ most system calls on both Unix and Windows. A foreign call
+ can be annotated with interruptible instead
+ of safe or unsafe:
+
+
+foreign import ccall interruptible
+ "sleep" :: CUint -> IO CUint
+
+
+ interruptble behaves exactly as
+ safe, except that when
+ a throwTo is directed at a thread in an
+ interruptible foreign call, an OS-specific mechanism will be
+ used to attempt to cause the foreign call to return:
+
+
+
+ Unix systems
+
+
+ The thread making the foreign call is sent
+ a SIGPIPE signal
+ using pthread_kill(). This is
+ usually enough to cause a blocking system call to
+ return with EINTR (GHC by default
+ installs an empty signal handler
+ for SIGPIPE, to override the
+ default behaviour which is to terminate the process
+ immediately).
+
+
+
+
+ Windows systems
+
+
+ [Vista and later only] The RTS calls the Win32
+ function CancelSynchronousIO,
+ which will cause a blocking I/O operation to return
+ with the
+ error ERROR_OPERATION_ABORTED.
+
+
+
+
+
+ If the system call is successfully interrupted, it will
+ return to Haskell whereupon the exception can be raised. Be
+ especially careful when
+ using interruptible that the caller of
+ the foreign function is prepared to deal with the
+ consequences of the call being interrupted; on Unix it is
+ good practice to check for EINTR always,
+ but on Windows it is not typically necessary to
+ handle ERROR_OPERATION_ABORTED.
+
+
@@ -251,7 +346,8 @@ int main(int argc, char *argv[])
hs_exit()The outermost
hs_exit() will actually de-initialise the
system. NOTE that currently GHC's runtime cannot reliably
- re-initialise after this has happened.
+ re-initialise after this has happened,
+ see .
.
NOTE: when linking the final program, it is normally
@@ -304,50 +400,10 @@ int main(int argc, char *argv[])
hs_exit() to shut down the runtime.
-
- On the use of hs_exit()
-
- hs_exit() normally causes the termination of
- any running Haskell threads in the system, and when
- hs_exit() returns, there will be no more Haskell
- threads running. The runtime will then shut down the system in an
- orderly way, generating profiling
- output and statistics if necessary, and freeing all the memory it
- owns.
-
- It isn't always possible to terminate a Haskell thread forcibly:
- for example, the thread might be currently executing a foreign call,
- and we have no way to force the foreign call to complete. What's
- more, the runtime must
- assume that in the worst case the Haskell code and runtime are about
- to be removed from memory (e.g. if this is a Windows DLL,
- hs_exit() is normally called before unloading the
- DLL). So hs_exit()must wait
- until all outstanding foreign calls return before it can return
- itself.
-
- The upshot of this is that if you have Haskell threads that are
- blocked in foreign calls, then hs_exit() may hang
- (or possibly busy-wait) until the calls return. Therefore it's a
- good idea to make sure you don't have any such threads in the system
- when calling hs_exit(). This includes any threads
- doing I/O, because I/O may (or may not, depending on the
- type of I/O and the platform) be implemented using blocking foreign
- calls.
-
- The GHC runtime treats program exit as a special case, to avoid
- the need to wait for blocked threads when a standalone
- executable exits. Since the program and all its threads are about to
- terminate at the same time that the code is removed from memory, it
- isn't necessary to ensure that the threads have exited first.
- (Unofficially, if you want to use this fast and loose version of
- hs_exit(), then call
- shutdownHaskellAndExit() instead).
-
- Using function headers
+ Using header filesC calls, function headers
@@ -455,12 +511,147 @@ int main(int argc, char *argv[])
+
+
+ Multi-threading and the FFI
+
+ In order to use the FFI in a multi-threaded setting, you must
+ use the option
+ (see ).
+
+
+ Foreign imports and multi-threading
+
+ When you call a foreign imported
+ function that is annotated as safe (the
+ default), and the program was linked
+ using , then the call will run
+ concurrently with other running Haskell threads. If the
+ program was linked without ,
+ then the other Haskell threads will be blocked until the
+ call returns.
+
+ 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 safe and
+ use . Some library functions
+ make such calls internally; their documentation should
+ indicate when this is the case.
+
+ If you are making foreign calls from multiple Haskell
+ threads and using , make sure that
+ the foreign code you are calling is thread-safe. In
+ particularly, some GUI libraries are not thread-safe and
+ require that the caller only invokes GUI methods from a
+ single thread. If this is the case, you may need to
+ restrict your GUI operations to a single Haskell thread,
+ and possibly also use a bound thread (see
+ ).
+
+ Note that foreign calls made by different Haskell
+ threads may execute in parallel, even
+ when the +RTS -N flag is not being used
+ (). The +RTS
+ -N flag controls parallel execution of Haskell
+ threads, but there may be an arbitrary number of foreign
+ calls in progress at any one time, regardless of
+ the +RTS -N value.
+
+ If a call is annotated as interruptible
+ and the program was multithreaded, the call may be
+ interrupted in the event that the Haskell thread receives an
+ exception. The mechanism by which the interrupt occurs
+ is platform dependent, but is intended to cause blocking
+ system calls to return immediately with an interrupted error
+ code. The underlying operating system thread is not to be
+ destroyed. See for more details.
+
+
+
+ The relationship between Haskell threads and OS
+ threads
+
+ 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
+ thread. Furthermore, there is no guarantee that multiple
+ calls made by one Haskell thread will be made by the same OS
+ thread.
+
+ This usually isn't a problem, and it allows the GHC
+ runtime system to make efficient use of OS thread resources.
+ However, there are cases where it is useful to have more
+ control over which OS thread is used, for example when
+ calling foreign code that makes use of thread-local state.
+ For cases like this, we provide bound
+ threads, which are Haskell threads tied to a
+ particular OS thread. For information on bound threads, see
+ the documentation
+ for the Control.Concurrent
+ module.
+
+
+
+ Foreign exports and multi-threading
+
+ When the program is linked
+ with , then you may
+ invoke foreign exported functions from
+ multiple OS threads concurrently. The runtime system must
+ be initialised as usual by
+ calling hs_init()
+ and hs_add_root, and these calls must
+ complete before invoking any foreign
+ exported functions.
+
+
+
+ On the use of hs_exit()
+
+ hs_exit() normally causes the termination of
+ any running Haskell threads in the system, and when
+ hs_exit() returns, there will be no more Haskell
+ threads running. The runtime will then shut down the system in an
+ orderly way, generating profiling
+ output and statistics if necessary, and freeing all the memory it
+ owns.
+
+ It isn't always possible to terminate a Haskell thread forcibly:
+ for example, the thread might be currently executing a foreign call,
+ and we have no way to force the foreign call to complete. What's
+ more, the runtime must
+ assume that in the worst case the Haskell code and runtime are about
+ to be removed from memory (e.g. if this is a Windows DLL,
+ hs_exit() is normally called before unloading the
+ DLL). So hs_exit()must wait
+ until all outstanding foreign calls return before it can return
+ itself.
+
+ The upshot of this is that if you have Haskell threads that are
+ blocked in foreign calls, then hs_exit() may hang
+ (or possibly busy-wait) until the calls return. Therefore it's a
+ good idea to make sure you don't have any such threads in the system
+ when calling hs_exit(). This includes any threads
+ doing I/O, because I/O may (or may not, depending on the
+ type of I/O and the platform) be implemented using blocking foreign
+ calls.
+
+ The GHC runtime treats program exit as a special case, to avoid
+ the need to wait for blocked threads when a standalone
+ executable exits. Since the program and all its threads are about to
+ terminate at the same time that the code is removed from memory, it
+ isn't necessary to ensure that the threads have exited first.
+ (Unofficially, if you want to use this fast and loose version of
+ hs_exit(), then call
+ shutdownHaskellAndExit() instead).
+
+
+