summaryrefslogtreecommitdiff
path: root/testsuite
diff options
context:
space:
mode:
authorIvan Kasatenko <sky.31338@gmail.com>2019-07-20 15:09:00 +0300
committerMarge Bot <ben+marge-bot@smart-cactus.org>2019-07-21 05:03:40 -0400
commit67ee741bd6a7017a62719c3c25a5447a0b03191e (patch)
treed3b5414c10231c458801591269a3ea36cfeb5844 /testsuite
parent5042ba9dbe0caff2e33a4f7f5a78f2f61eaf6a32 (diff)
downloadhaskell-67ee741bd6a7017a62719c3c25a5447a0b03191e.tar.gz
Do not ignore events deletion when events to be added are provided (#16916)
Kqueue/kevent implementation used to ignore events to be unsubscribed from when events to be subscribed to were provided. This resulted in a lost notification subscription, when GHC runtime didn't listen for any events, yet the kernel considered otherwise and kept waking up the IO manager thread. This commit fixes this issue by always adding and removing all of the provided subscriptions.
Diffstat (limited to 'testsuite')
-rw-r--r--testsuite/tests/lib/base/T16916.hs45
-rw-r--r--testsuite/tests/lib/base/T16916.stdout1
-rw-r--r--testsuite/tests/lib/base/all.T1
3 files changed, 47 insertions, 0 deletions
diff --git a/testsuite/tests/lib/base/T16916.hs b/testsuite/tests/lib/base/T16916.hs
new file mode 100644
index 0000000000..a5dafa515b
--- /dev/null
+++ b/testsuite/tests/lib/base/T16916.hs
@@ -0,0 +1,45 @@
+module Main where
+
+import Control.Concurrent
+import Foreign.C
+import GHC.Event
+import System.CPUTime
+import System.Posix.Types
+
+foreign import ccall unsafe "socket" c_socket ::
+ CInt -> CInt -> CInt -> IO CInt
+
+makeTestSocketFd :: IO Fd
+makeTestSocketFd = do
+ sockNum <-
+ c_socket
+ 1 -- PF_LOCAL
+ 2 -- SOCK_DGRAM
+ 0
+ return $ (fromIntegral sockNum :: Fd)
+
+callback :: FdKey -> Event -> IO ()
+callback _ _ = return ()
+
+idleCpuUsage :: IO Integer
+idleCpuUsage = do
+ startCPUTime <- getCPUTime
+ threadDelay 500000
+ endCPUTime <- getCPUTime
+ return $ endCPUTime - startCPUTime
+
+main :: IO ()
+main = do
+ (Just eventMgr) <- getSystemEventManager
+ fd <- makeTestSocketFd
+
+ noEventUsage <- idleCpuUsage
+
+ registerFd eventMgr callback fd evtRead OneShot
+ registerFd eventMgr callback fd evtWrite OneShot
+
+ eventTriggeredUsage <- idleCpuUsage
+
+ -- CPU consumption should roughly be the same when just idling vs
+ -- when idling after the event been triggered
+ print $ (fromIntegral eventTriggeredUsage / fromIntegral noEventUsage) < 2.0
diff --git a/testsuite/tests/lib/base/T16916.stdout b/testsuite/tests/lib/base/T16916.stdout
new file mode 100644
index 0000000000..0ca95142bb
--- /dev/null
+++ b/testsuite/tests/lib/base/T16916.stdout
@@ -0,0 +1 @@
+True
diff --git a/testsuite/tests/lib/base/all.T b/testsuite/tests/lib/base/all.T
index ff0c9f963f..8a97c0f907 100644
--- a/testsuite/tests/lib/base/all.T
+++ b/testsuite/tests/lib/base/all.T
@@ -1 +1,2 @@
test('T16586', normal, compile_and_run, ['-O2'])
+test('T16916', normal, compile_and_run, ['-O2 -threaded'])