From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Portable memory barrier?
Date: Thu, 18 May 2017 19:44:56 +0200
Date: 2017-05-18T19:44:56+02:00 [thread overview]
Message-ID: <ofkmin$1iog$1@gioia.aioe.org> (raw)
In-Reply-To: ofdbhn$jc1$1@franka.jacob-sparre.dk
On 16/05/2017 00:53, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> news:of174q$13o7$1@gioia.aioe.org...
>> On 11/05/2017 02:35, Randy Brukardt wrote:
>>
>>> Still, it would be nice to try something in this area. One could imagine
>>> creating an Annex C test that implemented a lock-free algorithm and just
>>> tried to see if it worked properly.
>>
>> The real application used socked communication. The problem I suspect is
>> that artificial tests would not show problems full-size application have.
>> Maybe, a better strategy could be specific low-level tests for atomic
>> objects used in lock-free algorithms.
>
> That's what I was thinking. But I'm not really the person to propose such
> tests, I know just enough to be dangerous. ;-) I'd be much better served
> being just an editor on such tests, as I wouldn't have too much trouble
> seeing things that need to be more portable (I have a lot of experience
> doing that).
>
>> And we really should extend the Annex C with some basic atomic operations
>> like atomic increment, test-then-increment, test-then-exchange etc, all
>> falling back to protected objects if the machine lacks corresponding
>> instructions.
>
> I think you are right about that. Supposedly, implementations are supposed
> to provide access to such things via machine code insertions, but that is
> never going to be portable (even to other implementations for the same
> target). So that's not really helpful.
>
> Perhaps you could to send a problem statement and brief proposal to
> Ada-Comment? There's still time to make suggestions for Ada 2020, and
> tasking issues of all kinds are right in the wheelhouse of what we're hoping
> to accomplish. (As always, the ARG can find ways to solve problems, the real
> issue is knowing what the problems are. I believe that you are saying that
> creating portable lock-free algorithms are harder than necessary because of
> limitations in what can be atomic and what can be safely done with atomic
> objects. That seems like an important problem for the ARG to spend some time
> on.)
I was thinking about something slightly higher level than tedious CAS.
E.g. predefined generic package:
generic
type Value_Type is (<>);
Initial_Value : Value_Type'Base;
package Atomic_Object is
--
-- Holder_Type -- Type of the atomic object to keep Value_Type'Base
--
type Holder_Type is private;
pragma Atomic (Holder_Type); -- It is a private type,
-- so it must be safe to assign
--
-- Get actual value
--
function Load (Item : Holder_Type) return Value_Type'Base;
--
-- Set new value
--
procedure Store (Item : in out Holder_Type;
New_Value : Value_Type'Base);
procedure Store (Item : in out Holder;
New_Value : Value_Type'Base;
Old_Value : out Value_Type'Base);
--
-- Compare old value to the barrier and if successful
-- store new value
--
procedure Store_If_Greater (Item : in out Holder_Type;
Barrier : Value_Type'Base;
New_Value : Value_Type'Base);
procedure Store_If_Greater (Item : in out Holder_Type;
Barrier : Value_Type'Base;
New_Value : Value_Type'Base;
Old_Value : out Value_Type'Base);
procedure Store_If_Equal ...
procedure Store_If_Inequal ...
procedure Store_If_Less ...
procedure Store_If_Greater ...
--
-- Increment value
--
procedure Increment (Item : in out Holder;
Increment : Value_Type'Base);
procedure Increment (Item : in out Holder;
Increment : Value_Type'Base;
Old_Value : out Value_Type'Base);
--
-- Compare old value to the barrier and if successful increment
--
procedure Increment_If_Greater (Item : in out Holder_Type;
Barrier : Value_Type'Base;
Increment : Value_Type'Base);
procedure Increment_If_Greater (Item : in out Holder_Type;
Barrier : Value_Type'Base;
Increment : Value_Type'Base;
Old_Value : out Value_Type'Base);
procedure Increment_If_Equal ...
procedure Increment_If_Inequal ...
procedure Increment_If_Less ...
procedure Increment_If_Greater ...
end Atomic_Object;
The implementation should be free to use machine instructions, a
spin-lock, or a protected object.
Example: reference counted object:
type Count_Type is mod 2**32;
package Atomic_Counters is new Atomic_Object (Count_Type, 0);
type Reference_Counted is record
Use_Count : Atomic_Counters.Holder_Type;
...
end record;
type Reference_Counted_Ptr is access all Reference_Counted;
procedure Free is new Ada.Unchecked_Deallocation (Reference_Counted,
Reference_Counted_Ptr);
type Handle is new Ada.Finalization.Controlled with record
Target : Reference_Counted_Ptr;
end record;
procedure Adjust (Pointer : in out Handle) is
begin -- Could check overflows using Increment_If_Less
Atomic_Counters.Increment (Pointer.Target.Use_Count, 1);
end Adjust;
procedure Finalize (Pointer : in out Handle) is
Old_Value : Count_Type;
begin
if Pointer.Target /= null then
Atomic_Counters.Increment_If_Greater
( Item => Pointer.Target.Use_Count,
Barrier => 0,
Increment => 0 - 1, -- Decrement by 1
Old_Value => Old_Value
);
case Old_Value is
when 0 => -- Use count is unexpectedly 0
raise Program_Error;
when 1 => -- Going to destroy the target
Free (Pointer.Target);
when others =>
null;
end case;
end if;
end Finalize;
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
next prev parent reply other threads:[~2017-05-18 17:44 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-06 2:23 Portable memory barrier? Jere
2017-05-06 8:47 ` Jeffrey R. Carter
2017-05-06 14:17 ` Jere
2017-05-06 19:08 ` Dennis Lee Bieber
2017-05-06 19:26 ` Jeffrey R. Carter
2017-05-06 19:41 ` Jeffrey R. Carter
2017-05-06 20:42 ` Niklas Holsti
2017-05-09 19:49 ` Randy Brukardt
2017-05-09 22:07 ` Jere
2017-05-11 1:14 ` Randy Brukardt
2017-05-10 18:28 ` Shark8
2017-05-11 1:17 ` Randy Brukardt
2017-05-11 16:23 ` Jeffrey R. Carter
2017-05-07 20:18 ` Robert Eachus
2017-05-08 7:45 ` Dmitry A. Kazakov
2017-05-08 15:56 ` Robert Eachus
2017-05-08 16:22 ` Dmitry A. Kazakov
2017-05-08 18:39 ` Robert Eachus
2017-05-08 19:18 ` Robert Eachus
2017-05-08 21:09 ` Dmitry A. Kazakov
2017-05-08 23:24 ` Robert Eachus
2017-05-09 0:30 ` Jere
2017-05-09 4:02 ` Robert Eachus
2017-05-09 4:32 ` Robert Eachus
2017-05-09 4:44 ` Robert Eachus
2017-05-09 22:26 ` Jere
2017-05-09 20:01 ` Randy Brukardt
2017-05-09 19:57 ` Randy Brukardt
2017-05-10 0:51 ` Jere
2017-05-10 5:25 ` J-P. Rosen
2017-05-10 22:56 ` Jere
2017-05-11 7:36 ` Dmitry A. Kazakov
2017-05-13 20:25 ` Jere
2017-05-10 7:13 ` Dmitry A. Kazakov
2017-05-10 16:45 ` Robert Eachus
2017-05-10 17:28 ` Simon Wright
2017-05-10 23:21 ` Jere
2017-05-11 0:47 ` Randy Brukardt
2017-05-13 20:11 ` Jere
2017-05-15 22:33 ` Randy Brukardt
2017-05-10 23:30 ` Jere
2017-05-11 0:38 ` Randy Brukardt
2017-05-10 16:38 ` Jeffrey R. Carter
2017-05-10 23:40 ` Jere
2017-05-10 16:19 ` Robert Eachus
2017-05-11 1:02 ` Randy Brukardt
2017-05-11 1:51 ` Robert Eachus
2017-05-15 22:45 ` Randy Brukardt
2017-05-08 20:29 ` Niklas Holsti
2017-05-08 21:09 ` Dmitry A. Kazakov
2017-05-09 4:34 ` Niklas Holsti
2017-05-09 6:16 ` Niklas Holsti
2017-05-09 8:34 ` Dmitry A. Kazakov
2017-05-09 20:18 ` Randy Brukardt
2017-05-09 20:10 ` Randy Brukardt
2017-05-09 0:05 ` Jere
2017-05-09 8:26 ` Dmitry A. Kazakov
2017-05-09 19:53 ` Randy Brukardt
2017-05-09 20:27 ` Dmitry A. Kazakov
2017-05-11 0:35 ` Randy Brukardt
2017-05-11 8:24 ` Dmitry A. Kazakov
2017-05-15 22:53 ` Randy Brukardt
2017-05-18 17:44 ` Dmitry A. Kazakov [this message]
2017-05-18 21:01 ` Randy Brukardt
2017-05-19 7:54 ` 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