1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- S Y S T E M . P O O L _ L O C A L --
9 -- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
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. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
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/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
34 with Ada
.Unchecked_Conversion
;
36 package body System
.Pool_Local
is
38 package SSE
renames System
.Storage_Elements
;
39 use type SSE
.Storage_Offset
;
41 Pointer_Size
: constant SSE
.Storage_Offset
:= Address
'Size / Storage_Unit
;
42 Pointers_Size
: constant SSE
.Storage_Offset
:= 2 * Pointer_Size
;
44 type Acc_Address
is access all Address
;
45 function To_Acc_Address
is
46 new Ada
.Unchecked_Conversion
(Address
, Acc_Address
);
48 -----------------------
49 -- Local Subprograms --
50 -----------------------
52 function Next
(A
: Address
) return Acc_Address
;
54 -- Given an address of a block, return an access to the next block
56 function Prev
(A
: Address
) return Acc_Address
;
58 -- Given an address of a block, return an access to the previous block
65 (Pool
: in out Unbounded_Reclaim_Pool
;
66 Address
: out System
.Address
;
67 Storage_Size
: SSE
.Storage_Count
;
68 Alignment
: SSE
.Storage_Count
)
70 pragma Warnings
(Off
, Alignment
);
72 Allocated
: constant System
.Address
:=
74 (Memory
.size_t
(Storage_Size
+ Pointers_Size
));
77 -- The call to Alloc returns an address whose alignment is compatible
78 -- with the worst case alignment requirement for the machine; thus the
79 -- Alignment argument can be safely ignored.
81 if Allocated
= Null_Address
then
84 Address
:= Allocated
+ Pointers_Size
;
85 Next
(Allocated
).all := Pool
.First
;
86 Prev
(Allocated
).all := Null_Address
;
88 if Pool
.First
/= Null_Address
then
89 Prev
(Pool
.First
).all := Allocated
;
92 Pool
.First
:= Allocated
;
101 (Pool
: in out Unbounded_Reclaim_Pool
;
102 Address
: System
.Address
;
103 Storage_Size
: SSE
.Storage_Count
;
104 Alignment
: SSE
.Storage_Count
)
106 pragma Warnings
(Off
, Storage_Size
);
107 pragma Warnings
(Off
, Alignment
);
109 Allocated
: constant System
.Address
:= Address
- Pointers_Size
;
112 if Prev
(Allocated
).all = Null_Address
then
113 Pool
.First
:= Next
(Allocated
).all;
114 Prev
(Pool
.First
).all := Null_Address
;
116 Next
(Prev
(Allocated
).all).all := Next
(Allocated
).all;
119 if Next
(Allocated
).all /= Null_Address
then
120 Prev
(Next
(Allocated
).all).all := Prev
(Allocated
).all;
123 Memory
.Free
(Allocated
);
130 procedure Finalize
(Pool
: in out Unbounded_Reclaim_Pool
) is
131 N
: System
.Address
:= Pool
.First
;
132 Allocated
: System
.Address
;
135 while N
/= Null_Address
loop
138 Memory
.Free
(Allocated
);
146 function Next
(A
: Address
) return Acc_Address
is
148 return To_Acc_Address
(A
);
155 function Prev
(A
: Address
) return Acc_Address
is
157 return To_Acc_Address
(A
+ Pointer_Size
);
160 end System
.Pool_Local
;