CMSC-341 Fall 2004

Project 2

Assigned 6 Oct 2004
Due 19 Oct 2004 at 11:59PM


Background

It is difficult to overstate the importance of the list abstract data type. This project will give you experience working with lists in the context of a dynamic memory allocation system.


Description

In this project you will implement a dynamic memory allocation system, like the one the manages calls to malloc() and free() in the C programming language. You will implement three classes - MemBlock, FreeBin, and MemoryManager. Objects of type MemBlock simply specify the starting and ending addresses of a block of memory. Objects of type FreeBin maintain a list of blocks of free memory, all of the same size. Objects of type MemoryManager maintain a set of FreeBins of various sizes from which memory is allocated, and a list of MemBlocks that are currently allocated.

The ADTs that you will implement are described fully in the ADT section below. Use the description there to design your classes. Please remember that you must provide good documentation as described in the Project Organization handout.

Here are your tasks:

  1. Obtain the files LinkedList.h, LinkedList.cpp, and dsexceptions.h from the following location:

    /afs/umbc.edu/users/o/a/oates/pub/CMSC341/Proj2/

    These files do not adhere to CS341 coding standards. You can use them "as is". That is, you do not need to edit them to bring them up to CS341 standards. HINT: You might find it useful to change the retrieve method to return a reference rather than a constant reference.

  2. Implement the MemBlock class.
  3. Implement the FreeBin class.
  4. Implement the MemoryManager class.
  5. Copy the file Proj2.cpp from:
  6. /afs/umbc.edu/users/o/a/oates/pub/CMSC341/Proj2/Proj2.cpp

    to your own directory. This Proj2.cpp is a driver that you can use to test your program. You do not need to submit it, nor do you need to write your own Proj2.cpp, though you will probably do so anyway to test your code. We provide this Proj2.cpp because if your Makefile works with it, your Makefile will work with the driver programs we will use to grade your project. However, you can submit a Proj2.cpp if you wish to ensure that submitmake and submit run work for this project. If you submit a Proj2.cpp, it will be overwritten by the grading scripts.

  7. Answer the questions posed in 341-Fall04-proj2_questions.txt. Copy the file
  8. /afs/umbc.edu/users/o/a/oates/pub/CMSC341/Proj2/341-Fall04-p2_questions.txt

    to your own directory and edit it to provide your answers to the questions. Don't forget to submit the edited file; it's 10% of this project's grade.


Definition of the ADT

Overview
The figure below shows a block of memory being managed, and the state of the memory manager. Note that this is just an example to show conceptually how the data structures are organized in one specific case. Suppose the memory manager is responsible for the memory from addresses 0 through 127. Initially, the entire block of memory is free. After several requests of the memory manager to allocate and free memory, the 128 bytes might be configured as shown in the top part of the figure. The first 32 bytes (from 0 to 31) are free (denoted by an F above the block). The next 8 bytes (from 32 to 39) are free as well, but the next 8 bytes (from 40 to 47) are allocated (denoted by an A above the block), and so on.

Information about the state of a block of memory is maintained in a MemoryManager object as shown in the lower part of the figure. The MemoryManager maintains a linked list of FreeBins, with the sizes of blocks of memory stored in the FreeBins increasing by a factor of 2 as you move down the list, starting with a block size of 8 bytes. In the figure there are FreeBins for blocks of size 8, 16, 32, 64, and 128.

Each FreeBin maintains a linked list of MemBlocks that are free and of the appropriate size. For example, the first FreeBin has a list of two 8-byte blocks that are free - bytes 32 through 39, and 48 through 55. Within a FreeBin, blocks are kept in sorted order by increasing start address.

In addition, the MemoryManager maintains a linked list of MemBlocks that have been alloocated. This list does not need to be kept in any sorted order. In the figure, there are four blocks of memory that have been allocated - two 8-byte blocks and two 16-byte blocks.

To allocate a block of memory of size N, the MemoryManager does the following:

To free a block of memory, the MemoryManager does the following: Any time a block is inserted into a FreeBin, it might be the case that two consecutive blocks in the list are also adjacent in memory. For example, in the figure above, if the 40-47 block is freed, the FreeBin for blocks of size 8 will contain the following blocks: 32-39, 40-47, and 48-55. That is, the 16-byte block of memory from address 32 to address 47 is free, but it is split up in two 8-byte blocks and thus cannot be used to satisfy a request for more than 8 bytes. To fix this situation, the MemoryManager must remove the two 8-byte blocks from the 8-byte FreeBin, create a new 16-byte block, and insert it into the 16-byte FreeBin. Note that this may result in the need to merge two 16-byte blocks, and so on. Also note that in the example above, there is the choice of whether to merge blocks 32-39 and 40-47 or blocks 40-47 and 48-55. In cases such as this, always merge the first pair rather than the second.

For each class described below, all data members must be private. Other than this requirement and any others explicitly stated in the description of a class, you have the freedom to design the class as you see fit. However, remember that you will be graded on the quality of that design. Be sure to note that it is generally a good idea to write an explicit destructor, copy constructor, and assignment operator, even if they are never called explicitly in your code, because they are often called implicitly.

