Copyright (c) Hyperion Entertainment and contributors.

Obsolete Exec Memory Allocation

From AmigaOS Documentation Wiki
Jump to navigation Jump to search

Introduction

Prior to AmigaOS 4.0, Exec's memory system was implemented as a simple linked list. Many older applications may have used the obsolete techniques described in this section to handle memory resources.

The purpose of this section is to describe the obsolete techniques in detail so that it may be easier to port those applications to Exec's modern memory system.

Memory Attributes

When asking the system for memory, an application can ask for memory with certain attributes. The currently supported flags are listed below.

Attribute Flag Meaning
MEMF_ANY This indicates that there is no requirement for the memory. Exec will always try to allocate faster memory before slower memory (if available). This is the default and should be used as often as possible. MEMF_ANY memory may be paged out. A typical implementation of malloc() would use MEMF_ANY as the memory flag.
MEMF_CHIP Deprecated. This indicates the application wants a block of chip memory, meaning it wants memory addressable by the classic Amiga custom chips. Chip memory is required for any data that will be accessed by custom chip DMA. This includes screen memory, images that will be blitted, sprite data, copper lists and audio data. Only useful on classic machines and should be avoided.
MEMF_FAST Deprecated. This indicates a memory block outside of the range that the classic Amiga special purpose chips can access. "FAST" means that the special-purpose chips do not have access to the memory and thus cannot cause processor bus contention, therefore processor access will likely be faster. Since the flag specifies memory that the custom chips cannot access, this flag is mutually exclusive with the MEMF_CHIP flag. Only useful on classic machines, and should be avoided
MEMF_VIRTUAL Use virtual memory in any case. This will fail if only public memory is available. Usually, you should not use this flag but use MEMF_ANY instead.
MEMF_EXECUTABLE Allocate memory that can hold executable code. Executable code must be placed in a specifically marked segment in memory to prevent buffer overflow exploits and for the automatic code type determination (PowerPC native vs. emulated 68k) to work. Failure to do so will result in an ISI exception.
MEMF_PUBLIC Deprecated. This indicates that the memory should be accessible to other tasks. MEMF_PUBLIC memory can never be paged out. See the discussion below why you should avoid it.
MEMF_SHARED Memory of this type is sharable between tasks. See the discussion below for details.
MEMF_PRIVATE Memory allocated with this flag is private for this task only. No other task can access it and any attempt to do so will result in a DSI exception.

Several flags are available that modifies or augments the memory allocation in a specific way. They can usually be used together with other flags listed above.

Modifier Flag Meaning
MEMF_CLEAR This indicates that the memory should be initialized with zeros.
MEMF_LOCAL Deprecated. This indicates memory which is located on the motherboard which is not initialized on reset.
MEMF_24BITDMA Deprecated. This indicates that the memory should be allocated within the 24 bit address space, so that the memory can be used in Zorro-II expansion device DMA transactions. This bit is for use by Zorro-II DMA devices only. It is not for general use by applications.
MEMF_REVERSE Deprecated. Indicates that the memory list should be searched backwards for the highest address memory chunk which can be used for the memory allocation.
MEMF_NO_EXPUNGE Prevents expunging from happening if set. Expunge is the process of freeing unused system resources.
MEMF_HWALIGNED Causes memory to be aligned to the hardware's physical page size. This flag is useful if you want to use the MMU to, for example, write protect memory.
MEMF_DELAYED Delay actual allocation of physical pages until they are accessed. Not currently implemented.

MEMF_PUBLIC and MEMF_SHARED

MEMF_PUBLIC is about one of the most misused features of AmigaOS. MEMF_PUBLIC was more or less described as "memory that cannot be swapped out, moved, or otherwise made unavailable." Unfortunately, this more or less applied to any memory in the classic AmigaOS. Therefore, many people just added the MEMF_PUBLIC flag to just about any allocation.

Starting with AmigaOS 4.0 a new MEMF_SHARED flag was introduced. Part of the problem of MEMF_PUBLIC is that classic AmigaOS device drivers assume that the physical and virtual addresses of a block of memory are the same. This assumption was carried over into AmigaOS 4.x. However, the cost of this is that less virtualized memory is available. Public memory is therefore limited in AmigaOS 4.x and only a fixed amount of it is made available during system startup. MEMF_PUBLIC is almost always completely unnecessary and can be replaced by MEMF_SHARED.

What does MEMF_PUBLIC mean?

MEMF_PUBLIC assumes that a memory block is allocated that cannot be physically moved around, is contiguous and will not be swapped. If you look at it this way, these requirements are almost always unnecessary. A normal application does not need to care about the physical address of a memory block nor will it have to think about the block not being contiguous as long as the virtual addresses are. The only requirement an application may have is to pin a block of memory, preventing it from being swapped out, for performance reasons. Swapped out memory might take a much longer time to be made available which can be an issue depending on the application.

MEMF_PUBLIC, due to its design, implies that the block of memory is available to all tasks and entities in the system. This is important for sending messages, for example. At the moment, there is nothing in the system that actually prevents access to another task's memory but semantics dictate that messages should be globally shared and a future memory system will enforce these semantics.

In summary, MEMF_PUBLIC means:

  • cannot be swapped
  • cannot be moved
  • accessible to all tasks
  • physical address equals virtual address
  • memory is contiguous

What does MEMF_SHARED mean?

A memory block that was allocated with MEMF_SHARED is accessible to all tasks and entities on the system. It is not protected and thus can be written to and read from by any task. Usually, its attributes can be changed as well. Other than that, no restriction is placed on the memory, which means it can be swapped (if not locked) and it can move in physical address space (not in virtual address space) and it might be not physically contiguous.

In summary, MEMF_SHARED means

  • can be swapped
  • can be moved
  • accessible to all tasks
  • physical and virtual address likely will be different
  • memory might not be physically contiguous (but not virtually)