Hi Alex, Thanks for reminding. hs_try_put_mvar() wouldn't work for our use case. If the C function finishes work and calls hs_try_put_mvar() synchronously, in Haskell takeMVar wouldn't block at all, which is all fine. However, if the C function is expected to call hs_try_put_mvar() asynchronously, the non-threaded RTS will hang!
Here's a minimal repro. It works with non-threaded RTS at first, but if you change scheduleCallback() in C so hs_try_put_mvar() is only invoked in a detached pthread, then the program hangs. The proposed async RTS API and related scheduler refactorings can't be avoided, if the MVar is intended to be fulfilled in an async manner, using the non-threaded RTS, on a platform with extremely limited syscall capabilities. ```haskell import Control.Concurrent import Control.Exception import Foreign import Foreign.C import GHC.Conc main :: IO () main = makeExternalCall >>= print makeExternalCall :: IO CInt makeExternalCall = mask_ $ do mvar <- newEmptyMVar sp <- newStablePtrPrimMVar mvar fp <- mallocForeignPtr withForeignPtr fp $ \presult -> do (cap,_) <- threadCapability =<< myThreadId scheduleCallback sp cap presult takeMVar mvar peek presult foreign import ccall "scheduleCallback" scheduleCallback :: StablePtr PrimMVar -> Int -> Ptr CInt -> IO () ``` ```c #include "HsFFI.h" #include "Rts.h" #include "RtsAPI.h" #include <unistd.h> #include <pthread.h> struct callback { HsStablePtr mvar; int cap; int *presult; }; void* callback(struct callback *p) { usleep(1000); *p->presult = 42; hs_try_putmvar(p->cap,p->mvar); free(p); return NULL; } void scheduleCallback(HsStablePtr mvar, HsInt cap, int *presult) { pthread_t t; struct callback *p = malloc(sizeof(struct callback)); p->mvar = mvar; p->cap = cap; p->presult = presult; // pthread_create(&t, NULL, callback, p); // pthread_detach(t); callback(p); } ``` On Thu, Dec 16, 2021 at 12:10 PM Alexander V Vershilov <alexander.vershi...@gmail.com> wrote: > > Hello, replying off-the thread as it would be basically an offtopic. > > But you can achieve the solution using MVars only. > The idea is that you can call mkStablePtr on the MVar that way it will > not be marked as dead, so RTS will not exit. > Then you can use hs_try_put_mvar in C thread to call the thread back. > > On Wed, 15 Dec 2021 at 05:07, Cheng Shao <cheng.s...@tweag.io> wrote: > > > > Hi devs, > > > > To invoke Haskell computation in C, we need to call one of rts_eval* > > functions, which enters the scheduler loop, and returns only when the > > specified Haskell thread is finished or killed. We'd like to enhance > > the scheduler and add async variants of the rts_eval* functions, which > > take C callbacks to consume the Haskell thread result, kick off the > > scheduler loop, and the loop is allowed to exit when the Haskell > > thread is blocked. Sync variants of RTS API will continue to work with > > unchanged behavior. > > > > The main intended use case is async foreign calls for the WebAssembly > > target. When an async foreign call is made, the Haskell thread will > > block on an MVar to be fulfilled with the call result. But the > > scheduler will eventually fail to find work due to empty run queue and > > exit with error! We need a way to gracefully exit the scheduler, so > > the RTS API caller can process the async foreign call, fulfill that > > MVar and resume Haskell computation later. > > > > Question I: does the idea of adding async RTS API sound acceptable by > > GHC HQ? To be honest, it's not impossible to workaround lack of async > > RTS API: reuse the awaitEvent() logic in non-threaded RTS, pretend > > each async foreign call reads from a file descriptor and can be > > handled by the POSIX select() function in awaitEvent(). But it'd > > surely be nice to avoid such hacks and do things the principled way. > > > > Question II: how to modify the scheduler loop to implement this > > feature? Straightforward answer seems to be: check some RTS API > > non-blocking flag, if present, allow early exit due to empty run > > queue. > > > > Thanks a lot for reading this, I appreciate any suggestions or > > questions :) > > > > Best regards, > > Cheng > > _______________________________________________ > > ghc-devs mailing list > > ghc-devs@haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs > > > > -- > -- > Alexander _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs