The GHC Haskell runtime supports preemtive scheduling of cooperative threads ("green threads"). In non-preemtive cooperative threading, threads yield to each other. However, when a thread goes into a syscall, it no longer has the control to yield. The only way to wake up from a syscall (and thus to decide wether another thread should be scheduled, inside the runtime, and thus to get preemtive scheduling), is to send a signal to the process that's blocked in the syscall; then the syscall gets interrupted with EINTR and the runtime can do its scheduling decision, and then resume the syscall if needed.
This signal sending is done by setting up a periodic "timer signal" that sends SIGALRM to the process every 10 ms (by default).
http://man7.org/linux/man-pages/man2/timer_create.2.html