------------------------------------------------------------------------------
--                                                                          --
--                         GNAT RUN-TIME COMPONENTS                         --
--                                                                          --
--                         S Y S T E M . M E M O R Y                        --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--         Copyright (C) 2001-2018, Free Software Foundation, Inc.          --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

--  This version provides ways to limit the amount of used memory for systems
--  that do not have OS support for that.

--  The amount of available memory available for dynamic allocation is limited
--  by setting the environment variable GNAT_MEMORY_LIMIT to the number of
--  kilobytes that can be used.
--
--  Windows is currently using this version.

with Ada.Exceptions;
with System.Soft_Links;

package body System.Memory is

   use Ada.Exceptions;
   use System.Soft_Links;

   function c_malloc (Size : size_t) return System.Address;
   pragma Import (C, c_malloc, "malloc");

   procedure c_free (Ptr : System.Address);
   pragma Import (C, c_free, "free");

   function c_realloc
     (Ptr : System.Address; Size : size_t) return System.Address;
   pragma Import (C, c_realloc, "realloc");

   function msize (Ptr : System.Address) return size_t;
   pragma Import (C, msize, "_msize");

   function getenv (Str : String) return System.Address;
   pragma Import (C, getenv);

   function atoi (Str : System.Address) return Integer;
   pragma Import (C, atoi);

   Available_Memory : size_t := 0;
   --  Amount of memory that is available for heap allocations.
   --  A value of 0 means that the amount is not yet initialized.

   Msize_Accuracy   : constant := 4096;
   --  Defines the amount of memory to add to requested allocation sizes,
   --  because malloc may return a bigger block than requested. As msize
   --  is used when by Free, it must be used on allocation as well. To
   --  prevent underflow of available_memory we need to use a reserve.

   procedure Check_Available_Memory (Size : size_t);
   --  This routine must be called while holding the task lock. When the
   --  memory limit is not yet initialized, it will be set to the value of
   --  the GNAT_MEMORY_LIMIT environment variable or to unlimited if that
   --  does not exist. If the size is larger than the amount of available
   --  memory, the task lock will be freed and a storage_error exception
   --  will be raised.

   -----------
   -- Alloc --
   -----------

   function Alloc (Size : size_t) return System.Address is
      Result      : System.Address;
      Actual_Size : size_t := Size;

   begin
      if Size = size_t'Last then
         Raise_Exception (Storage_Error'Identity, "object too large");
      end if;

      --  Change size from zero to non-zero. We still want a proper pointer
      --  for the zero case because pointers to zero length objects have to
      --  be distinct, but we can't just go ahead and allocate zero bytes,
      --  since some malloc's return zero for a zero argument.

      if Size = 0 then
         Actual_Size := 1;
      end if;

      Lock_Task.all;

      if Actual_Size + Msize_Accuracy >= Available_Memory then
         Check_Available_Memory (Size + Msize_Accuracy);
      end if;

      Result := c_malloc (Actual_Size);

      if Result /= System.Null_Address then
         Available_Memory := Available_Memory - msize (Result);
      end if;

      Unlock_Task.all;

      if Result = System.Null_Address then
         Raise_Exception (Storage_Error'Identity, "heap exhausted");
      end if;

      return Result;
   end Alloc;

   ----------------------------
   -- Check_Available_Memory --
   ----------------------------

   procedure Check_Available_Memory (Size : size_t) is
      Gnat_Memory_Limit : System.Address;

   begin
      if Available_Memory = 0 then

         --  The amount of available memory hasn't been initialized yet

         Gnat_Memory_Limit := getenv ("GNAT_MEMORY_LIMIT" & ASCII.NUL);

         if Gnat_Memory_Limit /= System.Null_Address then
            Available_Memory :=
              size_t (atoi (Gnat_Memory_Limit)) * 1024 + Msize_Accuracy;
         else
            Available_Memory := size_t'Last;
         end if;
      end if;

      if Size >= Available_Memory then

         --  There is a memory overflow

         Unlock_Task.all;
         Raise_Exception
           (Storage_Error'Identity, "heap memory limit exceeded");
      end if;
   end Check_Available_Memory;

   ----------
   -- Free --
   ----------

   procedure Free (Ptr : System.Address) is
   begin
      Lock_Task.all;

      if Ptr /= System.Null_Address then
         Available_Memory := Available_Memory + msize (Ptr);
      end if;

      c_free (Ptr);

      Unlock_Task.all;
   end Free;

   -------------
   -- Realloc --
   -------------

   function Realloc
     (Ptr  : System.Address;
      Size : size_t)
      return System.Address
   is
      Result      : System.Address;
      Actual_Size : constant size_t := Size;
      Old_Size    : size_t;

   begin
      if Size = size_t'Last then
         Raise_Exception (Storage_Error'Identity, "object too large");
      end if;

      Lock_Task.all;

      Old_Size := msize (Ptr);

      --  Conservative check - no need to try to be precise here

      if Size + Msize_Accuracy >= Available_Memory then
         Check_Available_Memory (Size + Msize_Accuracy);
      end if;

      Result := c_realloc (Ptr, Actual_Size);

      if Result /= System.Null_Address then
         Available_Memory := Available_Memory + Old_Size - msize (Result);
      end if;

      Unlock_Task.all;

      if Result = System.Null_Address then
         Raise_Exception (Storage_Error'Identity, "heap exhausted");
      end if;

      return Result;
   end Realloc;

end System.Memory;
