[m-rev.] for review: threadsafe version_arrays in Java

Peter Ross pro at missioncriticalit.com
Wed Apr 14 16:45:01 AEST 2010


On Wed, Apr 14, 2010 at 04:12:34PM +1000, Peter Ross wrote:
> Hi,
> 
> Peter Wang is probably the best person to review this.
> 
> Ralph might want to make version_arrays thread safe on the C backend,
> however at least now the user will get an error when they try and use
> the non-safe version_array in a context where it might have to support
> concurrent access.
> 

Here is the module I used to test the problem.

You have one thread which is constantly writing to array location 1, so
constantly creating a new diff.

The other thread just tries to read from array location 0 constantly,
thus it has to traverse all the way to the end of the list of array
diffs however when it arrives at the node containing the array, it stops
and then reads the value out of the array.

However concurrently the writing thread can add a new value thus
converting the node containing the array into a new diff node, thus
making the result you attempt to read out be totally bogus.

On the java backend this causes a incorrect class type exception
on the C backend I suspect what will happen is that you will just
get some random memory location or a seg fault.





:- module va_test.

:- interface.

:- import_module io.

:- pred main(io::di, io::uo) is cc_multi.

%------------------------------------------------------------------------------%
%------------------------------------------------------------------------------%

:- implementation.

:- import_module int.
:- import_module thread.
:- import_module mva.

%------------------------------------------------------------------------------%

main(!IO) :-
    VA = mva.new(2, 1),
    Count = 50000,
    thread.spawn(set(Count, VA), !IO),
    read(Count, VA, 0, !IO).


:- pred read(int::in, version_array(int)::in, int::in, io::di, io::uo) is det.

read(Loop, VA, Accum, !IO) :-
    ( Loop > 0 ->
        Val = VA ^ elem(0),
        read(Loop - 1, VA, Accum + Val, !IO)
    ;
        io.write_int(Accum, !IO),
        io.nl(!IO),
        true
    ).
    
:- pred set(int::in, version_array(int)::in, io::di, io::uo) is cc_multi.

set(Loop, VA0, !IO) :-
    ( Loop > 0 ->
        VA = VA0 ^ elem(1) := 2,
        set(Loop - 1, VA, !IO)
    ;
        true
    ).
    

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



More information about the reviews mailing list