<div dir="ltr"><div>Hi John,</div><div><br></div><div>I can, but the only reason that would work is because a blocking foreign call is except from the</div><div>deadlock detection code.  I can't block on the Handle itself as all the I/O calls are non-blocking for performance reasons.</div><div><br></div><div>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</div><div>and have a mutable state for each task, which is essentially what an MVar does.  My other concern is that using OS primitives<br></div><div>would hit performance a bit, which increases as the load increases. So I'd much rather do it purely in the Haskell world.</div><div><br></div><div>Kind regards,</div><div>Tamar<br></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Jan 7, 2019 at 5:44 AM John Lato <<a href="mailto:jwlato@gmail.com">jwlato@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto">Can you use an os-level structure? E.g. block on a file descriptor, socket, or something like that?</div><br><div class="gmail_quote"><div dir="ltr">On Sun, Jan 6, 2019, 10:37 Phyx <<a href="mailto:lonetiger@gmail.com" target="_blank">lonetiger@gmail.com</a> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Hi All,</div><div><br></div><div>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.</div><div><br></div><div>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.<br></div><div><br></div><div>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.<br></div><div><br></div><div>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).<br></div><div><br></div><div>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.</div><div><br></div><div>Cheers,</div><div>Tamar<br></div></div>
_______________________________________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org" rel="noreferrer" target="_blank">ghc-devs@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br>
</blockquote></div>
</blockquote></div>