140 likes | 331 Views
TAMU CSCE 313 (MP1 – Memory Allocator). TA: Daniel Miller dmiller@neo.tamu.edu. How does an operating system view and handle memory?. simple setup: one contiguous block Block is broken up and ‘handed out’ to requesting programs. Memory. prog 1. prog 2. prog 4. prog 3.
E N D
TAMU CSCE 313(MP1 – Memory Allocator) TA: Daniel Miller dmiller@neo.tamu.edu
How does an operating system view and handle memory? • simple setup: one contiguous block • Block is broken up and ‘handed out’ to requesting programs Memory prog 1 prog 2 prog 4 prog 3
What limitations exist with memory allocations? • Hardware doesn’t allow us to reference past a certain level (so forget those ideas easy bit assignment) -> thus a minimum size exists • There is only a finite amount of memory (whether physical or virtual) -> thus a maximum memory size exists = Basic Block = Largest Block possible for memory
How do we organize and keep track of ‘free’ memory? • Establish a free list – an array of pointers to linked lists, with each index pointing to a list of blocks (of memory) of a particular size • How to have linked list with memory blocks? • headers: the first section of memory inside the block that we will use for storing info of size, next pointer, symbol a b c d e f null e a d null free list memory header user memory
How do you break or combine a block • Breaking: • Calculate right child’s header location and write in header for it, while left child just takes the parent header and overwrites that • Combining: • Overwrite left buddy’s header with updated information and overwrite the right buddy’s header with junk NOTE: Symbol is used solely to verify you are in a valid location, thus upon creation of a header set it to a constant and when ‘removing’ overwrite it. Basically it helps check later when you do pointer arithmetic to get to some header that you are at a valid header location, because at the place the symbol should be the constant has already been written. UPDATE the Free List header user data pointer to header?
What about buddies • Breaking: • left child has parent’s memory address • right child’s address has the size bit flipped to 1 • Combining • Xor with bit mask of for size to get buddyie ~ for size 4, mask = 00100address 00000 xor 00100 = 00100address 00100 xor 00100 = 00000 convention: size Address (starting at 0) 8 ~ 00000 4 ~ 00000 4 ~ 00100 Bit shift 1<<i = 2^i 2 ~ 00000 2 ~ 00010 2 ~ 00100 2 ~ 00110
Great, now how in the world can we code this? • Get user specifications on the basic block size and memory segment size from the command line using getopt() • Establish your memory segment and free list as well as your initial block segments in init_allocator() • my_malloc is defined to return a block of free memory of certain size from the free list if available (breaking up larger blocks into smaller buddies if needed) • my_free() is defined to take back memory user returns and combine blocks to ensure that large requests are satisfied if possible (in buddy scheme) • upon exit the program release_allocator() is called and gives the system back the memory we reserved dynamically for the free list and memory segment (use atexit command)
Setup (initialization) • Define a header structure! • Dynamic arrays of lists can be defined like: void** var_name = malloc(num_of_elements_in_array * size_of_one_element) • void ** is a notation saying a void pointer to a set of pointers, a bit confusing • 2 malloc calls should be the max needed! • memory = malloc(memory_size) • free list = malloc(num_indices x sizeof(ptr_to_block)) • Binary scheme: f(i) = 2^i , 1,2,4,8,16,32,64,128,256,… • Largest block is the size of the largest multiple x basic block size that is ≤ memory size (and thus you can find how many indices should be in the free list) • Node’s aren’t created, they are overwritten using pointer casting such as: (Header*)(ptr_p)->size = 5 • All blocks defined are done by writing in their headers and storing the header location in the free list • Find largest block and write header (and store in free list), jump pointer to remainder, find largest block and write header (and store in free list), repeat until remainder is 0 or less than the smallest Block (< smallest Block is bad input and you can terminate the program upon receiving it) • Don’t forget to set unused pointers to NULL
Requests (my_malloc) • Calculate actual request size (remember our header placement) • search in free list at corresponding index to the fib multiple x Basic Block size that first fits • if found, remove from list and pass them the pointer (not the header pointer, they’ll destroy it!) • if not, check larger free list indices and subdivide recursively to satisfy request if it is possible (with case of no memory just output an error message and continue) UPDATE the Free List
Returning Memory (my_free) • check and see if pointer is a valid memory location (not null or out of memory size established) • jump to the header to get the block info (use pointer arithmetic using type-casting) • locate address of the buddy header (use your buddy bit and size info) and see if can combine blocks • Correct case: buddy’s address is found located in correct index list of free list • combine with the buddy if possible and see if the newly combined block has a free buddy to combine with • repeat process until either you can’t combine with the buddy or no buddy exists (case of top/initial block) UPDATE the Free List
What to hand in (online) • Correct and compiling C/C++ code that is commented so that others can understand your work (the more complex the more you should explain) • 1 page report over the assignment: • typical report may consist of: • a technical/performance evaluation of assignment • report of problems encountered/lessons learned • theoretical improvements for the assignment (ways to make it more efficient, faster, etcetera) • general feedback and thoughts regarding the problem
Advice and Common Mistakes • Start early and compile often • Create functions to print header info and the free list to debug easier • Try making your own memory requests before using the ackerman function (it recursively calls your my_malloc and my_free) • Turn in a report, it’s 25% of the grade • Work on the simplest problems first and build up in stages (setting up memory and free list, breaking up one block, recursively breaking blocks, etc.) • Ask questions if you are stuck, and you’re most likely not the only one confused • DO NOT COPY ANOTHER PERSON’S CODE!!! …unless you want to waste all your effort in this course
Advice and Common Mistakes • and finally… laugh, it eases your stress level