[m-dev.] Globals and concurrency

Peter Wang wangp at students.csse.unimelb.edu.au
Tue Aug 1 22:19:44 AEST 2006


On 2006-08-01, Julien Fischer <juliensf at csse.unimelb.edu.au> wrote:
> Actually, now I've had more of a think about it, that's not quite the
> problem.  Since io.{get, set}_globals are marked with `not_thread_safe'
> any thread executing one of them has to acquire the global mutex, so
> only one of them can be executed at time.  The problem, in the above
> example is that while one thread is executing foo(Globals0, Globals),
> another may come along and call set, get globals and stuff everything
> up.

I thought that's what you meant.

> What is needed is something to tell the compiler that the above three
> calls are a critical region, like synchronized blocks in Java.
> 
> Some thoughts:
> 
> - the current implementation of mutables with `thread_safe' is quite
>   unsafe.

Yes.  I was thinking `reentrant' might be a better name for the
attribute (for foreign_procs).

> - we could a new attribute `update' to the mutable declarations.  This
>   would cause the compiler to generate an update predicate that would
>   allow you to update the value of a mutable without interference from
>   other threads.
> 
>   e.g.
> 
> 	:- mutable(varname, vartype, intial_value, varinst, [...]).
> 
>   becomes something like:
> 
> 	:- pred update_varname((func(vartype) = vartype), io, io).
> 	:- mode update_varname((func(in) = out is det), di, uo) is det.
> 
> 	update_varname(F, !IO) :-
> 		<acquire lock on varname>,
> 		io.get_varname(V0, !IO),
> 		V = F(V0),
> 		io.set_varname(V, !IO),
> 		<release lock on varname>.
> 
>         - for that to work each mutable would need an associated mutex.
> 	- since F doesn't take the I/O state that prevents F itself
> 	  trying to alter the value of the mutable (unless you use the
>           impure interface.)

Not taking I/O means deadlocks won't be possible when one thread tries
to update A and B, and another thread tries to update B and A, but on
the other hand you can't atomically update two mutables.  Maybe they
should have just been one mutable to being with, though.

I think it would be useful to have context-specific mutables, like the
gcc __thread extension.  A child thread would inherit the values of
mutables from its parent thread, but updates to the mutable would not be
visible to any other thread.

And, maybe mutables should be context-specific by default.  Only
mutables explicitly marked as "really" global would have mutexes
associated with them; these can have locking predicates and/or update
predicates generated.

> - at the "lots of work" end of the spectrum these things could be
>   built into the language, synchronized scopes or something (to borrow
>   the Java terminology for them.

Monitors?  Anyway, I'd be happy with manual locks as there are very few
times you need mutables, and even fewer times you need to update them.

Peter

--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at csse.unimelb.edu.au
Administrative Queries: owner-mercury-developers at csse.unimelb.edu.au
Subscriptions:          mercury-developers-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the developers mailing list