bmk
bmk

Reputation: 1568

GHC ccall safe VS ccall unsafe

Dear GHC/Haskell Gurus,

I am currently writing a (medium-sized) Haskell server application using GHC, which (heavily) uses 3rd-party C library functions via the FFI. In other words, there are multiple FFI C calls made by a server thread, when serving a client request.

Currently I am calling all the C functions unsafely (unsafe ccall) in order to minimize the calling overhead. But the tradeoff here is, that the unsafe ccalls cannot be preemptied by the GHC RTS, meaning that all other Haskell threads are blocked until the C function returns. This could be problematic, if the C function takes too long.

On the other hand, the safe ccalls are more expensive but they will be run in separate OS threads and will not block the GHC's worker threads.

I guess, what I am trying to ask here is, how can you sensibly make the best choice whether to make a safe ccall or unsafe ccall? For example I don't want to make an expensive safe ccall if the C function is short and trivial, but if a C function takes long time to return (cpu-heavy computation, IO operations etc.), then making an unsafe call is problematic, since it will block a worker thread. Is there a kind of approximate threshold value t, so that if the C function takes longer than t to complete, then make it a safe ccall and otherwise unsafe ccall?

I hope, this question makes somewhat sense and if there are something unclear, please don't hesitate to comment.

Thans a ton for your help in advance!

Upvotes: 4

Views: 485

Answers (1)

Carl
Carl

Reputation: 27023

The rule of thumb is as follows:

  1. Make everything safe.
  2. If profiling reveals a performance problem in the overhead of FFI calls, carefully consider whether the semantics of unsafe are appropriate for the hotspot calls.
  3. If profiling has revealed a performance problem in the overhead of a safe FFI call and semantic analysis of the call has shown that unsafe won't break anything, then consider a change to unsafe if the worst-case time of the call is expected to be better than 1 millisecond.

Don't skip the first two steps. unsafe has more potential issues than just blocking the RTS.

Upvotes: 4

Related Questions