next up previous contents index
Next: 9.5.1 malloc_lmm: LMM pool Up: 9 Minimal C Library: Previous: 9.4.31 unistd.h: POSIX standard

9.5 Memory Allocation

 

All of the default memory allocation functions in the minimal C library are built on top of the OSKit LMM, described in Chapter 15.

There are three families of memory allocation routines available in the minimal C library. First is the standard malloc, realloc, calloc, and free. These work as in any standard C library.

The second family, smalloc, smemalign, and sfree, assume that the caller will keep track of the size of allocated memory blocks. Chunks allocated with smalloc-style functions must be freed with sfree rather than the normal free. These functions are not part of the POSIX standard, but are much more memory efficient when allocating many power-of-two-size chunks naturally aligned to their size (e.g., when allocating naturally-aligned pages or superpages). The normal memalign function attaches a prefix to each allocated block to keep track of the block's size, and the presence of this prefix makes it impossible to allocate naturally-aligned, natural-sized blocks successively in memory; only every other block can be used, greatly increasing fragmentation and effectively halving usable memory. (Note that this fragmentation property is not peculiar to the OSKit's implementation of memalign; most versions of memalign produce have this effect.)

The third family, mallocf, memalignf, smallocf, and smemalignf, allow LMM flags to be passed to the more common allocation routines. These are useful for allocating memory of a specific type (see 15.2). Memory allocated with these routines should be freed with free or sfree as appropriate.

All of the memory management functions, if they are unable to allocate a block out of the LMM pool, call the morecore function and then retry the allocation if morecore returns non-zero. The default behavior for this function is simply to return 0, signifying that no more memory is available. In environments in which a dynamically growable heap is available, you can override the morecore function to grow the heap as appropriate.

All of the memory allocation functions make calls to mem_lock and mem_unlock to protect access to the LMM pool under all of these services. The default implementation of these synchronization functions in the minimal C library is to do nothing. However, when the C library is initialized (see Section 9.9.1), a query for the lock manager will be made (See Section 4.12) to determine if there is a default implementation of locks available, and will use that implementation to guarantee thread/SMP safety. The absence of a lock manager implementation implies a single threaded environment, and thus locks are unnecessary. Additionally, they can be overridden with functions that acquire and release a lock of some kind appropriate to the environment in order to make the allocation functions thread- or SMP-safe. Also, note that if you link in liboskit_kern before liboskit_c, the kernel support library provides its own default implementation of mem_lock and mem_unlock, which call base_critical_enter and base_critical_leave respectively; this provides simple and robust, though probably far from optimal, memory allocation protection for kernel code running on the bare hardware.




next up previous contents index
Next: 9.5.1 malloc_lmm: LMM pool Up: 9 Minimal C Library: Previous: 9.4.31 unistd.h: POSIX standard

University of Utah Flux Research Group