30
1 FOSDEM 2016 Memory Management with Ada 2012 January 30 th , 2016 J-P. Rosen ADALOG [email protected]

Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

1FOSDEM 2016

Memory Managementwith Ada 2012

January 30th, 2016

J-P. [email protected]

Page 2: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

2FOSDEM 2016

Outline

When you don't need it

Access Types in Ada

Managing Memory

Conclusion

Page 3: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

3FOSDEM 2016

Some Definitions

Global (permanent) variables are at fixed memory locationsAda : Variables declared in library packagesPermanent lifetime, never released

Local variables (of subprograms) are allocated on a stackAKA automatic variablesAda : variables of subprograms (and tasks)Automatically released when subprogram exitsRequired for recursivity and multi-tasking

Dynamic variables are allocated on a heap (pool)Ada : variables created by allocators – newHave to be released by someone, sometime (manually,

automatically when not used any more...)

Page 4: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

4FOSDEM 2016

When you don't need it

Page 5: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

5FOSDEM 2016

Dynamic Stack Variables

Ada allows stack variables of statically-unknown size

Size given by initial value:

type Vector is array (Positive range <>) of Length;begin

loopGet (N);exit when N=0;declare

Dyn_Array : Vector (1 .. N); -- N statically unknownbegin

Dyn_Array := (others => 0.0); -- No restriction on usage…

end;end loop;

end;

Buffer : constant String := Get_Value_From_Network; -- No overflow possible!

Page 6: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

6FOSDEM 2016

Containers

Containers are useful for most usagesUse pointers internally, nothing visible outsideMemory management is fully controlled, no leak

✔ We'll see later how…

Inspired by the STLVectorsMapsDoubly linked listsMutliway treesSets ...

Page 7: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

7FOSDEM 2016

Access Types In Ada

Page 8: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

8FOSDEM 2016

Access (?) Types in Ada

Access types provide indirect access to variables and subprogramsOK, they are pointersAn access type is not an address

SyntaxPool specific

Generalized access to variable

Generalized access to constant

type Name is [not null] access Designated_Type;

type Name is [not null] access all Designated_Type;

type Name is [not null] access constant Designated_Type;

Really a pointer with read-only rights

Page 9: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

9FOSDEM 2016

Basic usage

The null value designates nothingAutomatic initialization

✔ All access objects are initialized to null

Dereference is checked✔ Dereferencing null Exception Constraint_Error

If type defined as not null:✔ Null value not allowed, all pointers must be initialized

AllocatorsSimple allocator (uninitialized)

Initialized allocator

P := new Date; – Equivalent to: V: Date;

P := new Date'(D); -- Equivalent to: V: Date := D;

Page 10: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

10FOSDEM 2016

Dereference

Explicit: .all, implicit when no ambiguity

User defined implicit dereference

type Major is (Letters, Sciences, Technology);type Student_Record (With_Major : Major) is

recordMathematics : Grade;case With_Major is

when Sciences => Physics : Grade;…

end case;end record;

type Student_Record_Ptr is access Student_Record;PSR1: Student_Record_Ptr;PSR2: Student_Record_Ptr;

beginPSR2 := new Student_Record (Sciences); -- No init, constraint must be givenPSR2.Physics := B; -- Equivalent to PSR.all.Physics := B;PSR1.all := PSR2.all

end;

Page 11: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

11FOSDEM 2016

Managing Memory

Page 12: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

12FOSDEM 2016

Issues

Allocated space must be returned when not used any moreA compiler may reclaim allocated memory when the

corresponding access type goes out of scope.

Returning all variables when they are not used any more does not guarantee the absence of memory shortage, due to fragmentation

Standard allocation/dealloction algorithm is usually part of the OS/Run-TimeEscapes validation, no user control

Standard allocation algorithm may be incompatible with real-time:Global lockBest fit / First fit often have unbounded WCET

Page 13: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

13FOSDEM 2016

Releasing Memory Space

The language provides:

A specific function must be instantiated for each access type:

Makes it easy to identify modules where memory is deallocated

generictype Object (<>) is limited private;type Name is access Object;

procedure Ada.Unchecked_Deallocation (X : in out Name);

type Link is access Node ;procedure Free is new Ada.Unchecked_Deallocation (Node, Link);

