File : s-atocou-builtin.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT RUN-TIME COMPONENTS                         --
   4 --                                                                          --
   5 --               S Y S T E M . A T O M I C _ C O U N T E R S                --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --          Copyright (C) 2011-2015, Free Software Foundation, Inc.         --
  10 --                                                                          --
  11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  22 -- You should have received a copy of the GNU General Public License and    --
  23 -- a copy of the GCC Runtime Library Exception along with this program;     --
  24 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  25 -- <http://www.gnu.org/licenses/>.                                          --
  26 --                                                                          --
  27 -- GNAT was originally developed  by the GNAT team at  New York University. --
  28 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
  29 --                                                                          --
  30 ------------------------------------------------------------------------------
  31 
  32 --  This package implements Atomic_Counter and Atomic_Unsigned operations
  33 --  for platforms where GCC supports __sync_add_and_fetch_4 and
  34 --  __sync_sub_and_fetch_4 builtins.
  35 
  36 package body System.Atomic_Counters is
  37 
  38    procedure Sync_Add_And_Fetch
  39      (Ptr   : access Atomic_Unsigned;
  40       Value : Atomic_Unsigned);
  41    pragma Import (Intrinsic, Sync_Add_And_Fetch, "__sync_add_and_fetch_4");
  42 
  43    function Sync_Sub_And_Fetch
  44      (Ptr   : access Atomic_Unsigned;
  45       Value : Atomic_Unsigned) return Atomic_Unsigned;
  46    pragma Import (Intrinsic, Sync_Sub_And_Fetch, "__sync_sub_and_fetch_4");
  47 
  48    ---------------
  49    -- Decrement --
  50    ---------------
  51 
  52    procedure Decrement (Item : aliased in out Atomic_Unsigned) is
  53    begin
  54       if Sync_Sub_And_Fetch (Item'Unrestricted_Access, 1) = 0 then
  55          null;
  56       end if;
  57    end Decrement;
  58 
  59    function Decrement (Item : aliased in out Atomic_Unsigned) return Boolean is
  60    begin
  61       return Sync_Sub_And_Fetch (Item'Unrestricted_Access, 1) = 0;
  62    end Decrement;
  63 
  64    function Decrement (Item : in out Atomic_Counter) return Boolean is
  65    begin
  66       --  Note: the use of Unrestricted_Access here is required because we
  67       --  are obtaining an access-to-volatile pointer to a non-volatile object.
  68       --  This is not allowed for [Unchecked_]Access, but is safe in this case
  69       --  because we know that no aliases are being created.
  70 
  71       return Sync_Sub_And_Fetch (Item.Value'Unrestricted_Access, 1) = 0;
  72    end Decrement;
  73 
  74    ---------------
  75    -- Increment --
  76    ---------------
  77 
  78    procedure Increment (Item : aliased in out Atomic_Unsigned) is
  79    begin
  80       Sync_Add_And_Fetch (Item'Unrestricted_Access, 1);
  81    end Increment;
  82 
  83    procedure Increment (Item : in out Atomic_Counter) is
  84    begin
  85       --  Note: the use of Unrestricted_Access here is required because we are
  86       --  obtaining an access-to-volatile pointer to a non-volatile object.
  87       --  This is not allowed for [Unchecked_]Access, but is safe in this case
  88       --  because we know that no aliases are being created.
  89 
  90       Sync_Add_And_Fetch (Item.Value'Unrestricted_Access, 1);
  91    end Increment;
  92 
  93    ----------------
  94    -- Initialize --
  95    ----------------
  96 
  97    procedure Initialize (Item : out Atomic_Counter) is
  98    begin
  99       Item.Value := 1;
 100    end Initialize;
 101 
 102    ------------
 103    -- Is_One --
 104    ------------
 105 
 106    function Is_One (Item : Atomic_Counter) return Boolean is
 107    begin
 108       return Item.Value = 1;
 109    end Is_One;
 110 
 111 end System.Atomic_Counters;