[GHC] #15485: GHC uses 300% CPU when calling into blocking C call

GHC ghc-devs at haskell.org
Tue Aug 7 05:33:45 UTC 2018


#15485: GHC uses 300% CPU when calling into blocking C call
-------------------------------------+-------------------------------------
           Reporter:  oconnore       |             Owner:  (none)
               Type:  bug            |            Status:  new
           Priority:  normal         |         Milestone:  8.6.1
          Component:  Runtime        |           Version:  8.4.3
  System                             |
           Keywords:                 |  Operating System:  Unknown/Multiple
       Architecture:  x86_64         |   Type of failure:  None/Unknown
  (amd64)                            |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 Hello,

 I'm trying to write a program that modifies /etc/passwd safely, and so I
 wrote a function that looks like this:

 {{{#!hs
 lockPwd f = bracket main recover (\_ -> f)
   where
     mode = unionFileModes ownerReadMode ownerWriteMode
     main = do
       fd <- openFd "/etc/.pwd.lock" WriteOnly (Just mode) defaultFileFlags
       putStrLn "waiting to set lock"
       waitToSetLock fd (WriteLock, AbsoluteSeek, 0, 0)
       putStrLn "got lock"
       return fd
     recover = flip setLock (Unlock, AbsoluteSeek, 0, 0)
 }}}

 When I run it, my fans go wild, and CPU usage hits 300%.

 /u/gelisam did some more in depth investigation here:
 https://www.reddit.com/r/haskell/comments/94wbfc/systemunixiowaittosetlock_call_results_in_300_cpu/e3p7sks/

 > Googling confirms that the parallel gc is using spin locks. So I think
 what is happening is that the waitToSetLock call makes the current thread
 unavailable for garbage collection (I don't know if that means the thread
 is "descheduled" as in the linked issue), which then causes the other
 threads to spin-lock while waiting for that thread at the next parallel
 GC. The problem still occurs with the latest release, GHC 8.4.3, and I
 could not find an existing issue describing the problem, so please file a
 ticket.

 Maybe an argument could be made that this waitToSetLock call should be
 converted to be
 [[https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ffi-
 chap.html#interruptible-foreign-calls|interruptible]], but it also seems
 like I should be able to make my haskell program block patiently if I want
 it to.

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15485>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list