From ba7961f118f42ba9db7e5fba017270a257852ff3 Mon Sep 17 00:00:00 2001
From: Paolo Capriotti <p.capriotti@gmail.com>
Date: Mon, 2 Jul 2012 11:52:39 +0100
Subject: [PATCH] Add a WARNING for sleep, and expand documentation.
sleep doesn't really work on GHC because it is always immediately
interrupted by SIGVTALRM used in the RTS.
I explained the problem in a comment and added a WARNING pragma.
usleep and nanosleep have a similar problem, but, since they have better
precision, they can be restarted, so they are not as unusable as sleep.
---
System/Posix/Unistd.hsc | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/System/Posix/Unistd.hsc b/System/Posix/Unistd.hsc
index 7312dae..dfd2673 100644
|
a
|
b
|
|
| 95 | 95 | -- | Sleep for the specified duration (in seconds). Returns the time remaining |
| 96 | 96 | -- (if the sleep was interrupted by a signal, for example). |
| 97 | 97 | -- |
| 98 | | -- GHC Note: the comment for 'usleep' also applies here. |
| | 98 | -- /GHC Note/: 'Control.Concurrent.threadDelay' is a better choice. Since GHC |
| | 99 | -- uses signals for its internal clock, a call to 'sleep' will usually be |
| | 100 | -- interrupted immediately. That makes 'sleep' unusable in a program compiled |
| | 101 | -- with GHC, unless the RTS timer is disabled (with @+RTS -V0@). Furthermore, |
| | 102 | -- without the @-threaded@ option, 'sleep' will block all other user threads. |
| | 103 | -- Even with the @-threaded@ option, 'sleep' requires a full OS thread to |
| | 104 | -- itself. 'Control.Concurrent.threadDelay' has none of these shortcomings. |
| 99 | 105 | -- |
| 100 | 106 | sleep :: Int -> IO Int |
| 101 | 107 | sleep 0 = return 0 |
| 102 | 108 | sleep secs = do r <- c_sleep (fromIntegral secs); return (fromIntegral r) |
| 103 | 109 | |
| | 110 | #ifdef __GLASGOW_HASKELL__ |
| | 111 | {-# WARNING sleep "This function has several shortcomings (see documentation). Please consider using Control.Concurrent.threadDelay instead." #-} |
| | 112 | #endif |
| | 113 | |
| 104 | 114 | foreign import ccall safe "sleep" |
| 105 | 115 | c_sleep :: CUInt -> IO CUInt |
| 106 | 116 | |
| 107 | 117 | -- | Sleep for the specified duration (in microseconds). |
| 108 | 118 | -- |
| 109 | | -- GHC Note: 'Control.Concurrent.threadDelay' is a better choice. |
| | 119 | -- /GHC Note/: 'Control.Concurrent.threadDelay' is a better choice. |
| 110 | 120 | -- Without the @-threaded@ option, 'usleep' will block all other user |
| 111 | 121 | -- threads. Even with the @-threaded@ option, 'usleep' requires a |
| 112 | 122 | -- full OS thread to itself. 'Control.Concurrent.threadDelay' has |
| … |
… |
|
| 134 | 144 | |
| 135 | 145 | -- | Sleep for the specified duration (in nanoseconds) |
| 136 | 146 | -- |
| | 147 | -- /GHC Note/: the comment for 'usleep' also applies here. |
| 137 | 148 | nanosleep :: Integer -> IO () |
| 138 | 149 | #ifndef HAVE_NANOSLEEP |
| 139 | 150 | nanosleep = error "nanosleep: not available on this platform" |