Introduction
RISC OS memory is managed by Dynamic Areas. All areas of memory are assigned to a Dynamic Area which controls the sizing of the area, what is mapped into the area, and what access control is applied to it. These areas can themselves have certain properties which are managed by the Kernel - being sparse, and being able to be shrunk on demand would be examples of these properties.
Some modules using dynamic areas can provide operations to manage the content of those areas. A typical example of such management would be the Sprite Area which will be resized as operations are performed on it. One area that is considered special is the application space. This dynamic area is managed within the Operating System, and is treated a little differently by some parts of the system.
The application space is managed as a special dynamic area whose contents can be switched in and out on demand. The contents of these areas are known as 'Application Memory Blocks'. There is a dedicated SWI, SWI OS_AMBControl, which mananges the contents of the application space and these 'AMBs'.
This specialised management of the application space is largely historical, although there are certain performance improvements that are gained by the management being given preferential treatment.
Overview
Dynamic Area -1, known as the Application Space, usually contains the user mode code being executed by the system. This is the main place where code and data is stored for execution by the user. The application space lives at &8000, and contains a single continous block of paged memory. This area of memory, and the dynamic area which describes it, is able to controlled by the SWI OS_AMBControl SWIs.
Initially, only a single AMB exists, and is mapped into the application space. However, the WindowManager will manipulate the Dynamic Area to allow tasks to be switched in and out of the application space. The WindowManager concept of a 'Task' is its view on to the AMBs that it manages. The WindowManager hides the switching of application space from the user mode application tasks through the use of SWI Wimp_Poll.
Historically, the WindowManager usurped the management of the application space from the Kernel to perform the task switches. With the introduction of RISC OS 3.7, OS_AMBControl returned the control of the application space to the Kernel. This allows other managers to also perform application space management in a similar manner to that of the WindowManager.
Technical details
The application space is managed through OS_AMBControl through an 'AMB handle'. This is an opaque identifier which identifies a specific mapping of memory - the AMB. AMBs must be created, destroyed and managed through the SWI OS_AMBControl SWI. However, other SWIs may also have an effect on the region.
Application Memory Blocks
Application Memory Blocks ('AMBs') have a number of properties which are managed by the OS_AMBControl system:
- They define the contents of a region of memory.
- The memory to which they refer can be visible to the system ('mapped in') or inaccessible ('mapped out').
- The memory may be mapped within the application space (at &8000), or to an arbitary location in memory. This is used under special circumstances by the WindowManager for performance reasons.
- The number of pages which are used by the AMB.
The system keeps track of the Current AMB. This is the AMB which is mapped at the base of the application space. AMBs mapped into other areas of memory are a concession to the historic operation of the WindowManager. The Current AMB is reflected in the sizes returned from OS_ChangeDynamicArea and OS_DynamicArea.
The operating system interfaces which interact with the Current AMB are:
-
Calls to read the application space size will return the size of the current AMB.
-
On RISC OS Classic: Calls to change the application space size will fail. The size of the free pool must be changed to affect the AMB size. Removing pages from the Free Pool will add them to the AMB. Adding pages to the Free Pool will remove them from the AMB.
On RISC OS Pyromaniac: Calls to change the application space will change the AMB. The Free Pool does not exist.
-
The Application Space is never enumerated by OS_DynamicArea.
-
Environment Handler 0 contains the memory limit. This is the maximum address occupied by the Current AMB. This value is updated by when the Current AMB is changed, or the size of the Current AMB is updated.
-
Environment Handler 14 contains the application space size. This value is updated by when the Current AMB is changed, or the size of the Current AMB is updated.
On RISC OS Classic: Writing to this environment handler will directly manipulate the logical size of the dynamic area, and may have undesireable effects on the system.
-
Changes the size of the WindowManager's understanding of the current AMB, and the 'next' slot.
Caveats
Although the AMBs have been discussed in terms of their relationship to the Application Space dynamic area, there are special cases to be aware of.
AMB existence
On RISC OS Classic: The application space dynamic area may exist without a corresponding AMB to manage it. Only on starting the WindowManager do AMBs begin to be used. Until that time (or after the WindowManager has relinquished control), the application space is managed only through the standard DynamicArea operations. This is because the application space dynamic area and memory is controlled by the Kernel, with OS_AMBControl manipulating the state when it is used. Until OS_AMBControl is used, the application space essentially just another region of memory.
On RISC OS Pyromaniac: There is always an AMB handle present, and changes to it or dynamic areas will have the same effect. This is because the application space is owned by the OS_AMBControl system, and there is always a view on to application space which reflects OS_AMBControl's state.
Allocation of AMBs
On RISC OS Classic: On allocation of an AMB it will overlay the current mapping. If an AMB is already mapped into the application space, it may result in memory being present where the state of the dynamic areas (and OS_ValidateAddress) indicates there should not be any present. Always map out the AMB before use.
On RISC OS Pyromaniac: On allocation of an AMB, the Current AMB is always mapped out first.
Partial mapping of AMBs
On RISC OS Classic: AMBs may be mapped anywhere in memory. This is to allow the WindowManager to perform fast copies between applications.
On RISC OS Pyromaniac: AMBs may only be mapped into application space.
Lazy mapping
From RISC OS 4 onward, it is possible for the OS_AMBControl system to map regions of memory from the AMB only when required. The mapping still honours the maximum memory limits, and the pages are still allocated upfront, but page table updates may be deferred until an access requires the page. This was a performance improvement by avoiding large numbers of page table updates, and TLB or cache flushes on some systems. This behaviour was termed 'Lazy mapping'.
This behaviour is optional, and should be transparent to the user application. It may have an impact on applications relying on DMA, or which manipulate page tables directly. The behaviour can be controlled through SWI OS_AMBControl 5.
RISC OS Pyromaniac does not support this behaviour - it does not have page tables for this to have an effect.
SWI calls
R0 | = | Reason code and flag bits:
|
R0 - R3 | = | Dependant on reason code |
This SWI is used to control and read information about the Application Memory Blocks which manage the Application Space. Consult the individual reason codes for more information.
R0 | = | Reason code and flag bits:
| ||||||||||||
R1 | = | Number of pages requested |
R1 | = | Number of pages actually allocated |
R2 | = | New AMB handle |
This SWI is used to allocate a new AMB. The AMB will be given the size specified by the number of pages requested, if they are available. If the requested size is not available, the number of pages which were able to be allocated will be returned.
The newly allocated AMB becomes the Current AMB and will replace any AMB which is currently mapped in.
Note: It is not guaranteed that the pages allocated will have been cleared; they may contain data from earlier system use.
R0 | = | Reason code and flag bits:
| ||||||||||||
R2 | = | AMB handle |
R0 | preserved | |
R2 | preserved |
This SWI is used to deallocate a given AMB. The memory associated with the AMB will be discarded. If the AMB handle refers to the Current AMB, it will be mapped out.
Note: It is not guaranteed that the pages released will have been cleared; they may be available when mapped to other locations.
R0 | = | Reason code and flag bits:
| ||||||||||||
R1 | = | Number of pages requested | ||||||||||||
R2 | = | AMB handle |
R1 | = | Number of pages actually allocated |
R3 | = | Previous number of pages allocated |
This SWI is used to change the number of pages which are allocated to the AMB, resizing it. If the AMB handle refers to the Current AMB, the pages will be mapped into memory. Otherwise, the AMB pages will be added or removed logically, but not physically in memory.
Note: The pages added or removed may not be cleared.
R0 | = | Reason code and flag bits:
| ||||||||||||||||||||
R1 | = | Logical start address to map, or -1 to map out | ||||||||||||||||||||
R2 | = | AMB handle | ||||||||||||||||||||
R3 | = | Offset of start of mapping, in pages, if bit 8 of the flags is set | ||||||||||||||||||||
R4 | = | Number of pages to map, if bit 8 of the flags is set |
This SWI is used to control whether the AMB is mapped into the application space or not, or whether it is mapped into another area of memory (if bit 8 is set).
Partial address space mapping is only intended for specialised use for the WindowManager. It is not supported under RISC OS Pyromaniac.
R0 | = | Reason code and flag bits:
| ||||||||||||
R2 | = | AMB handle |
R1 | = | Current mapping start address, or -1 if mapped out (on RISC OS Classic, mapped out AMBs will return the address 'nowhere' - consult OS_ReadSysInfo for this location) |
R3 | = | Current number of pages |
This SWI is used to read information about a specific AMB.
R0 | = | Reason code and flag bits:
| ||||||||||||
R1 | = | 0 to disable laziness, 1 to enable laziness, -1 to read laziness | ||||||||||||
R2 | = | AMB handle |
R1 | = | New laziness value |
This SWI is used to control whether lazy mapping of AMBs is performed. Lazy mapping is not supported on RISC OS Pyromaniac and will always return 0, to indicate it is not supported.
R0 | = | Reason code and flag bits:
| ||||||||||||
R1 | = | Pointer to buffer for AMB information |
R0 - R1 | preserved |
This SWI is used for diagnostic purposes to return the information about all currently allocated AMBs. Call SWI OS_AMBControl 9 to read the number of AMBs currently in use, to size the buffer.
Offset | Contents | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
0 | Number of AMBs present in the table | ||||||||||
4 | Current AMB handle | ||||||||||
8 | List of AMB descriptors:
|
R0 | = | Reason code and flag bits:
|
R2 | = | Current AMB handle |
R3 | = | Number of AMBs present |
This SWI is used to read information about the number of AMBs and the Current AMB handle.
Error messages
The error AMBNoHandles is returned if too many AMB handles have been created and a new one cannot be allocated.
The error AMBBadReason is returned when the AMB handle supplied to an OS_AMBControl SWI is not valid.
The error AMBBadReason is returned when reason code supplied to an OS_AMBControl SWI is not recognised.
The error AMBInvalidFlags is returned when flags supplied to an OS_AMBControl SWI were not recognised.
The error AMBBadMapSlot is returned when an attempt has been made to map a slot to an invalid location in memory.