Advertisement
Guest User

Untitled

a guest
Feb 7th, 2016
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.68 KB | None | 0 0
  1. /*
  2. * mm-naive.c - The fastest, least memory-efficient malloc package.
  3. *
  4. * In this naive approach, a block is allocated by simply incrementing
  5. * the brk pointer. A block is pure payload. There are no headers or
  6. * footers. Blocks are never coalesced or reused. Realloc is
  7. * implemented directly using mm_malloc and mm_free.
  8. *
  9. * NOTE TO STUDENTS: Replace this header comment with your own header
  10. * comment that gives a high level description of your solution.
  11. */
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <assert.h>
  15. #include <unistd.h>
  16. #include <string.h>
  17.  
  18. #include "mm.h"
  19. #include "memlib.h"
  20.  
  21. /*********************************************************
  22. * NOTE TO STUDENTS: Before you do anything else, please
  23. * provide your team information in the following struct.
  24. ********************************************************/
  25. team_t team = {
  26. /* Team name */
  27. "Foo and the Bars",
  28. /* First member's full name */
  29. "Winston Xu",
  30. /* First member's email address */
  31. /* Second member's full name (leave blank if none) */
  32. "David Bai",
  33. /* Second member's email address (leave blank if none) */
  34. };
  35.  
  36. /* single word (4) or double word (8) alignment */
  37. #define ALIGNMENT 8
  38.  
  39. /* rounds up to the nearest multiple of ALIGNMENT */
  40. #define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7)
  41.  
  42.  
  43. #define SIZE_T_SIZE (ALIGN(sizeof(size_t)))
  44. //everything below, up to realloc, is pretty much straight from the book (~pg 855, section 9.9.12)
  45. //I understand the concepts/psuedocode, but haven't examined the actual details
  46. //super carefully yet - still, I feel pretty good about what is below. Though maybe I shouldn't...
  47. #define WSIZE 4 //word size may be different, thus d size as well
  48. #define DSIZE 8
  49. #define CHUNKSIZE (1<<12)
  50.  
  51. #define MAX(x,y) ( (x) > (y) ? (x) : (y) )
  52.  
  53. #define PACK(size, alloc) ((size) | (alloc))
  54.  
  55. #define GET(p) (*(unsigned int *)(p)) //gives bits at pointer p interpreted as an unsigned int
  56. #define PUT(p, val) (*(unsigned int *)(p) = (val))
  57.  
  58. #define GET_SIZE(p) (GET(p) & ~0x7) //functionally ignore last 3 bits (assign them all 0)
  59. #define GET_ALLOC(p) (GET(p) & 0x1) //only look at last bit (0 or 1 depending on allocation bit)
  60.  
  61. #define HDRP(bp) ((char *)(bp) - WSIZE) //just 1 byte so math doesn't need to divide/multiply
  62. #define FTRP(bp) ((char *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE)
  63.  
  64. #define NEXT_BLKP(bp) ( (char *)(bp) + GET_SIZE( ((char *)(bp) - WSIZE) ) )
  65. #define PREV_BLKP(bp) ( (char *)(bp) - GET_SIZE( ((char *)(bp) - DSIZE) ) )
  66.  
  67. /*
  68. *Tries to free up space by combining adjacent free blocks
  69. */
  70. static void *coalesce(void *bp)
  71. {
  72. size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp)));
  73. size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
  74. size_t size = GET_SIZE(HDRP(bp));
  75. //printf("Entered coalesce\n");
  76. //printf("Previous block size %d\n", GET_SIZE(PREV_BLKP(bp)));
  77. //printf("Next Block size %d\n", GET_SIZE(NEXT_BLKP(bp)));
  78. // fflush(stdout);
  79. if (prev_alloc && next_alloc) {
  80. // printf("No change\n");
  81. // fflush(stdout);
  82. return bp;
  83. }
  84. else if( prev_alloc && !next_alloc){
  85. // printf("Next is free\n");
  86. // fflush(stdout);
  87. size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
  88. PUT(HDRP(bp), PACK(size, 0));
  89. PUT(FTRP(bp), PACK(size, 0));
  90. }
  91. else if( !prev_alloc && next_alloc){
  92. // printf("Prev is free\n");
  93. // fflush(stdout);
  94. size += GET_SIZE(HDRP(PREV_BLKP(bp)));
  95. PUT(FTRP(bp), PACK(size, 0));
  96. PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
  97. bp = PREV_BLKP(bp);
  98. }
  99. else{
  100. // printf("Both prev and next are free\n");
  101. // fflush(stdout);
  102. size += GET_SIZE(HDRP(PREV_BLKP(bp)))+GET_SIZE(FTRP(NEXT_BLKP(bp)));
  103. PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
  104. PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
  105. bp = PREV_BLKP(bp);
  106. }
  107. return bp;
  108. }
  109.  
  110. //helper function which puts the right header and footer values in the new allocated block
  111. static void place(char *blockpointer, size_t size)
  112. {
  113. int remaining_space = GET_SIZE(HDRP(blockpointer)) - size;
  114. PUT( HDRP(blockpointer), PACK(size, 1) );
  115. PUT( FTRP(blockpointer), PACK(size, 1) );
  116. PUT( HDRP(NEXT_BLKP(blockpointer)), PACK(remaining_space, 0));
  117. PUT( FTRP(NEXT_BLKP(blockpointer)), PACK(remaining_space, 0));
  118. }
  119.  
  120. /*
  121. *How malloc finds the next free block
  122. *Uses next fit for now, starts at beginning of list and iterates through
  123. */
  124. /*static*/ char *find_fit(size_t size)
  125. {
  126. //starting at first free block, which can be a global var
  127. //last free block's 'next' pointer should point to null
  128. // printf("Enter find_fit\n");
  129. // fflush(stdout);
  130. char *freeBlockP = (char *)(mem_heap_lo() + 4*WSIZE);
  131. printf("Looking for free block. Free? %s Size %d\n",
  132. GET_ALLOC(HDRP(freeBlockP)) ? "No" : "Yes", GET_SIZE(HDRP(freeBlockP)));
  133. fflush(stdout);
  134. while(GET_ALLOC(HDRP(freeBlockP)) == 1 || GET_SIZE(HDRP(freeBlockP)) < size)
  135. {
  136. printf("Looking for free block in loop. Free? %s Size %d\n",
  137. GET_ALLOC(HDRP(freeBlockP)) ? "No" : "Yes", GET_SIZE(HDRP(freeBlockP)));
  138. fflush(stdout);
  139. sleep(1);
  140. //go through free block
  141. //update freeblockP
  142. freeBlockP = NEXT_BLKP(freeBlockP);
  143. }
  144. if(GET_SIZE(HDRP(freeBlockP)) < size)
  145. {
  146. return NULL;
  147. }
  148. return freeBlockP;
  149. }
  150.  
  151. /*
  152. *Tells heap that more memory is being allocated-if possible
  153. */
  154. static void *extend_heap(size_t words)
  155. {
  156. char *bp;
  157. size_t size;
  158. //allocate even number of words to maintain alignment
  159. size = (words % 2) ? (words+1) * WSIZE: words * WSIZE;
  160. if( (long)(bp = mem_sbrk(size)) == -1) { //couldn't get move brk correctly
  161. printf("Current heap not big enough\n");
  162. fflush(stdout);
  163. return NULL;
  164. }
  165. // printf("MM init heap 1 is %d\n", *bp);
  166. // printf("MM init heap 2 is %d\n", *(bp+WSIZE));
  167. // printf("MM init heap 3 is %d\n", *(bp+DSIZE));
  168. // printf("MM init heap 4 is %d\n", *(bp+3*WSIZE));
  169. //initialize the free block's header and its footer, also the new epilogue header
  170. PUT( HDRP(bp), PACK(size, 0) );
  171. // printf("Extend heap header is %d\n", *HDRP(bp));
  172. // fflush(stdout);
  173. PUT( FTRP(bp), PACK(size, 0) );
  174. PUT( HDRP(NEXT_BLKP(bp)), PACK(0, 1) );
  175. //coalesce if previous block was free
  176. return coalesce(bp);
  177. }
  178.  
  179. /*
  180. *Goes through heap to make sure it is as planned
  181. */
  182. static int mm_check()
  183. {
  184. int return_value = 0;
  185. //do checks
  186. //return value = 1 if any errors
  187. char *freeBlockP = (char *)(mem_heap_lo() + 4*WSIZE);
  188. printf("First check: Free? %s Size %d\n",
  189. GET_ALLOC(HDRP(freeBlockP)) ? "No" : "Yes", GET_SIZE(HDRP(freeBlockP)));
  190. fflush(stdout);
  191. while(GET_ALLOC(HDRP(freeBlockP)) == 1)
  192. {
  193. // printf("Free? %s Size %d\n",
  194. // GET_ALLOC(HDRP(freeBlockP)) ? "No" : "Yes", GET_SIZE(HDRP(freeBlockP)));
  195. sleep(1);
  196. //go through free block
  197. //update freeblockP
  198. freeBlockP = NEXT_BLKP(freeBlockP);
  199. printf("Shifted Free? %s Size %d\n",
  200. GET_ALLOC(HDRP(freeBlockP)) ? "No" : "Yes", GET_SIZE(HDRP(freeBlockP)));
  201. fflush(stdout);
  202. }
  203.  
  204. return return_value; //if no errors caught by the end, return 0
  205. }
  206. /*********************************************************
  207. * End of Helper Functions
  208. ********************************************************/
  209. /*
  210. * mm_init - initialize the malloc package.
  211. */
  212. int mm_init() //void means no params; just to keep certain versions of c happy
  213. {
  214. mem_init();
  215. char *heap_listp;
  216. if ( (heap_listp = mem_sbrk(4*WSIZE)) == (void *)-1 ){
  217. return -1;
  218. }
  219. PUT(heap_listp, 0);
  220. PUT(heap_listp + (1*WSIZE), PACK(DSIZE, 1));
  221. PUT(heap_listp + (2*WSIZE), PACK(DSIZE, 1));
  222. PUT(heap_listp + (3*WSIZE), PACK(0, 1));
  223. heap_listp += (2*WSIZE); //probably unnecessary
  224. //extend the empty heap with a free block of CHUNKSIZE bytes...2^12 (arbitrary?? It's 4kb, aka possible size of page)
  225. if (extend_heap(CHUNKSIZE/WSIZE) == NULL){ //if couldn't extend heap
  226. return -1;
  227. }
  228.  
  229. return 0; //if no errors caught by the end, return
  230. }
  231.  
  232. /*
  233. * mm_malloc - Allocate a block by incrementing the brk pointer.
  234. * Always allocate a block whose size is a multiple of the alignment.
  235. */
  236. void *mm_malloc(size_t size)
  237. {
  238. // printf("Before malloc\n");
  239. // fflush(stdout);
  240. // mm_check();
  241. size_t asize;
  242. size_t extendsize;
  243. char *bp;
  244. //printf("--NEW alloc--\n");
  245. //fflush(stdout);
  246. if (size == 0){ //strange case to ignore
  247. // printf("Not allocating anything!");
  248. // printf("After malloc\n");
  249. // fflush(stdout);
  250. // mm_check();
  251. return NULL;
  252. }
  253.  
  254. //change requested block size to fit header/footer, and align
  255. if(size <= DSIZE){
  256. asize = 2*DSIZE; //AKA 2 double words (for alignment, must be some # of double words)
  257. //1 double word for headers/footers, at least 1 for data
  258. }
  259. else{
  260. asize = DSIZE * ( ( size + (DSIZE) + (DSIZE-1) ) / DSIZE);
  261. //
  262. //take size, add 15 bytes, divide by 8
  263. // if size % 8 = 0, asize is size + 1 (1 for hdr/ftr)
  264. // if size % 8 = 1 - 7, asize is size + 2 (1 for some padding, 1 for hdr/ftr)
  265. }
  266. printf("Old size %d New Size %d\n", size, asize);
  267. fflush(stdout);
  268.  
  269. //look for fit in the free list
  270. //Finds first open spot? not enough space for a header
  271. if( (bp = find_fit(asize)) != NULL){ //
  272. place(bp, asize);
  273. // printf("There was still space\n");
  274. // fflush(stdout);
  275. // printf("After malloc\n");
  276. // fflush(stdout);
  277. // mm_check();
  278. return bp;
  279. }
  280. //reached here if no such fit...get more memory
  281. extendsize = MAX(asize, CHUNKSIZE);
  282. if( (bp = extend_heap(extendsize/WSIZE)) == NULL){
  283. printf("\tOut of memory for heap!\n");
  284. fflush(stdout);
  285. // printf("After malloc\n");
  286. // fflush(stdout);
  287. // mm_check();
  288. return NULL;
  289. }
  290. printf("\tAdding stuff of size %d\n", asize);
  291. fflush(stdout);
  292. place(bp, asize);
  293. //Reset epilogue
  294. PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1));
  295. // printf("After malloc\n");
  296. // fflush(stdout);
  297. // mm_check();
  298. return bp;
  299. }
  300. /*
  301. * mm_free - Freeing a block does nothing.
  302. */
  303. void mm_free(void *ptr)
  304. {
  305. size_t size = GET_SIZE(HDRP(ptr));
  306. PUT( HDRP(ptr), PACK(size, 0) );
  307. PUT( FTRP(ptr), PACK(size, 0) );
  308. coalesce(ptr);
  309. }
  310.  
  311. /*
  312. * mm_realloc - Implemented simply in terms of mm_malloc and mm_free
  313. */
  314. void *mm_realloc(void *ptr, size_t size)
  315. {
  316. //check for free blocks to the left, see if it's big enough
  317. //if big enough, just move footer and adjust values in header/footer of current block and free block
  318. void *oldptr = ptr;
  319. void *newptr;
  320. size_t copySize;
  321.  
  322. newptr = mm_malloc(size);
  323. if (newptr == NULL){
  324. return NULL;
  325. }
  326. copySize = *(size_t *)((char *)oldptr - SIZE_T_SIZE);
  327. if (size < copySize){
  328. copySize = size;
  329. }
  330. memcpy(newptr, oldptr, copySize);
  331. mm_free(oldptr);
  332. return newptr;
  333. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement