[m-dev.] Interleaved output in hlc.gc.par

Zoltan Somogyi zoltan.somogyi at runbox.com
Thu Sep 17 17:32:24 AEST 2015



On Thu, 17 Sep 2015 17:01:59 +1000, Paul Bone <paul at bone.id.au> wrote:

> On Thu, Sep 17, 2015 at 05:00:27PM +1000, Peter Wang wrote:
> > On Thu, 17 Sep 2015 16:36:42 +1000, Paul Bone <paul at bone.id.au> wrote:
> > > 
> > > Should a user reasonably expect calls to io.format to be atomic with respect
> > > to the IO state?  I ask because this creates an inconsistency.
> > 
> > I don't think so.  It is the user's responsibility to serialise any
> > concurrent uses of the stream.  It's not specific to io.format.
> > Two threads calling write_string may produce output with interleaved
> > characters, e.g. "Hweolrllod !"
> 
> Oh,
> 
> 1) How can users control this for cases when they need to?
> 2) Why are we writing character by character?!?!

"We" are not writing anything. Due to this line in library/string.format.m:

#define ML_USE_SPRINTF MR_TRUE

calls to io.format are implemented using sprintf. All the threads use
the same buffer, so it is lucky even that you get all the characters you printed,
without a character printed by one thread overwriting a character printed
by another thread.

To control it, we (the implementors, not Mercury users) would need to surround
all the C code fragments we invoke that may affect stdio buffers with the *same*
lock. I believe we already surround such pieces of code with locks, but these locks
guard only against two threads executing the same *piece of code*, not two
different pieces of code modifying the same *piece of data*.

This would impose serialization of I/O even in cases where different threads
write to different files, which itself is undesirable. The only good solution
I can think of is to attach the lock to a Mercury-controlled handle for the
file pointer.

Zoltan.

Zoltan.





More information about the developers mailing list