Blocking a task indefinitely in the RTS

Phyx lonetiger at
Mon Jan 7 22:16:51 UTC 2019

Hi John,

I can, but the only reason that would work is because a blocking foreign
call is except from the
deadlock detection code.  I can't block on the Handle itself as all the I/O
calls are non-blocking for performance reasons.

Instead what I want to do is just pause the current task, which means I
don't have to allocate OS level locks for each task
and have a mutable state for each task, which is essentially what an MVar
does.  My other concern is that using OS primitives
would hit performance a bit, which increases as the load increases. So I'd
much rather do it purely in the Haskell world.

Kind regards,

On Mon, Jan 7, 2019 at 5:44 AM John Lato <jwlato at> wrote:

> Can you use an os-level structure? E.g. block on a file descriptor,
> socket, or something like that?
> On Sun, Jan 6, 2019, 10:37 Phyx <lonetiger at wrote:
>> Hi All,
>> I'm looking for a way to block a task indefinitely until it is woken up
>> by an external event in both the threaded and non-threaded RTS and returns
>> a value that was stored/passed. MVar works great for the threaded RTS, but
>> for the non-threaded there's a bunch of deadlock detection in the scheduler
>> that would forcibly free the lock and resume the task with an opaque
>> exception. This means that MVar and anything derived from it is not usable.
>> STMs are more expensive but also have the same deadlock code. So again no
>> go. The reason it looks like a deadlock to the RTS is that the "Wake-up"
>> call in the non-threaded rts will come from C code running inside the RTS.
>> The RTS essentially just sees all tasks blocked on it's main capability and
>> (usually rightly so) assumes a deadlock occurred.
>> You have other states like BlockedOnForeign etc but those are not usable
>> as a primitive. Previous iterations of I/O managers have each invented
>> primitives for this such as asyncRead#, but they are not general and can't
>> be re-used, and requires a different solution for threaded and non-threaded.
>> I have started making a new primitive IOPort for this, based on the MVar
>> code, but this is not trivial... (currently I'm getting a segfault
>> *somewhere* in the primitive's cmm code). The reason is that the semantics
>> are decidedly different from what MVars guarantee. I should also mention
>> that this is meant to be internal to base (i.e no exported).
>> So before I continue down this path and some painful debugging..., does
>> anyone know of a way to block a task, unblock it later and pass a value
>> back? It does not need to support anything complicated such as multiple
>> take/put requests etc.
>> Cheers,
>> Tamar
>> _______________________________________________
>> ghc-devs mailing list
>> ghc-devs at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the ghc-devs mailing list