Discussions on hw7 Memory Allocation Exercise 3 functions: void initalloc(void); char * alloc(int n); void freef(char *p); You are asked to write the freef() function The alloctest.c program is provided to test the functions It teaches you how to write malloc and free Explain about malloc and free again Initalloc -> allocates the buffer for our job -> simulate malloc and free on it Alloc -> similar to malloc Freef -> similar to free. You should wright the freef function -> return the used space to our initial buffer If your program works well, the output should be same as mine
initalloc function Initializes a large free buffer struct blockl{ unsigned int tag:8; unsigned int size :24; struct blockl *nextp; struct blockl *prevp;}; Blockrp = allocbuf + ALLOCSIZE -TAGSIZE Cursorp = freep = allocbuf F TAGSIZE allocbuf ALLOCSIZE Struct blockr{ unsigned int tag:8; unsigned int size:24;}; Bit fields Size = allocsize -> fixed size You should do all the computations in char * domain and not the struct doman. For example if curorp is a pointer to a structure, first I should cast it to char * pointer, then I can do calculation by doing subtraction TAGSIZE = sizeof(blockr) MINFREESIZE= sizeof(blockl) + sizeof(blockr) USEDTAG = 0xaa FREETAG = 0x55
Function alloc(n) Allocate a buffer of allocsize = n (in multiple of 4 ) + 2*TAGSIZE bytes from the free buffer pool The tags for both ends of the allocated buffer are of type struct blockr. They are not kept using a linked list (no need for the char * elements) Function returns a pointer = holdp + TAGSIZE Linux in its free time does search in your memory and creates a free list (linked list) of all the free spaces in the memory. So when you ask for malloc it finds from the free list. So we don’t need to keep track of used blocks holdp pointer returned by alloc U U n bytes in multiple of 4 TAGSIZE TAGSIZE
Allocation Algorithm I) cursorp->size < allocsize=4*((n-1)/4 +1) +2*TAGSIZE return null if all free blocks are not big enough II) cursor->size > allocsize + MINFREESIZE return pointer =holdp + TAGSIZE p=cursorp=holdp blockrp = p +holdp->size -TAGSIZE U allocsize U The size of free block has been changed blockrp =p + allocsize-TAGSIZE cursorp allocsize F U new free size holdp = p blockrp = p-TAGSIZE
Enchaining Free Buffers Allocated buffers are not chained An example of chaining 4 free buffers Most recent freep cursorp Least recent BUF 4 BUF 3 BUF 2 BUF 1 nextp =3 prevp =1 nextp =2 nextp =1 nextp =4 prevp =4 prevp =3 prevp =2
Unchaining free buffers Most recent Least recent BUF 4 BUF 3 BUF 2 BUF 1 nextp =3 prevp =1 nextp =2 nextp =1 nextp =4 prevp =4 prevp =3 prevp =2 freep cursorp BUF 4 BUF 2 BUF 1 nextp =2 prevp =1 nextp =1 nextp =4 prevp =4 prevp =2
Multiple cases of freef Left block is not free Case 1: Left block is free freef -> chnge0xaa to 0x55 and add to pointers If 2 free blocks are adjacent to each other, I should make a big free block so use the coalesce function To check you are in which case: check the tag of the left block. Use the pointer and cast it to struct * and see the tag Char * p Ptr = P – sizeof(struct blockr) – sizeof(struct blockl) (struct blockr *) ptr -> tag F F U U F F Case 3: Both left and right blocks are free
Pseudocode for freef(char *p) p is the same pointer obtained from alloc() Change tag to FREETAG on blockl Change tag to FREETAG on blockr No need to update size on blockl and blockr because alloc() sets the sizes correctly Check if block on left is also free? case 1: yes, coalesce free block on left and p case 2: no, enchain buffer Check if block on right is also free? case 3: yes, unchain the block on right and coalesce p with block on right. return