Logo Data Structures and Algorithms with Object-Oriented Design Patterns in C++
next up previous contents index

Buddy System for Storage Management

 

The preceding sections describe two storage pool implementations that both use a linear list to keep track of the free areas. When the singly-linked list is used, the linear list is kept sorted by address; when the doubly-linked list is used, the order of the areas in the list is essentially random.

Each time an area is to be reserved, the free lists are searched in order to find an area that is sufficiently large to satisfy the request. Since there is no direct relationship between the size of an area and its position in the free list, the search has worst-case running time that is O(l), where l is the length of the free list. And in the worst case l is O(n), where n is the number of blocks in the storage pool.

In this section we present a storage pool implementation, called a buddy system , that uses more than one free list. All of the areas in a given free list have the same size and there is a separate free list for each available size of area. As a result a suitable free area can be found quickly.

Given a storage pool of size N bytes, we would require N free lists altogether if we were to place no restriction the allowable size of an area. This is clearly infeasible. Instead we require that N is a power of two, i.e., tex2html_wrap_inline68165 for some positive integer m. Furthermore, the size of each area in the pool must also be a power of two. As a result, we only need m+1 free lists, since the allowed sizes of an area (in bytes) are

displaymath68145

The key feature of a buddy system is that when a request is made for an area of size tex2html_wrap_inline58821 for some k less than m, we first look in the corresponding free list for an area with the correct size. Notice that if there are no areas of size tex2html_wrap_inline58821 left, we can obtain one by splitting an area of size tex2html_wrap_inline68179 in two. And if there are no areas of size tex2html_wrap_inline68179 left, we can obtain one of those by splitting an area of size tex2html_wrap_inline68183 in two, and so on.

The two areas obtained when a larger area is split in two are called buddies. Whenever an area is freed, we check to see if its buddy is also free. If an area of size tex2html_wrap_inline58821 and its buddy are both free, they can be combined into a single area of size tex2html_wrap_inline68179.

Of course, the user does not always need an an amount of storage that is exactly a power of two. In those situations where it is not, we shall allocate an amount of memory that is the smallest power of two no less than the amount requested.

Figure gif shows a memory map of a storage pool managed using the buddy system. The reserved areas in Figure gif are exactly the same as those shown in Figure gif. Figure gif shows an important characteristic of the buddy pool: An area of size tex2html_wrap_inline58821 bytes is always aligned on a tex2html_wrap_inline58821 byte boundary. E.g., all 1KB areas are aligned on 1KB boundaries. I.e., they begin at 0KB, 1KB, 2KB, ...

   figure31625
Figure: Memory Map of a Buddy System Storage Pool

Let b be the offset from the start of the pool (in bytes) of an area of size tex2html_wrap_inline58821. Then for b to be aligned on a tex2html_wrap_inline58821 byte boundary means that tex2html_wrap_inline68201. In other words, the binary representation of the number b has the form

displaymath68146

where tex2html_wrap_inline66822 is the tex2html_wrap_inline58387 bit in the representation of b.

If we take the block of size tex2html_wrap_inline58821 at offset b and split it into two blocks of size tex2html_wrap_inline68217, the offsets of the two blocks which result are

align31641

I.e., the offsets of the buddies of size tex2html_wrap_inline58821 differ in only the tex2html_wrap_inline61700 bit position. This gives us a very simple way to determine the position of the buddy of a given area. I.e., given the offset of a buddy of size tex2html_wrap_inline58821 is b, the offset of the buddy is given by

  equation31657

Fortunately, it is quite simple to compute Equation gif since all that we need to do is toggle the tex2html_wrap_inline61700 bit of the binary representation b. This can be done using the bitwise exclusive-or operation   as the following function definition shows:

unsigned int Buddy (unsigned int b, unsigned int k)
    { return b ^ (1 << (k - 1U)); }

As before, we implement the storage pool as an array of Blocks. The structure of a Block is shown in Figure gif. A sequence of contiguous blocks in the array constitutes and area. This time the size (in bytes) of every area in the pool is an integer power of two. The first block in each area is used to keep track the entire area.

   figure31676
Figure: BuddyPool::Block Structure Layout

The structure of the block is quite similar to that used in the implementation of the DoublyLinkedPool class. I.e., the header is comprised of two parts: A single bit which indicates whether the area represented by the block is reserved or free and a field called k which specifies the size of the area. I.e., the size of the block is tex2html_wrap_inline68235 bytes.

The free lists are implemented as doubly-linked lists. Therefore, a free block contains two pointers, prev and next, which point to the previous and next areas (respectively) in the free list.




next up previous contents index

Bruno Copyright © 1997 by Bruno R. Preiss, P.Eng. All rights reserved.