lecture 25 -- buddy mem alloc part 2 we went over the binary tree method of buddy alloc. see example alloc/dealloc tree: http://www.cs.uml.edu/~fredm/courses/91.308-spr05/files/buddy.txt this would be the tree that's created from the Wikipedia buddy example. also, dave kinsella presented his method, a recursive algorithm using the addr bits and alloc size info. see his post on the ikonboard, http://teaching-2.cs.uml.edu/cgi-bin/ikonboard/ikonboard.cgi?s=75bdb43e69fd51e528c05c5eadb19914;act=ST;f=82;t=24 his pseudo-code is copied below. ------------------------------------------------------------ if (next_node_free()) then if ((next_size == node_size) && check_buddy (node_addr/64k, next_addr/64k)) then combine_nodes() else nothing if(previous_node_free()) if ((previous_size == node_size) && check_buddy (previous_addr/64k, next_addr/64k)) then combine_nodes() else nothing check_buddy(int L, int R) if (((L % 2)==0) && ((R % 2)==0)) check _buddy(L/2, R/2) else if(((L % 2)==0) && ((R % 2)==1)) return 1; else return 0; 1) Check to see if next node is not allocated. 2) If it is free then check to see if the node size is equal to next node size. If they are not then they canies. 4) If they are buddies combine them and check next node. 5) If next node not buddy check previous node. How's it work? It is obvious you have to check to see if the nodes are the same size before you combine them so I will explain the rest. I used the same info from the sample on the web. I first masked off the last 15 bits by dividing by 64k. This made the recursion in my check buddy smaller. You can divide by 64k because this is the size of the blocks in the sample. For our program we would just divide by 32. Dividing by the 64k will just right shift the bits over 15 spots. The 15 spots that fall off the edge are just zero's anyway. Now our sample looks a little different. The address in binary for node A is 0000 for nodeB is 0010 for node C is 0001 and for node D is 0100. I will walk through my code at the start of freeing memory. Starting with 5 program C releases its memory. Check to see if the next node is free. It is not so it does nothing. Checks to see if the previous node is free. It is not so it does nothing. Program A releases its memory. Check to see if the next node is free. Yes. Checks to see if sizes are same. Yes. Then checks check_buddy. This is when it first masks off all the 0 bits. Address A is 0000 and nextnode is 0001. It fails the first case so it then checks the else. It passes this 0 % 2 = 0 and 1 % 2 = 1 so it returns one. Making the if ((next_size == node_size) && check_buddy (node_addr/64k, next_addr/64k)) true so it combines nodes. Program B releases its memory. Check to see if the next node is free. No. Checks to see if the previous node is free. Yes. Checks to see if sizes are same. Yes. Then checks check_buddy. This is when it first masks off all the 0 bits. Address of previous node is 0000 and C is 0001. It fails the first case so it then checks the else. It passes this 0 % 2 = 0 and 1 % 2 = 1 so it returns one. Making the if ((previous_size == node_size) && check_buddy (previous_addr/64k, previous_addr/64k)) true so it combines nodes. Program D releases its memory. Check to see if the next node is free. Yes. Checks to see if sizes are same. Yes. Then checks check_buddy. This is when it first masks off all the 0 bits. Address D is 0100 and nextnode is 0110. The first time it goes into check_buddy it passes the first if statement because 0100 (4 % 2 ==0) and 0110(6 % 2==0) so it calls check_buddy(4/2, 6/2) It fails the first case so it then checks the else. It passes this 2 % 2 = 0 and 3 % 2 = 1 so it returns one. Making the if ((next_size == node_size) && check_buddy (node_addr/64k, next_addr/64k)) true so it combines nodes. I tried it different ways and it works. The only part I need to do is the beginning to call it recursively to keep combining until all free blocks are combined correctly. I didn't;t know if you want me to post it on the iconboard or just let them figure it out themselves. Dave