Advertisement
Guest User

Untitled

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