Copyright (c) Hyperion Entertainment and contributors.

Exec Item Pools

From AmigaOS Documentation Wiki
Jump to navigation Jump to search

Introduction

An item pool is a special memory pool that can only allocate and deallocate predefined slabs of memory. Every allocation from this pool is exactly the same size. There are no exceptions to this rule. Allocation and deallocation of these items is typically extremely fast unless the pool needs to be enlarged or garbage collection takes place. Item pools are commonly called "slab allocators" although the latter usually also refers to a kind of allocation that leaves data intact between calls.

An item pool should be used whenever an application wants to allocate a large number of equally sized objects. For example, an application allocating a couple thousand Rectangle structures, or list items, could use an item pool for that to dramatically reduce the allocation time and memory fragmentation.

Many applications frequently allocate very similar pieces of memory, like list nodes, rectangles, or similar structures. If these items are sufficiently large, their constant allocation and deallocation will produce a potentially large amount of fragmented memory nodes.

Creating an Item Pool

You create an item pool by calling AllocSysObject() with the ASOT_ITEMPOOL object type and the item size, memory type, garbage collection policy and other options.

The item pool is created with an initial amount of item storage space and automatically extends when that space runs out. To control the maximum number of allocations allowed use the ASOITEM_MaxSize tag.

The memory type is one of MEMF_PRIVATE or MEMF_SHARED. The MEMF_ANY type may be used to indicate that either of these memory types is suitable. If your application requires memory of different types (for example, private memory and shared memory), it must create a pool for each type.

Setting MEMF_CLEAR in the memory flags will result in clearing each allocated item (prior to calling any defined constructor hook) so it might introduce a certain overhead.

If successful, AllocSysObject() returns the address of the item pool.

APTR item_pool = IExec->AllocSysObjectTags(ASOT_ITEMPOOL,
  ASOITEM_MFlags, MEMF_PRIVATE | MEMF_CLEAR,
  ASOITEM_ItemSize, sizeof(struct Rectangle),
  TAG_END);
 
if (item_pool != NULL)
{
  // ...
}
else
  IDOS->Printf("Pool could not be created.\n");

The example above attempts to create an item pool with an item size of sizeof(struct Rectangle).

Take note that all you know about an item pool is its address. Do not poke around it trying to figure out its organization. It's private for a reason!

Allocating Memory from an Item Pool

You must not make any assumptions about the contents of a newly created item (other than having it cleared when MEMF_CLEAR is specified). Most notably, the content of an item may change when it is re-allocated.

Items within an item pool are not necessarily packed closely together. The system may adjust the item size for better cache coherency or other factors.

If set to non-NULL values, the constructor and destructor hooks are called with the newly allocated item or an item to be deallocated.

Deleting an Item Pool

Similar to old exec memory pools, all memory allocated in the item pool is delete as soon as the item pool itself is freed (via a call to FreeSysObject).