From: anon@att.net
Subject: Re: User Defined Storage Pool : Example
Date: Sat, 22 Jan 2011 09:47:41 +0000 (UTC)
Date: 2011-01-22T09:47:41+00:00 [thread overview]
Message-ID: <ihe93r$1jd$1@news.ett.com.ua> (raw)
In-Reply-To: op.vpont3pqule2fv@garhos
-- referance delete for spacing
-- Found on www.adapower.com
--
-- http://www.adapower.com/index.php?Command=Class&ClassID=Advanced&CID=222
--
-- Files:
-- memory_management-test.adb
-- memory_management-support.ads
-- memory_management-support.adb
-- memory_management.ads
-- memory_management.adb
--
-- To compile and run:
--
-- >gnat make memory_management-test.adb
-- >memory_management-test
--
-- Memory Management with Storage Pools (Anh Vo)
--
-- Memory management can cause real headache due to memory leakage over
-- time. That is, memory allocation is not properly deallocated after the
-- call. When the memory runs out, the result could be catastrophic for
-- some applications. This problem can be recued by garbage collector
-- built-in the compiler such as Java. However, the cost of run-time
-- overhead is high.
-- Here comes Ada 95 to the recue. How is it possible you may ask? Ah!
-- Ada 95 provides a feature called Storage Pool. It allows the users
-- have total control over the memory management. Best of all, it does
-- not involve run-time overhead as garbage collector. When it is
-- combined with controlled type, the memory leakage problem is history.
-- As shown in the test case, 100 storage elements were allocated
-- initially. Then, these storage elements are reused again and again. It
-- is pretty cool isn't it? Enjoy.
--------------------------------------------
-- File => memory_management-test.adb
--
with Ada.Finalization ;
with Ada.Text_Io ;
with Memory_Management.Support ;
procedure Memory_Management.Test is
use Ada ;
use Text_Io ;
begin
Put_Line ("********* Memory Control Testing Starts **********") ;
for Index in 1 .. 10 loop
declare
David_Botton : Support.General_Data ;
Nick_Roberts : Support.General_Data ;
Anh_Vo : Support.General_Data ;
begin
David_Botton := ( Finalization.Controlled with
Id => new Integer' ( 111 ),
Name => new String' ( "David Botton" ) ) ;
Nick_Roberts := ( Finalization.Controlled with
Id => new Integer' ( 222 ),
Name => new String' ( "Nick Roberts" ) ) ;
Anh_Vo := ( Finalization.Controlled with
Id => new Integer' ( 333 ),
Name => new String' ( "Anh Vo" ) ) ;
end ;
end loop ;
Put_Line ( "Memory Management Test Passes" ) ;
exception
when others =>
Put_Line ( "Memory Management Test Fails" ) ;
end Memory_Management.Test ;
--------------------------------------------
-- File => memory_management-support.ads
--
with Ada.Finalization ;
package Memory_Management.Support is
use Ada ;
-- Adjust the storage size according to the application
Big_Pool : User_Pool ( Size => 100 ) ;
type Int_Acc is access Integer ;
for Int_Acc'Storage_Pool use Big_Pool ;
type Str_Acc is access all String ;
for Str_Acc'Storage_Pool use Int_Acc'Storage_Pool ;
type General_Data is new Finalization.Controlled
with record
Id : Int_Acc ;
Name : Str_Acc ;
end record ;
procedure Initialize ( Object : in out General_Data ) ;
procedure Finalize ( Object : in out General_Data ) ;
end Memory_Management.Support ;
--------------------------------------------
-- File => memory_management-support.adb
--
with Ada.Unchecked_Deallocation ;
package body Memory_Management.Support is
procedure Free is new Ada.Unchecked_Deallocation
( Integer, Int_Acc ) ;
procedure Free is new Ada.Unchecked_Deallocation
( String, Str_Acc ) ;
procedure Initialize ( Object : in out General_Data ) is
begin
null ;
end Initialize ;
procedure Finalize ( Object : in out General_Data ) is
begin
Free ( Object.Id ) ;
Free ( Object.Name ) ;
end Finalize ;
end Memory_Management.Support ;
--------------------------------------------
-- File => memory_management.ads
--
with System.Storage_Pools ;
with System.Storage_Elements ;
package Memory_Management is
use System ;
use Storage_Elements ;
use Storage_Pools ;
type User_Pool ( Size : Storage_Count ) is new
Root_Storage_Pool with private ;
procedure Allocate ( Pool : in out User_Pool ;
Storage_Address : out Address ;
Size_In_Storage_Elements : in Storage_Count ;
Alignment : in Storage_Count ) ;
procedure Deallocate
( Pool : in out User_Pool ;
Storage_Address : in Address ;
Size_In_Storage_Elements : in Storage_Count ;
Alignment : in Storage_Count ) ;
function Storage_Size ( Pool : in User_Pool )
return Storage_Count ;
-- Exeption declaration
Memory_Exhausted : exception ;
Item_Too_Big : exception ;
private
type User_Pool ( Size : Storage_Count ) is new Root_Storage_Pool
with record
Data : Storage_Array ( 1 .. Size ) ;
Addr_Index : Storage_Count := 1 ;
end record ;
end Memory_Management ;
--------------------------------------------
-- File => memory_management.adb
--
with Ada.Exceptions ;
with Ada.Text_Io ;
with System ;
with System.Storage_Elements ;
with System.Address_To_Access_Conversions ;
package body Memory_Management is
use Ada ;
use Text_Io ;
use System ;
use Storage_Elements ;
use type Storage_Count ;
Package_Name : constant String := "Memory_Management." ;
-- Used to turn on/off the debug information
Debug_On : Boolean := True ; -- False ;
type Holder is record
Next_Address : Address := System.Null_Address ;
end record ;
package Addr_To_Acc is new Address_To_Access_Conversions ( Holder ) ;
-- Keep track of the size of memory block for reuse
Free_Storage_Keeper : array ( Storage_Count range 1 .. 100 )
of Address := ( others => Null_Address ) ;
procedure Display_Info ( Message : string ;
With_New_Line : Boolean := True ) is
begin
if Debug_On then
if With_New_Line then
Put_Line ( Message ) ;
else
Put ( Message ) ;
end if ;
end if ;
end Display_Info ;
procedure Allocate ( Pool : in out User_Pool ;
Storage_Address : out Address ;
Size_In_Storage_Elements : in Storage_Count ;
Alignment : in Storage_Count ) is
Procedure_Name : constant String := "Allocate" ;
Temp_Address : Address := Null_Address ;
Marker : Storage_Count ;
begin
Marker := ( Size_In_Storage_Elements + Alignment - 1 )
/ Alignment ;
if Free_Storage_Keeper ( Marker ) /= Null_Address then
Storage_Address := Free_Storage_Keeper ( Marker ) ;
Free_Storage_Keeper (Marker) :=
Addr_To_Acc.To_Pointer
( Free_Storage_Keeper ( Marker ) ).Next_Address ;
else
Temp_Address := Pool.Data (Pool.Addr_Index)'Address ;
Pool.Addr_Index := Pool.Addr_Index
+ Alignment
* ( ( Size_In_Storage_Elements
+ Alignment - 1 )
/ Alignment ) ;
-- make sure memory is available as requested
if Pool.Addr_Index > Pool.Size then
Exceptions.Raise_Exception ( Storage_Error'Identity,
"Storage exhausted in "
& Package_Name
& Procedure_Name ) ;
else
Storage_Address := Temp_Address ;
end if ;
end if ;
Display_Info ( "Address allocated from pool: "
& Integer_Address'Image
( To_Integer ( Storage_Address ) ) ) ;
Display_Info ( "storage elements allocated from pool: "
& Storage_Count'Image
( Size_In_Storage_Elements ) ) ;
Display_Info ( "Alignment in allocation operation: "
& Storage_Count'Image ( Alignment ) ) ;
exception
when Error : others => -- Object too big or memory exhausted
Display_Info ( Exceptions.Exception_Information ( Error ) ) ;
raise ;
end Allocate ;
procedure Deallocate
( Pool : in out User_Pool ;
Storage_Address : in Address ;
Size_In_Storage_Elements : in Storage_Count ;
Alignment : in Storage_Count ) is
Marker : Storage_Count ;
begin
Marker := ( Size_In_Storage_Elements + Alignment - 1)
/ Alignment ;
Addr_To_Acc.To_Pointer ( Storage_Address ).Next_Address :=
Free_Storage_Keeper ( Marker ) ;
Free_Storage_Keeper ( Marker ) := Storage_Address ;
Display_Info ( "Address returned to pool: "
& Integer_Address'Image
( To_Integer ( Storage_Address ) ) ) ;
Display_Info ( "storage elements returned to pool: "
& Storage_Count'Image
( Size_In_Storage_Elements ) ) ;
Display_Info ( "Alignment used in deallocation: "
& Storage_Count'Image ( Alignment ) ) ;
end Deallocate ;
function Storage_Size ( Pool : in User_Pool )
return Storage_Count is
begin
return Pool.Size ;
end Storage_Size ;
end Memory_Management ;
next prev parent reply other threads:[~2011-01-22 9:47 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-22 0:04 User Defined Storage Pool : did you ever experiment with it ? Yannick Duchêne (Hibou57)
2011-01-22 0:55 ` Adam Beneschan
2011-01-22 1:42 ` Yannick Duchêne (Hibou57)
2011-01-22 5:19 ` Randy Brukardt
2011-01-22 8:49 ` Dmitry A. Kazakov
2011-01-22 9:47 ` anon [this message]
2011-01-22 9:54 ` AdaMagica
2011-01-24 9:57 ` Yannick Duchêne (Hibou57)
2011-01-24 10:48 ` Mark Lorenzen
2011-01-22 15:13 ` Simon Wright
2011-01-24 9:56 ` Yannick Duchêne (Hibou57)
2011-01-24 16:09 ` Simon Wright
2011-01-24 23:58 ` Yannick Duchêne (Hibou57)
2011-01-22 22:17 ` Fritz Wuehler
2011-01-24 9:52 ` Yannick Duchêne (Hibou57)
2011-01-24 14:20 ` Bill Findlay
2011-01-24 9:25 ` Ludovic Brenta
2011-01-24 9:43 ` Yannick Duchêne (Hibou57)
2011-01-24 13:43 ` Emmanuel Briot
2011-01-24 16:48 ` Dirk Craeynest
2011-01-25 1:16 ` Yannick Duchêne (Hibou57)
2011-01-24 11:46 ` Jacob Sparre Andersen
2011-01-24 23:51 ` Yannick Duchêne (Hibou57)
2011-02-10 7:59 ` Jacob Sparre Andersen
2011-02-13 15:56 ` AdaMagica
2011-02-13 19:10 ` Simon Clubley
2011-01-24 14:04 ` Timo Warns
2011-01-24 23:34 ` Yannick Duchêne (Hibou57)
2011-01-25 0:14 ` Yannick Duchêne (Hibou57)
2011-01-25 1:36 ` Randy Brukardt
2011-02-06 20:05 ` Yannick Duchêne (Hibou57)
2011-02-07 22:09 ` Randy Brukardt
2011-02-07 22:18 ` Randy Brukardt
2011-02-07 22:59 ` Maciej Sobczak
2011-02-07 23:57 ` Shark8
2011-02-08 13:40 ` Maciej Sobczak
2011-02-10 2:08 ` Randy Brukardt
2011-02-08 9:08 ` Alex R. Mosteo
2011-01-26 20:13 ` Warren
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox