From: Hadrien Grasland <hadrien.grasland@gmail.com>
Subject: Re: Lock-Free stack in Ada SPARK
Date: Sat, 11 Feb 2017 01:57:56 -0800 (PST)
Date: 2017-02-11T01:57:56-08:00 [thread overview]
Message-ID: <52b3faef-34b7-485f-98fb-6f488692ae9b@googlegroups.com> (raw)
In-Reply-To: <c7c7fd16-9302-4ea0-99c0-c6c48c775348@googlegroups.com>
Le samedi 11 février 2017 04:07:43 UTC+1, stevensele...@gmail.com a écrit :
> It's probably buggy. I still can't figure out how I'm supposed to prove properties about a volatile (protected) object.
>
> https://sstewartgallus.com/git?p=linted.git;a=blob;f=src/ada-core/src/linted-lock_free_stack.adb;h=ee17ba8dcff26527fa4f06dfa750d0846a16f255;hb=HEAD
>
> There's also a lock-free condition variable like thing
>
> https://sstewartgallus.com/git?p=linted.git;a=blob;f=src/ada-core/src/linted-wait_lists.adb;h=be46f99cb2907e13a37f2e848b901a4dcdd02109;hb=HEAD
Actually, I'm not convinced that Ada atomics provide the required properties for what you're trying to do here.
To me, Ada's "Atomic", as defined by section C.6 of the Ada 2012 RM, provides essentially the same synchronization guarantees as Java's "volatile":
1/Each read from an atomic variable is atomic.
2/Each write to an atomic variable is atomic.
3/Each thread sees the same atomic writes occuring, without reordering.
What it does not guarantee, however, is that nothing will happen between the time where a thread reads from a variable, and the time where a thread writes to a variable. Which means, for example, that "X := X + 1" is a race condition in Ada even if X is atomic.
It also means that the Linted.Compare_And_Swap primitive that your lock-free stack is using has a race condition inside of it, as far as I can tell. From https://sstewartgallus.com/git?p=linted.git;a=blob;f=src/ada-core/src/linted-atomics.adb;h=a0a59e66568c8b5e11318691d97608dc33363315;hb=HEAD ...
26 procedure Compare_And_Swap
27 (Old_Ptr : Element_T;
28 New_Ptr : Element_T;
29 Success : in out Boolean)
30 is
31 begin
32 if Old_Ptr = Ptr then
33 Ptr := New_Ptr;
34 Success := True;
35 else
36 Success := False;
37 end if;
38 end Compare_And_Swap;
...you actually cannot guarantee that Ptr will not be updated by another thread between the time where you check it at line 32 and the time where you write to it at line 33, which means that you have a data race on your hands.
You could expose this by running two tasks in parallel, have them call compare-and-swap on a shared memory location, and see if you can observe an inconsistent memory state (i.e. one where a task should have not written to memory but did so anyway).
next prev parent reply other threads:[~2017-02-11 9:57 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-11 3:07 Lock-Free stack in Ada SPARK stevenselectronicmail
2017-02-11 9:57 ` Hadrien Grasland [this message]
2017-02-11 10:07 ` Hadrien Grasland
2017-02-11 10:08 ` Hadrien Grasland
2017-02-11 10:14 ` Hadrien Grasland
2017-02-11 17:34 ` stevenselectronicmail
2017-02-11 19:36 ` Jeffrey R. Carter
2017-02-11 20:42 ` stevenselectronicmail
2017-02-11 22:40 ` Dmitry A. Kazakov
2017-02-11 23:02 ` stevenselectronicmail
2017-02-12 8:30 ` Dmitry A. Kazakov
2017-02-12 12:26 ` Hadrien Grasland
2017-02-12 12:49 ` Dmitry A. Kazakov
2017-02-12 13:19 ` Hadrien Grasland
2017-02-12 14:57 ` Dmitry A. Kazakov
2017-02-12 13:04 ` Hadrien Grasland
2017-02-12 22:25 ` Robert Eachus
2017-02-13 8:22 ` Dmitry A. Kazakov
2017-02-13 20:04 ` stevenselectronicmail
2017-02-21 1:51 ` Robert Eachus
2017-02-21 8:44 ` Dmitry A. Kazakov
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox