The implementation of the memory allocator follows the algorithm described in a USENIX 1988 paper called "Design of a General Purpose Memory Allocator for the 4.3BSD Unix Kernel" by Marshall K. McKusick and Michael J. Karels. You can find it at various locations on the net, including http://docs.FreeBSD.org/44doc/papers/kernmalloc.pdf. A minor variation allows this implementation to have 'extendable' heaps when needed, with multiple memory extents providing autonomous page address spaces.
The data structures hierarchy is as follows:
HEAP {
block_buckets[]
extent_queue -------+
} |
V
EXTENT #1 {
{static header}
page_map[npages]
page_array[npages][pagesize]
} -+
|
|
V
EXTENT #n {
{static header}
page_map[npages]
page_array[npages][pagesize]
}
Files | |
file | heap.c |
Dynamic memory allocation services. | |
Functions | |
int | xnheap_init (xnheap_t *heap, void *heapaddr, u_long heapsize, u_long pagesize) |
Initialize a memory heap. | |
int | xnheap_destroy (xnheap_t *heap, void(*flushfn)(xnheap_t *heap, void *extaddr, u_long extsize, void *cookie), void *cookie) |
Destroys a memory heap. | |
void * | xnheap_alloc (xnheap_t *heap, u_long size) |
Allocate a memory block from a memory heap. | |
int | xnheap_test_and_free (xnheap_t *heap, void *block, int(*ckfn)(void *block)) |
Test and release a memory block to a memory heap. | |
int | xnheap_free (xnheap_t *heap, void *block) |
Release a memory block to a memory heap. | |
int | xnheap_extend (xnheap_t *heap, void *extaddr, u_long extsize) |
Extend a memory heap. | |
void | xnheap_schedule_free (xnheap_t *heap, void *block, xnholder_t *link) |
Schedule a memory block for release. |
|
Allocate a memory block from a memory heap. Allocates a contiguous region of memory from an active memory heap. Such allocation is guaranteed to be time-bounded.
This service can be called from:
Rescheduling: never. |
|
Destroys a memory heap. Destroys a memory heap.
This service can be called from:
Rescheduling: never. |
|
Extend a memory heap. Add a new extent to an existing memory heap.
This service can be called from:
Rescheduling: never. |
|
Release a memory block to a memory heap. Releases a memory region to the memory heap it was previously allocated from.
Environments: This service can be called from:
Rescheduling: never. |
|
Initialize a memory heap. Initializes a memory heap suitable for time-bounded allocation requests of dynamic memory.
Environments: This service can be called from:
Rescheduling: never. |
|
Schedule a memory block for release. This routine records a block for later release by xnheap_finalize_free(). This service is useful to lazily free blocks of heap memory when immediate release is not an option, e.g. when active references are still pending on the object for a short time after the call. xnheap_finalize_free() is expected to be eventually called by the client code at some point in the future when actually freeing the idle objects is deemed safe.
This service can be called from:
Rescheduling: never. |
|
Test and release a memory block to a memory heap. Releases a memory region to the memory heap it was previously allocated from. Before the actual release is performed, an optional user-defined can be invoked to check for additional criteria with respect to the request consistency.
This service can be called from:
Rescheduling: never. |