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

-- Turbo_Platform.Operations, x86 version

with System, Interfaces; use System, Interfaces;

package Turbo_Platform.Operations is
   pragma Preelaborate;

   type Atomic_Integer_32 is limited private;
   for Atomic_Integer_32'Alignment use 4;

   type Atomic_Unsigned_32 is limited private;
   for Atomic_Unsigned_32'Alignment use 4;

   function Fetch (Source : in Atomic_Integer_32)
      return Integer_32;
   function Fetch (Source : not null access Atomic_Integer_32)
      return Integer_32;

   procedure Store (Destination : not null access Atomic_Integer_32;
      Value : Integer_32);
   procedure Store (Destination : in out Atomic_Integer_32;
      Value : Integer_32);
   function Exchange (Destination : not null access Atomic_Integer_32;
      Value : Integer_32) : Integer_32;
   
   function Compare_Exchange (Destination : not null access Atomic_Integer_32;
      Comparand, Replacement : Integer_32) return Boolean;
   function Compare_Exchange (Destination : not null access Atomic_Integer_32;
      Comparand, Replacement : Integer_32) return Integer_32;
   function Compare_Exchange (Destination : not null access Atomic_Integer_32;
      Comparand, Replacement : Integer_32; Fetched : out Integer_32)
      return Boolean;

   function Increment_Fetch (Addend : not null access Atomic_Integer_32)
      return Integer_32;
   function Fetch_Increment (Addend : not null access Atomic_Integer_32)
      return Integer_32;
   procedure Increment (Addend : in out Atomic_Integer_32);
   procedure Increment (Addend : not null access Atomic_Integer_32);

   function Increment_Fetch (Destination : not null access Atomic_Integer_32;
      Value : Integer_32) return Integer_32;
   function Fetch_Increment (Destination : not null access Atomic_Integer_32;
      Value : Integer_32) return Integer_32;
   procedure Increment (Destination : in out Atomic_Integer_32;
      Value : Integer_32);
   procedure Increment (Destination : not null access Atomic_Integer_32;
      Value : Integer_32);

   function Decrement_Fetch (Addend : not null access Atomic_Integer_32)
      return Integer_32;
   function Fetch_Decrement (Addend : not null access Atomic_Integer_32)
      return Integer_32;
   procedure Decrement (Addend : in out Atomic_Integer_32);
   procedure Decrement (Addend : not null access Atomic_Integer_32);

   function Decrement_Fetch (Destination : not null access Atomic_Integer_32;
      Value : Integer_32) return Integer_32;
   function Fetch_Decrement (Destination : not null access Atomic_Integer_32;
      Value : Integer_32) return Integer_32;
   procedure Decrement (Destination : in out Atomic_Integer_32;
      Value : Integer_32);
   procedure Decrement (Destination : not null access Atomic_Integer_32;
      Value : Integer_32);

private

   type Atomic_Integer_32 is new Integer_32;
   pragma Volatile (Atomic_Integer_32);

   type Atomic_Unsigned_32 is new Unsigned_32;
   pragma Volatile (Atomic_Unsigned_32);

end Turbo_Platform.Operations;
