[Haskell-cafe] Locking of threads in one OS thread
nikoamia at gmail.com
Wed Aug 20 06:31:59 UTC 2014
Thanks for the answer! I've thought about (c) already, and (a) and (b)
are interesting, too -- maybe (a) is my answer.
I'm very interested in how Haskell handles this already -- for
example, in "network" or "unix" package sources I haven't found any
handling of this (see ,  for example) and it looks to me that
these packages are prone to this race condition -- am I right?
If this is not a known error, then my thoughts is that to add a way to
fix this without losing much speed we could add new prims -- something
like "maskPreemption#", "unmaskPreemption#" and "getPreemptionState#"
(using "mask" implementation as an example) and new "maskPreemption"
function in Control.Concurrent, for example. Prims can use
thread-local flag without any locking that runtime checks before
thread preemption -- this should be nearly unnoticeable operation in
terms of performance.
This is all just an idea of how I would implement this, and I don't
have knowledge of RTS internals, so for someone competent this may be
utter nonsense -- I'm sorry for this.
On Wed, Aug 20, 2014 at 5:02 AM, Carter Schonwald
<carter.schonwald at gmail.com> wrote:
> several ideas
> a) you can use forkOS to run the ffi call and the the subsequent errno value
> checking in a pinned OS thread so you can guarantee you can access the
> thread local storage
> b) you could have a CallManager that keeps a MVar or queue or something,
> along with a handle on the forkOS thread id, and "intiialize" the forkOS
> thread with a teeny worker that read from an input MVar and writes to a
> result MVar (thus guarantee only one call a time)
> c) something that uses these ideas together.
> theres a lot of strategies you can use. but i hope this gives you a sketch
> (i can spell it out more later this week if need be)
> On Tue, Aug 19, 2014 at 5:36 PM, Nikolay Amiantov <nikoamia at gmail.com>
>> Hello Cafe,
>> I'm using FFI to interact with a library which calls, when fail, leave
>> the reason in some kind of "errno"-like variable which is retrived via
>> another call. AFAIU, this is not thread-safe in Haskell even if
>> thread-local storage is used inside the library, because Haskell uses
>> its own thread management and the Haskell thread in the same OS thread
>> might be switched between the actual call and the retrival of errno
>> value. This should be somehow handled already in Haskell (errno is
>> widely used with syscalls in Linux, for example), but the source of
>> Foreign.C.Error suggests that this is not handled in any way at all.
>> For example, throwErrnoIf is implemented as such:
>> throwErrno loc = do
>> errno <- getErrno
>> ioError (errnoToIOError loc errno Nothing Nothing)
>> throwErrnoIf pred loc f = do
>> res <- f
>> if pred res then throwErrno loc else return res
>> So, the question is: how is it ensured that this block is "atomic" in
>> sense that at most one Haskell thread computes this whole function at
>> every moment in every OS thread?
>> Thanks for any explanations! (And sorry if my English is poor)
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
More information about the Haskell-Cafe