MemBlock
MemBlocks specify the start and end addresses of a block of memory (either free or allocated) that is managed by a MemoryManager. All addresses must be of type mem_addr_t, which must be declared in MemBlock.h as follows: Also consider the following when implementing the MemBlock class:
FreeBin
Consider the following when implementing the FreeBin class:
MemoryManager
The MemoryManager must implement the following public methods with the prototypes shown: In addition, you must implement operator<< using as shown in the example code on page 35 of the Weiss text. This operator should output the contents of the FreeBins and the list of allocated blocks. An example of the output of this operator is shown below in the Sample Output section. This is one of the most important methods you will write. The output of this method is what we will look at when determining if your program is working correctly. Make sure that it works, is complete, and produces output that is easy to read and understand.

It will be useful to have a private method that takes as input the start and end addresses of a block of memory and inserts that block into the appropriate FeeBin (if its size is a power of 2) or FreeBins (if it needs to be decomposed into a number if smaller blocks whose sizes are powers of 2).

The main routine
Rather than having you write a main routine that reads commands from a command file, all you need to do is write and test the three classes described above. To test your code, we will write Proj2.cpp, and compile and link it with the classes you write. Your Makefile should assume that there is a Proj2.cpp file, like the one you can obtain as described in the task list above.

Sample Output

The following Proj2.cpp file:
#include <iostream.h>
#include "MemoryManager.h"

using namespace std;

int main(int argc, char **argv) {
  MemoryManager m;

  m.initialize(1, 32);

  cout << m;
  cout << endl << endl;

  mem_addr_t p1, p2, p3, p4;

  p1 = m.alloc(1);
  p2 = m.alloc(1);
  p3 = m.alloc(1);
  p4 = m.alloc(1);

  m.free(p1);
  m.free(p3);
  
  cout << m << endl << endl;

  m.free(p2);

  cout << m << endl << endl;

  m.free(p4);

  cout << m << endl << endl;
}
Creates the following output:
Memory Manager
--------------

FreeBins
--------
FreeBin: size = 8

FreeBin: size = 16

FreeBin: size = 32
MemBlock: 1 - 32


Allocated
---------


Memory Manager
--------------

FreeBins
--------
FreeBin: size = 8

FreeBin: size = 16
MemBlock: 1 - 16

FreeBin: size = 32


Allocated
---------
MemBlock: 17 - 24
MemBlock: 25 - 32


Memory Manager
--------------

FreeBins
--------
FreeBin: size = 8
MemBlock: 25 - 32

FreeBin: size = 16
MemBlock: 1 - 16

FreeBin: size = 32


Allocated
---------
MemBlock: 17 - 24


Memory Manager
--------------

FreeBins
--------
FreeBin: size = 8

FreeBin: size = 16

FreeBin: size = 32
MemBlock: 1 - 32


Allocated
---------



Files To Be Submitted

Submit all files required to build an executable named Proj2 by running make. Remember that you do not need to submit a file named Proj2.cpp, as we will write one to test your code.

Submit the files using the procedure given to you for your section of the course.
If your makefile is set up correctly, you should be able to execute the command make submit.

Submit Tools
There are a number of tools available to you to check on your submittal. It is your responsibility to ensure that the submittal is correct and will result in a successful
compilation of your project. Do not wait till the last minute to submit your files. Give yourself enough time to check that your submittal is correct.

If you don't submit a project correctly, you will not get credit for it. Why throw away all that hard work you did to write the project? Check your
submittals. Make sure they work. Do this before the due date.

Documentation for the submit program is on the web at http://www.gl.umbc.edu/submit/. One of the tools provided by the submit program is
submitls. It lists the names of the files you have submitted.

Additionally, there are two programs for use only by CMSC-341 students (not part of the UCS submit program). They are in the directory
/afs/umbc.edu/users/o/a/oates/pub/CMSC341/ and are named submitmake and submitrun. You can use these programs to
make or run your submitted projects.

The syntax is similar to that for submit:

submitmake <class> <project>

Example:  submitmake cs341 Proj1

This makes the project, and shows you the report from the make utility. It cleans up the directory after making the project (removes .o and ii_files), but leaves the
executable in place.

submitrun <class> <project> [command-line args]

Example:  submitrun cs341Proj1 checkers checkfile.dat

This runs the project, assuming there is an executable (i.e. submitmake was run successfully).


Grading and Academic Integrity

Your project will be tested using a variety of command lines, some of which will be invalid.
Your project will also be tested using a variety of command files which will test various conditions which your code should handle.

Project grading is described in the Project Policy handout.

Your answers to 341-Fall04-proj1_questions.txt are worth 10% of your project grade.

Cheating in any form will not be tolerated. Please re-read the Project Policy handout for further details on honesty in doing projects for this course.

Remember, the due date is firm. Submittals made after midnight of the due date will not be accepted. Do not submit any files after that time.