P : Link;...Free(P); -- Memory space designated by P is freed, and P is reset to null

Page 14: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

14FOSDEM 2016

Controlled Types (1)

A type whose initialization, finalization and assignment are under program's control.A controlled type is a descendant of Controlled or

Limited_Controlled:

Default procedures do nothing✔ Only those that need special processing need to be redefined

package Ada.Finalization istype Controlled is abstract tagged private;procedure Initialize (Object : in out Controlled);procedure Adjust (Object : in out Controlled);procedure Finalize (Object : in out Controlled);

type Limited_Controlled is abstract tagged limited private;procedure Initialize (Object : in out Limited_Controlled);procedure Finalize (Object : in out Limited_Controlled);

end Ada.Finalization;

Page 15: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

15FOSDEM 2016

Controlled Types (2)

InitializationThe procedure is called after assignment of default values.

FinalizationApplied in reverse order from initialization.

AssignmentLHS := RHS

✔ The LHS is finalized✔ Bit copy of RHS into LHS✔ Adjust is called on (new) LHS

Very convenient to hide pointers and memory management

To be honnest: it's slightly more complicated than that

(optional anonymous temporary)

Page 16: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

16FOSDEM 2016

Use of Controlled Types to Hide Access Types

Example: Unbounded_StringAn unbounded string is just a (controlled) pointer to String:

Old textA

B New text

New text 1) A is finalized

3) A is adjusted

2) Bit copy

type Unbouded_String is new Ada.Finalization.Controlled withrecord

Content : String_Access;end record;

procedure Adjust (Object : in out Unbounded_String);procedure Finalize (Object : in out Unbounded_String);

A := B

Page 17: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

17FOSDEM 2016

Collection

Memory space reserved for exclusive use by a given access type (and types derived from it).Reserved beforehandDoes not compete with other access types.

Specification of the size of a collectionNon static clause:

Reserves at least the given space (or Storage_Error is raised)

Exclusive of Storage_PoolRequires storage to be freed when the

scope of the type is left

Accessing the size of a collectionAttribute: Access_type'Storage_Size

for Ptr_T'STORAGE_SIZE use n;

Used by Ptr_T

Used by other access types

Page 18: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

18FOSDEM 2016

Null Storage_Size

Storage_Size can be anything, including 0

Special case : when Storage_Size is specified to be 0:Allocators (new) and Unchecked_Deallocation are not allowedPointers are only allowed to global or stack objects

Global/StackHeap

Pool specific GeneralGeneral General with null Storage_Size

Page 19: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

19FOSDEM 2016

Pools (1)

A pool type is a type derived from Root_Storage_Poolwith Ada.Finalization;with System.Storage_Elements;package System.Storage_Pools is

pragma Preelaborate (System.Storage_Pools);type Root_Storage_Pool is abstract new Ada.Finalization.Limited_Controlled with private;

procedure Allocate(Pool : in out Root_Storage_Pool; Storage_address: out Address; Size_in_storage_elements: in Storage_Elements.Storage_Count; Alignment : in Storage_Elements.Storage_Count) is abstract;

procedure Deallocate(Pool : in out Storage_Pool; Storage_address : in Address; Size_in_storage_elements: in Storage_Elements.Storage_Count; Alignment : in Storage_Elements.Storage_Count) is abstract;

function Storage_size (Pool : Root_storage_pool)return Storage_elements.Storage_count is abstract;

private...

end System.Storage_pools;

A controlled type

Page 20: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

20FOSDEM 2016

Pools (2)

How to manage dynamic allocation :Define policy

Declare one (or more) object(s):

Associate the object to an access type :

Properties:new gets memory by calling Allocate.Unchecked_Deallocation returns memory by calling Deallocate.T'Storage_size returns the result of calling Storage_SizeT'Storage_Pool designates the pool object associated with T

type Own_Pool is new System.Storage_pool.Root_Storage_Pool with ...;procedure Allocate ...;procedure Deallocate ...;function Storage_Size ...;

My_Pool : Own_Pool;

type T is access … with Storage_Pool => My_Pool;for T'Storage_Pool use My_Pool; -- Ada < 2012

Page 21: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

21FOSDEM 2016

Pools (3)

Example: Fixed size allocatorAllocated size is limited to slot sizeFull slot reserved whatever the

allocated sizeDeallocation frees the whole slotOf course, it wastes space…

BenefitsAllocation, deallocation are O(1)No fragmentationSlot size can be parameterized:

type Fixed_Allocator (Slot_Size : Positive) isnew System.Storage_pool.Root_Storage_Pool;

Page 22: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

22FOSDEM 2016

Default Storage Pool

The compiler provides a default storage pool for access types without associated storage pool.

The default storage pool can be specified:

The default pool can be null:

Forces Storage_Size to 0 (no allocator unless the type has user-defined storage pool)

pragma Default_Storage_Pool (Pool_Object);

pragma Default_Storage_Pool (null);

Page 23: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

23FOSDEM 2016

Usages of Pools

Manage memory with a custom algorithmKnown space and timing properties, certified algorithm…

DebuggingGnat.Debug_Pools

✔ Trace allocations/deallocations✔ Display high-water marks, un-deallocated space at termination…

Persistent objects (even better with automatic dereference) J. Sparre Andersen, Ada-Europe 2010Kazakov components

Page 24: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

24FOSDEM 2016

Subpools (1)

Some pools may manage subpoolsOf type Root_Storage_Pool_With_Subpools (derived from

Root_Storage_Pool)

A subpool is created with Create_SubpoolAn access type is associated with a pool (as before)An allocator may indicate a subpool:

✔ If no subpool is indicated, the default subpool is used (raises Program_Error by default)

A subpool can be reclaimed as a whole (with all its objects) by calling Deallocate_Subpool

Ptr := new (subpool) T;Ptr := new (subpool) T’(initial_value);

An indication of a "partition" of the space managed by the pool(whatever that means)

Page 25: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

25FOSDEM 2016

Subpools (2)

UsageMark-release pool (example in Ada RM 13.11.6)

✔ "Mark" creates a new subpool✔ "Release" frees the subpool and makes the previous one active✔ Not allowed to use a subpool other than the top one

"families" of objects to be reclaimed together✔ Each subpool is a linked list of objects

managing multiple heaps✔ Embedded systems: allocations either from private or shared memory

...

Page 26: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

26FOSDEM 2016

Conclusion

Page 27: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

27FOSDEM 2016

Garbage Collection

Ada allows, but does not require garbage collection It's implemented with the JVM and .Net compilers

Pros:Great when you are unable to manage memory

✔ When everything is dynamically allocated and you are not able to manage when to deallocate

✔ When pointers evade to far-away locations, and nobody knows when to deallocate

✔ Not Ada !

Cons:Does not always work (circular dependencies)Does not avoid fragmentationUnpredictable execution time, unpredictable triggeringNot a silver bullet

✔ "Don't forget to return unused variables to null, or the GC won't get them"

Page 28: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

28FOSDEM 2016

A Good Advice

Randy Bruckardt on comp.lang.ada, April 06, 2015

IMHO, the order of memory management preferability goes approximately as follows:

1) Stack-based (in Ada, this includes dynamically-sized objects, such as an array whose length depends on a parameter; this probably isn't implemented with a traditional stack, but the compiler will do the management).

2) Container-based. 3) Finalization-based. (Using a controlled wrapper of some sort;

deallocate on finalize. Smart pointers fall into this category. The only reason that these fall below 2) is that these are user-defined, meaning there is a higher possibility of errors. [Implementers make mistakes, but there are more people using there stuff so they don't last as long.])

4) Subpool-based. (Sometimes called "arenas"; this is a semi-automatic mechanism in that all items of a group are freed together.)

5) Manual allocate/deallocate (with or without storage pools).

Page 29: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

29FOSDEM 2016

Ada Is Safer Because...

Pointers are initialized to null

Pointers preserve strong typingNo "void *"Enforces profile in pointers to subprograms

Dereference is checked for validity

Unchecked_Deallocation returns pointer to null

Explicit with of Ada.Unchecked_Deallocation makes sensitive modules stand out

Encapsulation prevents pointers from leaking everywhereWith containers, no visible pointer anywhere

Controlled types provide for automatic management

Pools and subpools for user controlled memory management

No garbage collection!

Page 30: Memory Management with Ada 2012 - KU Leuvendirk.craeynest/ada... · FOSDEM 2016 3 Some Definitions Global (permanent) variables are at fixed memory locations Ada : Variables declared

30FOSDEM 2016