--------------------------------
-- Ivan Levashew aka OCTAGRAM --
--              Barnaul, 2009 --
--------------------------------

-- Turbo_Private.Generic_Atomic_32, x86 version

generic
   type Type_32 is private;
package Turbo_Private.Generic_Atomic_32 is
   pragma Preelaborate;

   type Atomic_Type_32 is limited record
      Item : aliased Type_32;
      pragma Atomic (Item);
   end record;

   for Atomic_Type_32'Size use 32;
   for Atomic_Type_32'Alignment use 4;

   function Get (Source : in Atomic_Type_32)
      return Type_32;
   function Get (Source : not null access Atomic_Type_32)
      return Type_32;
   pragma Inline (Get);

   function "+" (Source : in Atomic_Type_32)
      return Type_32 renames Get;
   function "+" (Source : not null access Atomic_Type_32)
      return Type_32 renames Get;

   function Lazy_Get (Source : in Atomic_Type_32)
      return Type_32;
   function Lazy_Get (Source : not null access Atomic_Type_32)
      return Type_32;
   pragma Inline (Lazy_Get);

   procedure Set (Target : not null access Atomic_Type_32;
      Item : Type_32);
   procedure Set (Target : in out Atomic_Type_32;
      Item : Type_32);
   pragma Inline (Set);

   procedure Lazy_Set (Target : not null access Atomic_Type_32;
      Item : Type_32);
   procedure Lazy_Set (Target : in out Atomic_Type_32;
      Item : Type_32);
   pragma Inline (Lazy_Set);

   function Create (Item : Type_32) return Atomic_Type_32;
   pragma Inline (Create);

   function "+" (Item : Type_32) return Atomic_Type_32
      renames Create;
   pragma Inline ("+");

   function Lazy_Create (Item : Type_32) return Atomic_Type_32;
   pragma Inline (Lazy_Create);

   function Swap (Target : not null access Atomic_Type_32;
      Item : Type_32) return Type_32;
   pragma Inline (Swap);
   
   function Compare_Swap (Target : not null access Atomic_Type_32;
      Comparand, New_Item : Type_32) return Boolean;
   function Compare_Swap (Target : not null access Atomic_Type_32;
      Comparand, New_Item : Type_32) return Type_32;
   function Compare_Swap (Target : not null access Atomic_Type_32;
      Comparand, New_Item : Type_32; Fetched : not null access Type_32)
      return Boolean;

   function Compare_Swap (Target : not null access Type_32;
      Comparand, New_Item : Type_32) return Type_32; -- internal
   pragma Inline (Compare_Swap);

end Turbo_Private.Generic_Atomic_32;
