Note that there are some explanatory texts on larger screens.

plurals
  1. POSchedule error when calling multi-threaded C FFI with Haskell Callback function
    text
    copied!<p>Below is a Haskell/C FFI code that is throwing schedule error at runtime (GHC 7.0.3, Mac OS 10.7, x86_64). I searched for explanation of the error but didn't find anything relevant.</p> <p>C Code (<code>mt.c</code>):</p> <pre><code>#include &lt;pthread.h&gt; #include &lt;stdio.h&gt; typedef void(*FunctionPtr)(int); /* This is our thread function. It is like main(), but for a thread*/ void *threadFunc(void *arg) { FunctionPtr fn; fn = (FunctionPtr) arg; fn(1); //call haskell function with a CInt argument to see if it works } void create_threads(FunctionPtr* fp, int numThreads ) { pthread_t pth[numThreads]; // array of pthreads int t; for (t=0; t &lt; numThreads;){ pthread_create(&amp;pth[t],NULL,threadFunc,*(fp + t)); t++; } printf("main waiting for all threads to terminate...\n"); for (t=0; t &lt; numThreads;t++){ pthread_join(pth[t],NULL); } } </code></pre> <p>Haskell code (<code>t.hs</code>) - it calls <code>create_threads</code> in <code>mt.c</code> above with <code>Storable Vector</code> of <code>FunPtr</code> to Haskell function <code>f</code> (after applying first three arguments to <code>f</code>):</p> <pre><code>{-# LANGUAGE BangPatterns #-} import Control.Concurrent (forkIO, threadDelay, MVar, newEmptyMVar, putMVar, takeMVar) import qualified Data.Vector.Storable.Mutable as MSV import qualified Data.Vector.Storable as SV import Control.Monad.Primitive (PrimState) import Control.Monad (mapM, forM_) import Foreign.Ptr (Ptr, FunPtr) import Foreign.C.Types (CInt) type Length = CInt -- | f is a function that is called back by create_threads in mt.c f :: MVar Int -&gt; MSV.MVector (PrimState IO) CInt -&gt; Length -&gt; CInt -&gt; IO () f m v l x = do !i &lt;- takeMVar m case (i&lt; fromIntegral l) of True -&gt; MSV.unsafeWrite v i x &gt;&gt; print x &gt;&gt; putMVar m (i+1) False -&gt; return () -- overflow -- a "wrapper" import gives us a converter for converting a Haskell function to a foreign function pointer foreign import ccall "wrapper" wrap :: (CInt -&gt; IO()) -&gt; IO (FunPtr (CInt -&gt; IO())) foreign import ccall safe "create_threads" createThreads :: Ptr (FunPtr (CInt -&gt; IO())) -&gt; CInt -&gt; IO() main = do let threads = [1..4] m &lt;- mapM (\x -&gt; newEmptyMVar) $ threads -- intialize mvars with 0 forM_ m $ \x -&gt; putMVar x 0 let l = 10 -- intialize vectors of length 10 that will be filled by function f v &lt;- mapM (\x -&gt; MSV.new l) threads -- create a list of function pointers to partial function - the partial function is obtained by applying first three arguments to function f lf &lt;- mapM (\(x,y) -&gt; wrap (f x y (fromIntegral l))) $ zip m v -- convert above function list to a storable vector of function pointers let fv = SV.fromList lf -- call createThreads with storable vector of function pointers, and number of threads - createThreads will spawn threads which will use function pointers for callback SV.unsafeWith fv $ \x -&gt; createThreads x (fromIntegral $ length threads) </code></pre> <p>Please ignore unsafe parts in the code - my objective here is to test callback using Haskell FFI with multi-threaded C code. When I compile it, and run it, I get the error below:</p> <pre><code>$ ghc -O2 t.hs mt.c -lpthread [1 of 1] Compiling Main ( t.hs, t.o ) Linking t ... $ ./t main waiting for all threads to terminate... t: schedule: re-entered unsafely. Perhaps a 'foreign import unsafe' should be 'safe'? $ uname -a Darwin desktop.local 11.2.0 Darwin Kernel Version 11.2.0: Tue Aug 9 20:54:00 PDT 2011; root:xnu-1699.24.8~1/RELEASE_X86_64 x86_64 $ ghc --version The Glorious Glasgow Haskell Compilation System, version 7.0.3 </code></pre> <p>The schedule error happens only if I have the C threads call back haskell function f. I guess it is more likely there is a bug in my code, than there is a bug in one of the libraries or GHC. So, I will like to check here first for pointers on cause of the error.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload