Oberon || Library || Module Index || Search Engine || Definition || Module


Ulm's Oberon Library:
Memory


NAME

Memory - address space management

SYNOPSIS

TYPE Address = Types.UntracedAddress;
TYPE Size = Types.Size;
(* allocation mode *)
CONST fixed = { 0 };
CONST growingForward = { 1 };
CONST growingBackward = { 0, 1 };
CONST redzoneProtected = { 2 };
TYPE AllocationMode = SET;
(* status returns for memory locations *)
CONST stAllocated = 1;
CONST stRedzone = 2;
CONST stReserved = 3;
CONST stThreatened = 4;
CONST stInternalFrag = 5;
CONST stFree = 6;
TYPE Status = SHORTINT; (* stAllocated..stFree *)
TYPE Region = POINTER TO RegionRec;
TYPE RegionRec = RECORD (Disciplines.ObjectRec) END;
(* assertions *)
VAR overlappingRegions: Events.EventType;
VAR addrNotOnPageBoundary: Events.EventType;
VAR pagesizeSetTwice: Events.EventType;
VAR undefinedPageSize: Events.EventType;
CONST cannotAllocRegion = 0;
CONST cannotExtendRegion = 1;
CONST fixedRegion = 2;
CONST reservedRegionsAreNotProtected = 3;
CONST badParamsOfReservedRegion = 4;
CONST errorcodes = 5;
TYPE ErrorEvent = POINTER TO ErrorEventRec;
TYPE ErrorEventRec =
   RECORD
      (Events.EventRec)
      errorcode: SHORTINT;
   END;
VAR errormsg: ARRAY errorcodes OF Events.Message;
VAR error: Events.EventType;


PROCEDURE ReserveRegion(addr: Address; len: Size; mode: AllocationMode; VAR region: Region); PROCEDURE AllocateRegion(len: Size; mode: AllocationMode; VAR addr: Address; VAR region: Region; errors: RelatedEvents.Object) : BOOLEAN; PROCEDURE ExtendRegion(region: Region; newlen: Size; errors: RelatedEvents.Object) : BOOLEAN; PROCEDURE ReleaseRegion(region: Region); PROCEDURE GetStatus(addr: Address; VAR status: Status; VAR region: Region); PROCEDURE SetPageSize(pagesize: Size); PROCEDURE GetPageSize() : Size; PROCEDURE AlignSize(VAR size: Size);

DESCRIPTION

Memory provides a general and machine-independent allocation of memory regions. The only dependency of the implementation is the type SysTypes.Address and its representation.

Usually there are many modules which accesses the address space: the compiler dependent procedures which are called by NEW and on creation of coroutines, system dependent modules which need space for shared memory or mapped files. Memory is to be used by all these procedures and modules to assure that no part of the address space is accidently used twice and for achieving more fairness for growing memory regions (e.g. for stacks of coroutines).

Following allocation modes are supported:

fixed
The size of the region is fixed and doesn't grow.
growingForward
The memory region may grow forward, i.e. from lower to higher addresses.
growingBackward
The memory region may grow backward, i.e. from higher to lower addresses.
redzoneProtected
At least one memory page before and after the region is to be reserved in addition to the returned region.
Exactly one of the modes fixed, growingForward and growingBackward is to be given. redzoneProtected may be added optionally.

Addresses and lengths must be multiplies of the system dependent page size. A length of 0 designates the entire address space.

Initially, Memory isn't aware of preallocated memory regions, e.g. for program text and the stack of the main coroutine. These preallocated memory regions are to be declared by use of ReserveRegion in the early stage of the startup phase by some system dependent modules. The memory region is specified by [addr, addr+len) for fixed or forward growing regions and by [addr-len, addr) for backward growing regions. An addr value of 0 represents the end of the address space in case of backward growing regions.

AllocateRegion tries to allocate a memory region of the given length and the given allocation mode. If successful, AllocateRegion returns a reference to the region in region. Further addr is returned which designates the beginning of the region (fixed and growingForward) or the end of the region (growingBackward).

ExtendRegion allows to extend growing regions by specifying a new length which must not be smaller than the previous length. The length of the memory region remains unchanged in case of failures.

ReleaseRegion allows to release a given region.

GetStatus returns the allocation status and, if possible, the associated region of the page which is designated by addr. Memory classifies pages according to following characteristics:

stAllocated
The memory page belongs to the returned region.
stRedzone
The memory page belongs to the redzone of the returned region.
stReserved
The area is reserved for a growing region and cannot be allocated to other regions.
stThreatened
This area is threatened by the returned growing region but not yet reserved or allocated.
stInternalFrag
The memory page cannot be allocated due to internal fragmentation caused by the returned fixed region.
stFree
The memory page is free.

SetPageSize must be called during the startup before any of the other procedures gets called.

GetPageSize returns the pagesize set previously and AlignSize aligns the given size to the next page boundary.

DIAGNOSTICS

Errors lead to events or assertions which are passed to RelatedEvents or Assertions. Following assertions and error codes are implemented:
overlappingRegions
A memory region has been given to ReserveRegion which overlaps existing regions.
addrNotOnPageBoundary
An address or length has been given which is not a multiply of the page size.
pagesizeSetTwice
SetPageSize was called twice.
undefinedPageSize
One of the procedures was called without a prior call of SetPageSize.
cannotAllocRegion
A memory region of the given length cannot be allocated.
cannotExtendRegion
The given memory region cannot be extended to the given length.
fixedRegion
ExtendRegion cannot extend fixed regions.
reservedRegionsAreNotProtected
Reserved regions cannot be redzone protected.
badParamsOfReservedRegion
The parameters addr and len specify a memory region which does not fit into the address space.

SEE ALSO

Assertions
handling of assertions
RelatedEvents
error handling
SysTypes
system dependent types

BUGS

The current implementation needs dynamic memory for its data structure and is free to call NEW during any of its operations and its initialization.

The implementation uses a modified buddy system allocator. This results in internal fragmentation for lengths which are not a power of 2. Only ReserveRegion is able to allocate the given length without internal fragmentation.


Edited by: borchert, last change: 1996/12/06, revision: 1.6, converted to HTML: 1997/04/28

Oberon || Library || Module Index || Search Engine || Definition || Module