next up previous contents index
Next: 16.5 Generic interface Up: 16 Address Map Manager: Previous: 16.3 Address maps and

16.4 Simple interface

 

Though the AMM is general enough to allow the user to associate arbitrary attributes with address map entries, one of the most common uses of address maps involves keeping track of which elements of a resource are free and which are available.

The AMM library provides an interface to make this ``simple'' use more convenient and, to some extent, more efficient. It is important to note that the simple interfaces are just wrappers for the generic interfaces described in Section 16.5. They are not a separate implementation. Thus, simple and generic routines can be called for the same map.

In the simple interface, the AMM pre-defines three attribute values: AMM_ALLOCATED, AMM_FREE, and AMM_RESERVED, and provides a set of routines that knows their semantics. Addresses that are AMM_ALLOCATED represent resources that are in use and unavailable until freed. Addresses that are AMM_FREE represent resources that are available for allocation. AMM_RESERVED addresses represent ``out of range'' resources that can not be allocated or freed.

amm_init performs the one-time initialization of an address map including restricting the ``valid'' range of addresses. Addresses within the specified range are marked as free and all others marked as reserved. amm_reserve allows additional areas of the address map to be reserved. This can be used to represent ``holes'' within an otherwise contiguous address map. amm_allocate allocates a range of a given size from the valid portion of the address map. This routine includes a ``hint'' address indicating where to start searching for free space in which to locate the range. Finally, amm_deallocate can be used to free a range of allocated space.

This set of routines is sufficient to implement basic resource management similar to that provided by UNIX resource maps. For example:

#include <oskit/amm.h>
#include <assert.h>

struct simple_rmap {
    amm_t amm;
};

void simple_rminit(struct simple_rmap *smap, oskit_addr_t saddr, oskit_addr_t eaddr)
{
    assert(saddr != 0);    /* zero is used to indicate allocation errors */
    amm_init(&smap->amm, saddr, eaddr);
}

oskit_addr_t simple_rmalloc(struct simple_rmap *smap, oskit_size_t size)
{
    oskit_addr_t addr = 0;

    return amm_allocate(&smap->amm, &addr, size, 0) ? 0 : addr;
}

void simple_rmfree(struct simple_rmap *smap, oskit_addr_t addr, oskit_size_t size)
{
    (void)amm_deallocate(&smap->amm, addr, size);
}

Three additional routines enable the simple interface to be used for another common OS usage: managing process/task address spaces. amm_protect changes the attributes associated with a range of the map. Attributes are restricted to whatever can be described in the flag word and should not clash with the AMM_ALLOCATED, AMM_FREE, and AMM_RESERVED bits, but there are typically only a small number of address space protection bits anyway so this isn't likely to be a problem. amm_find_addr looks up an address, returning a pointer to the entry containing the address. A final function, amm_iterate takes a function pointer and calls that function for every entry in the map, passing the map and map entry pointers as arguments. This allows the user to traverse the map, examining each entry in turn.

When using the simple AMM interface, map entries are allocated with malloc, deallocated with free, and the default library routines are used to split and join entries based on the attributes in the flag word.


next up previous contents index
Next: 16.5 Generic interface Up: 16 Address Map Manager: Previous: 16.3 Address maps and

University of Utah Flux Research Group