summaryrefslogtreecommitdiff
path: root/src/vhdl/simulate/areapools.ads
blob: 186f297070232d64a48ab0287a3e05679719fbdf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
--  Area based memory manager
--  Copyright (C) 2014 Tristan Gingold
--
--  GHDL is free software; you can redistribute it and/or modify it under
--  the terms of the GNU General Public License as published by the Free
--  Software Foundation; either version 2, or (at your option) any later
--  version.
--
--  GHDL is distributed in the hope that it will be useful, but WITHOUT ANY
--  WARRANTY; without even the implied warranty of MERCHANTABILITY or
--  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
--  for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with GHDL; see the file COPYING.  If not, write to the Free
--  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
--  02111-1307, USA.

with System; use System;
with System.Storage_Elements; use System.Storage_Elements;

package Areapools is
   type Areapool is limited private;
   type Mark_Type is private;

   type Areapool_Acc is access all Areapool;

   --  Modular type for the size.  We don't use Storage_Offset in order to
   --  make alignment computation efficient (knowing that alignment is a
   --  power of two).
   type Size_Type is mod System.Memory_Size;

   --  Allocate SIZE bytes (aligned on ALIGN bytes) in memory pool POOL and
   --  return the address in RES.
   procedure Allocate (Pool : in out Areapool;
                       Res : out Address;
                       Size : Size_Type;
                       Align : Size_Type);

   --  Return TRUE iff no memory is allocated in POOL.
   function Is_Empty (Pool : Areapool) return Boolean;

   --  Higher level abstraction for Allocate.
   generic
      type T is private;
   function Alloc_On_Pool_Addr (Pool : Areapool_Acc; Val : T)
                               return System.Address;

   --  Get a mark of POOL.
   procedure Mark (M : out Mark_Type;
                   Pool : Areapool);

   --  Release memory allocated in POOL after mark M.
   procedure Release (M : Mark_Type;
                      Pool : in out Areapool);

   Empty_Marker : constant Mark_Type;
private
   --  Minimal size of allocation.
   Default_Chunk_Size : constant Size_Type := 16 * 1024;

   type Chunk_Type;
   type Chunk_Acc is access all Chunk_Type;

   type Data_Array is array (Size_Type range <>) of Storage_Element;
   for Data_Array'Alignment use Standard'Maximum_Alignment;

   type Chunk_Type (Last : Size_Type) is record
      Prev : Chunk_Acc;
      Data : Data_Array (0 .. Last);
   end record;
   for Chunk_Type'Alignment use Standard'Maximum_Alignment;

   type Areapool is limited record
      First, Last : Chunk_Acc := null;
      Next_Use : Size_Type;
   end record;

   type Mark_Type is record
      Last : Chunk_Acc := null;
      Next_Use : Size_Type;
   end record;

   Empty_Marker : constant Mark_Type := (Last => null, Next_Use => 0);

   Erase_When_Released : constant Boolean := True;
end Areapools;