[m-dev.] Globals and concurrency

Julien Fischer juliensf at csse.unimelb.edu.au
Tue Aug 1 22:49:20 AEST 2006


On Tue, 1 Aug 2006, Peter Wang wrote:

> 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.

Almost, I'd forgotten that the mutex used for foreign_procs is global.

>> 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).

For foreign_procs thread_safe == reentrant.

>> - 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.

A `thread_local' attribute for mutables?

> And, maybe mutables should be context-specific by default.

Maybe, it's a bit soon to tell.

> Only
> mutables explicitly marked as "really" global would have mutexes
> associated with them; these can have locking predicates and/or update
> predicates generated.

Will that be the attribute name, really_global? ;-)
(That's almost as bad as C's long long).

Julien.








--------------------------------------------------------------------------
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