File : s-memory.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT RUN-TIME COMPONENTS                         --
   4 --                                                                          --
   5 --                         S Y S T E M . M E M O R Y                        --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --          Copyright (C) 2001-2016, 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 is the default implementation of this package
  33 
  34 --  This implementation assumes that the underlying malloc/free/realloc
  35 --  implementation is thread safe, and thus, no additional lock is required.
  36 --  Note that we still need to defer abort because on most systems, an
  37 --  asynchronous signal (as used for implementing asynchronous abort of
  38 --  task) cannot safely be handled while malloc is executing.
  39 
  40 --  If you are not using Ada constructs containing the "abort" keyword, then
  41 --  you can remove the calls to Abort_Defer.all and Abort_Undefer.all from
  42 --  this unit.
  43 
  44 pragma Compiler_Unit_Warning;
  45 
  46 with System.CRTL;
  47 with System.Parameters;
  48 with System.Soft_Links;
  49 
  50 package body System.Memory is
  51 
  52    use System.Soft_Links;
  53 
  54    function c_malloc (Size : System.CRTL.size_t) return System.Address
  55     renames System.CRTL.malloc;
  56 
  57    procedure c_free (Ptr : System.Address)
  58      renames System.CRTL.free;
  59 
  60    function c_realloc
  61      (Ptr : System.Address; Size : System.CRTL.size_t) return System.Address
  62      renames System.CRTL.realloc;
  63 
  64    -----------
  65    -- Alloc --
  66    -----------
  67 
  68    function Alloc (Size : size_t) return System.Address is
  69       Result : System.Address;
  70    begin
  71       --  A previous version moved the check for size_t'Last below, into the
  72       --  "if Result = System.Null_Address...". So malloc(size_t'Last) should
  73       --  return Null_Address, and then we can check for that special value.
  74       --  However, that doesn't work on VxWorks, because malloc(size_t'Last)
  75       --  prints an unwanted warning message before returning Null_Address.
  76 
  77       if Size = size_t'Last then
  78          raise Storage_Error with "object too large";
  79       end if;
  80 
  81       if Parameters.No_Abort then
  82          Result := c_malloc (System.CRTL.size_t (Size));
  83       else
  84          Abort_Defer.all;
  85          Result := c_malloc (System.CRTL.size_t (Size));
  86          Abort_Undefer.all;
  87       end if;
  88 
  89       if Result = System.Null_Address then
  90 
  91          --  If Size = 0, we can't allocate 0 bytes, because then two different
  92          --  allocators, one of which has Size = 0, could return pointers that
  93          --  compare equal, which is wrong. (Nonnull pointers compare equal if
  94          --  and only if they designate the same object, and two different
  95          --  allocators allocate two different objects).
  96 
  97          --  malloc(0) is defined to allocate a non-zero-sized object (in which
  98          --  case we won't get here, and all is well) or NULL, in which case we
  99          --  get here. We also get here in case of error. So check for the
 100          --  zero-size case, and allocate 1 byte. Otherwise, raise
 101          --  Storage_Error.
 102 
 103          --  We check for zero size here, rather than at the start, for
 104          --  efficiency.
 105 
 106          if Size = 0 then
 107             return Alloc (1);
 108          end if;
 109 
 110          raise Storage_Error with "heap exhausted";
 111       end if;
 112 
 113       return Result;
 114    end Alloc;
 115 
 116    ----------
 117    -- Free --
 118    ----------
 119 
 120    procedure Free (Ptr : System.Address) is
 121    begin
 122       if Parameters.No_Abort then
 123          c_free (Ptr);
 124       else
 125          Abort_Defer.all;
 126          c_free (Ptr);
 127          Abort_Undefer.all;
 128       end if;
 129    end Free;
 130 
 131    -------------
 132    -- Realloc --
 133    -------------
 134 
 135    function Realloc
 136      (Ptr  : System.Address;
 137       Size : size_t)
 138       return System.Address
 139    is
 140       Result      : System.Address;
 141    begin
 142       if Size = size_t'Last then
 143          raise Storage_Error with "object too large";
 144       end if;
 145 
 146       if Parameters.No_Abort then
 147          Result := c_realloc (Ptr, System.CRTL.size_t (Size));
 148       else
 149          Abort_Defer.all;
 150          Result := c_realloc (Ptr, System.CRTL.size_t (Size));
 151          Abort_Undefer.all;
 152       end if;
 153 
 154       if Result = System.Null_Address then
 155          raise Storage_Error with "heap exhausted";
 156       end if;
 157 
 158       return Result;
 159    end Realloc;
 160 
 161 end System.Memory;