



Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
A machine problem assignment for implementing a simple memory allocator that uses the fibonacci buddy system scheme. The allocator should manage physical memory by partitioning it into zones and using a buddy-system allocator for each zone. The allocator implements my_malloc() and my_free() functions to allocate and deallocate memory portions. The management of free memory blocks is made easy by using an array of free lists for each allowable block size. Fragmentation may occur as memory blocks are rounded up to the next allowable block size.
Typology: Assignments
1 / 5
This page cannot be seen from the preview
Don't miss anything!




Introduction
In this machine problem, you are to develop a simple memory allocator that implements the functions my malloc() and my free(), very similarly to the UNIX calls malloc() and free(). (Let’s assume that – for whatever reason – you are unhappy with the memory allocator provided by the system.) The objectives of this Machine Problem are
Background: Kernel Memory Management. The kernel manages the physical memory both for itself and for the system and user processes. The memory occupied by the kernel code and its data is reserved and is never used for any other purpose. Other physical memory may be used as frames for virtual memory, for buffer caches, and so on. Most of this memory must be allocated and de-allocated dynamically, and an infrastructure must be in place to keep track of which physical memory is in use, and by whom. Ideally, physical memory should look like a single, contiguous segment from which an allocator can take memory portions and return them. This is not the case in most systems. Rather, different segments of physical memory have different properties. For example, DMA may not be able to address physical memory above 16MB. Similarly, the system may contain more physical memory than what can be directly addressed, and the segments above need to be handled using appropriate memory space extension mechanisms. For all these reasons, many operating systems (for example Linux) partition the memory into so-called zones, and treat each zone separately for allocation purposes. Memory allocation requests typically come with a list of zones that can be used to satisfy the request. For example, a particular request may be preferably satisfied from the “normal” zone. If that fails, from the high-memory zone that needs special access mechanisms. Only if that fails too, the allocation may attempt to allocation from the DMA zone. Within each zone, many systems (for example Linux) use a buddy-system allocator to allocate and free physical memory. This is what you will be providing in this machine problem (for a single zone, and of course not at physical memory level).
Your Assignment. You are to implement a C module (.h and .c files) that realizes a memory allocator as defined by the following file my allocator.h:
#ifndef MY_ALLOCATOR_H #define MY_ALLOCATOR_H
/* File: my_allocator.h */
typedef void * Addr;
unsigned int init_allocator(unsigned int _basic_block_size, unsigned int _length); /* This function initializes the memory allocator and makes a portion of ’_length’ bytes available. The allocator uses a ’_basic_block_size’ as its minimal unit of allocation. The function returns the amount of memory made available to the allocator. If an error occurred, it returns 0. */
int release_allocator(); /* This function returns any allocated memory to the operating system. After this function is called, any allocation fails. */
Addr my_malloc(unsigned int _length) {}; /* Allocate _length number of bytes of free memory and returns the address of the allocated portion. Returns 0 when out of memory. */
int my_free(Addr _a) {}; /* Frees the section of physical memory previously allocated using ’my_malloc’. Returns 0 if everything ok. */
#endif
You are to provide the implementation of the memory allocator in form of the file my allocator.c. The memory allocator you are supposed to implement is based on the Fibonacci Buddy System, which in turn is a generalization of the so-called “Buddy-System” scheme. (The Fibonacci Buddy System scheme is described in D. S. Hirschberg: “A class of dynamic memory allocation algorithms” in Communications of the ACM, 16(10):615:618, October 1973. A description of the Binary Buddy- System scheme – so-to-say Buddy System in the narrow sense – is given in Section 9.8.1 of the Silbershatz et al. textbook. A more detailed description of the Binary Buddy System is given in Section 2.5 of D. Knuth, “The Art of Computer Programming. Volume 1 / Fundamental Algo- rithms”. We give a very short overview of the Fibonacci Buddy System below.)
Fibonacci Buddy-System Memory Allocation:
Buddy-system allocators allocate memory in predefined block sizes, which are integer multiples of a basic block size (powers of two in the case of binary buddy systems, and Fibonacci numbers^1 in the case of Fibonacci buddy systems). For example, if 9kB of memory are requested, the allocator returns 12kB (3 is a Fibonacci number, times a basic block size of 4kB,) and 3kB goes wasted – this is called fragmentation. We will see that the restriction to allowable block sizes makes the management of free memory blocks very easy. The allocator keeps an array of free lists, one for each allowable block size. Every request is rounded up to the next allowable block size, and the corresponding free list is checked. If there is an entry in the free list, this entry is simply used and deleted from the free list. Splitting Free Blocks: If the free list is empty (i.e. there are no free memory blocks of this size,) a larger block is selected (using the free list of some larger block size) and split. Whenever a free (^1) Reminder: Fibonacci numbers satisfy the recursive relation F (k) = F (k − 1) + F (k − 2). The numbers 1, 2, 3, 5, 8, 13, 21,... are Fibonacci numbers.
free memory blocks themselves to store the free-list data. For example, the first bytes of each free memory block would contain the pointer to the previous and to the next free memory block of the same size. The pointers to the first and last block in each free list can easily be stored in an array of pointers, two for each allowable block size.
Note on Block Size: If you decide to put management information into allocated blocks (e.g. the size, as described above), you have to be careful about how this may affect the size of the allocated block. For example, when you allocate a block of size 5, and add an 8-word header to the block, you are actually allocating a 5 blocks +8 Word, which requires a block of size 8! (This is extremely wasteful.)
Where does my allocator get the memory from? Inside the initializer you will be allocating the required amount of memory from the run time system, using the malloc() command. Don’t forget to free this memory when you release the allocator.
What does my malloc() return? In the case above, putting the management information block in front of the the allocated memory block is as good a place as any. In this case make sure that your my malloc() routine returns the address of the allocated block, not the address of the management info block.
Initializing the Free List and the Free Blocks: You are given the size of the available memory as argument to the init() method. The given memory size is likely not a Fibonacci number. You are to partition the memory into a sequence of Fibonacci-number sized blocks and initialize the blocks and the free list accordingly.
You are to implement a buddy-system memory manager that allocates memory in blocks with sizes that are Fibonacci-number multiples of a basic block size. The basic block size is given as an argument when the allocator is initialized.
memtest [-b
-b
What to Hand In