You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

439 lines
10 KiB

6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
  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. #include "mm.h"
  18. #include "memlib.h"
  19. /*********************************************************
  20. * NOTE TO STUDENTS: Before you do anything else, please
  21. * provide your team information in the following struct.
  22. ********************************************************/
  23. team_t team = {
  24. /* Team name */
  25. "ateam",
  26. /* First member's full name */
  27. "Deng Bohao",
  28. /* First member's email address */
  29. "10225501432@stu.ecnu.edu.cn",
  30. /* Second member's full name (leave blank if none) */
  31. "Deng Bohao",
  32. /* Second member's email address (leave blank if none) */
  33. "10225501432@stu.ecnu.edu.cn"
  34. };
  35. /* single word (4) or double word (8) alignment */
  36. #define ALIGNMENT 8
  37. /* rounds up to the nearest multiple of ALIGNMENT */
  38. #define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7)
  39. #define SIZE_T_SIZE (ALIGN(sizeof(size_t)))
  40. /* Basic constants and macros */
  41. #define WSIZE 4 /* Word and header/footer size (bytes) */
  42. #define DSIZE 8 /* Double word size (bytes) */
  43. #define CHUNKSIZE (1<<12) /* Extend heap by this amount (bytes) */
  44. #define MAX(x, y) ((x) > (y) ? (x) : (y))
  45. /* Pack a size and allocated bit into word */
  46. #define PACK(size, alloc) ((size) | (alloc))
  47. /* Read and write a word at address p */
  48. #define GET(p) (*(unsigned int *)(p))
  49. #define PUT(p, val) (*(unsigned int *)(p) = (val))
  50. /* Read and write a pointer at address p */
  51. #define GET_PTR(p) ((unsigned int *)(long)(GET(p)))
  52. #define PUT_PTR(p, ptr) (*(unsigned int *)(p) = ((long)ptr))
  53. /* Read the size and allocated fields from address p */
  54. #define GET_SIZE(p) (GET(p) & ~0x7)
  55. #define GET_ALLOC(p) (GET(p) & 0x1)
  56. /* Given block ptr bp, compute address of its header and footer */
  57. #define HDRP(bp) ((char *)(bp) - WSIZE)
  58. #define FTRP(bp) ((char *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE)
  59. /* Given block ptr bp, compute address of next and previous blocks */
  60. #define NEXT_BLKP(bp) ((char *)(bp) + GET_SIZE(((char *)(bp) - WSIZE)))
  61. #define PREV_BLKP(bp) ((char *)(bp) - GET_SIZE(((char *)(bp) - DSIZE)))
  62. /* 每个free list中块的大小范围 */
  63. #define SIZE1 (1<<4)
  64. #define SIZE2 (1<<5)
  65. #define SIZE3 (1<<6)
  66. #define SIZE4 (1<<7)
  67. #define SIZE5 (1<<8)
  68. #define SIZE6 (1<<9)
  69. #define SIZE7 (1<<10) /* 1 KB */
  70. #define SIZE8 (1<<11)
  71. #define SIZE9 (1<<12)
  72. #define SIZE10 (1<<13)
  73. #define SIZE11 (1<<14)
  74. #define SIZE12 (1<<15)
  75. #define SIZE13 (1<<16)
  76. #define SIZE14 (1<<17)
  77. #define SIZE15 (1<<18)
  78. #define SIZE16 (1<<19)
  79. #define SIZE17 (1<<20) /* 1 MB */
  80. #define LISTS_NUM 18 /* free list 的数量 */
  81. /* Globe var */
  82. static char *heap_listp;
  83. /* 函数声明 */
  84. static void *extend_heap(size_t words);
  85. static void *coalesce(void *bp);
  86. static void *find_fit(size_t asize);
  87. static void place(void *bp, size_t asize);
  88. static void insert_list(void *bp);
  89. int getListOffset(size_t size);
  90. void delete_list(void *bp);
  91. /*
  92. * mm_init - initialize the malloc package.
  93. */
  94. int mm_init(void)
  95. {
  96. char *bp;
  97. int i;
  98. if ((heap_listp = mem_sbrk((LISTS_NUM + 4) * WSIZE)) == (void *)-1) {
  99. return -1;
  100. }
  101. PUT(heap_listp + LISTS_NUM * WSIZE, 0);
  102. PUT(heap_listp + (1 + LISTS_NUM) * WSIZE, PACK(DSIZE, 1));
  103. PUT(heap_listp + (2 + LISTS_NUM) * WSIZE, PACK(DSIZE, 1));
  104. PUT(heap_listp + (3 + LISTS_NUM) * WSIZE, PACK(0, 1));
  105. for (i = 0; i < LISTS_NUM; i++) {
  106. PUT_PTR(heap_listp + WSIZE * i, NULL);
  107. }
  108. /* Extend the empty heap with a free block of CHUNKSIZE bytes */
  109. if ((bp = extend_heap(CHUNKSIZE / WSIZE)) == NULL) {
  110. return -1;
  111. }
  112. return 0;
  113. }
  114. /*
  115. * heap的大小
  116. */
  117. void *extend_heap(size_t words)
  118. {
  119. char *bp;
  120. size_t size;
  121. /* Allocate an even number of words to maintain alignment */
  122. size = (words % 2) ? ((words + 1) * WSIZE) : (words * WSIZE);
  123. if ((long)(bp = mem_sbrk(size)) == -1) {
  124. return NULL;
  125. }
  126. /* Initialize free block header/footer and the epilogue header */
  127. PUT(HDRP(bp), PACK(size, 0)); /* Free block header */
  128. PUT(FTRP(bp), PACK(size, 0)); /* Free block footer */
  129. PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* New epilogue header */
  130. /* Coalesce if the previous block was free */
  131. return coalesce(bp);
  132. }
  133. /*
  134. * free block
  135. */
  136. void *coalesce(void *bp)
  137. {
  138. size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp)));
  139. size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
  140. size_t size = GET_SIZE(HDRP(bp));
  141. if (prev_alloc && next_alloc) { /* 前后都分配了 */
  142. bp = bp;
  143. } else if (prev_alloc && !next_alloc) { /* 前分配, 后未分配 */
  144. delete_list(NEXT_BLKP(bp));
  145. size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
  146. PUT(HDRP(bp), PACK(size, 0));
  147. PUT(FTRP(bp), PACK(size, 0));
  148. } else if (!prev_alloc && next_alloc) { /* 前未分配, 后分配 */
  149. delete_list(PREV_BLKP(bp));
  150. size += GET_SIZE(HDRP(PREV_BLKP(bp)));
  151. PUT(FTRP(bp), PACK(size, 0));
  152. PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
  153. bp = PREV_BLKP(bp);
  154. } else { /* 前后都未分配 */
  155. delete_list(NEXT_BLKP(bp));
  156. delete_list(PREV_BLKP(bp));
  157. size = size + GET_SIZE(HDRP(PREV_BLKP(bp))) +
  158. GET_SIZE(HDRP(NEXT_BLKP(bp)));
  159. PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
  160. PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
  161. bp = PREV_BLKP(bp);
  162. }
  163. insert_list(bp);
  164. return bp;
  165. }
  166. /*
  167. * mm_malloc - Allocate a block by searching the free list.
  168. * Always allocate a block whose size is a multiple of the alignment.
  169. */
  170. void *mm_malloc(size_t size)
  171. {
  172. size_t asize; /* Adjusted block size */
  173. size_t extendsize; /* Amount to extend heap if no fit */
  174. char *bp;
  175. /* Igore spurious requests */
  176. if (0 == size) {
  177. return NULL;
  178. }
  179. /* Adjusted block size to include overhead and alignment reqs */
  180. if (size <= DSIZE) {
  181. asize = 2 * DSIZE;
  182. } else {
  183. asize = DSIZE * ((size + (DSIZE) + (DSIZE - 1)) / DSIZE);
  184. }
  185. /* Search the free list for a fit */
  186. if ((bp = find_fit(asize)) != NULL) {
  187. place(bp, asize);
  188. return bp;
  189. }
  190. /* No fit found. Get more memory and place the block */
  191. extendsize = MAX(asize, CHUNKSIZE);
  192. if ((bp = extend_heap(extendsize / WSIZE)) == NULL) {
  193. return NULL;
  194. }
  195. place(bp, asize);
  196. return bp;
  197. }
  198. /*
  199. * getListOffset - size的块应该在哪个list中
  200. */
  201. int getListOffset(size_t size)
  202. {
  203. if (size <= SIZE1) {
  204. return 0;
  205. } else if (size <= SIZE2) {
  206. return 1;
  207. } else if (size <= SIZE3) {
  208. return 2;
  209. } else if (size <= SIZE4) {
  210. return 3;
  211. } else if (size <= SIZE5) {
  212. return 4;
  213. } else if (size <= SIZE6) {
  214. return 5;
  215. } else if (size <= SIZE7) {
  216. return 6;
  217. } else if (size <= SIZE8) {
  218. return 7;
  219. } else if (size <= SIZE9) {
  220. return 8;
  221. } else if (size <= SIZE10) {
  222. return 9;
  223. } else if (size <= SIZE11) {
  224. return 10;
  225. } else if (size <= SIZE12) {
  226. return 11;
  227. } else if (size <= SIZE13) {
  228. return 12;
  229. } else if (size <= SIZE14) {
  230. return 13;
  231. } else if (size <= SIZE15) {
  232. return 14;
  233. } else if (size <= SIZE16) {
  234. return 15;
  235. } else if (size <= SIZE17) {
  236. return 16;
  237. } else {
  238. return 17;
  239. }
  240. }
  241. /*
  242. * insert_list - free block插入到相应大小的free list中,
  243. */
  244. void insert_list(void *bp)
  245. {
  246. int index;
  247. size_t size;
  248. size = GET_SIZE(HDRP(bp));
  249. index = getListOffset(size);
  250. if (GET_PTR(heap_listp + WSIZE * index) == NULL) {
  251. PUT_PTR(heap_listp + WSIZE * index, bp);
  252. PUT_PTR(bp, NULL);
  253. PUT_PTR((unsigned int *)bp + 1, NULL);
  254. } else {
  255. PUT_PTR(bp, GET_PTR(heap_listp + WSIZE * index));
  256. PUT_PTR(GET_PTR(heap_listp + WSIZE * index) + 1, bp); /* 修改前一个位置 */
  257. PUT_PTR((unsigned int *)bp + 1, NULL);
  258. PUT_PTR(heap_listp + WSIZE * index, bp);
  259. }
  260. }
  261. /*
  262. * delete_list -
  263. */
  264. void delete_list(void *bp)
  265. {
  266. int index;
  267. size_t size;
  268. size = GET_SIZE(HDRP(bp));
  269. index = getListOffset(size);
  270. if (GET_PTR(bp) == NULL && GET_PTR((unsigned int *)bp + 1) == NULL) {
  271. /* 链表中唯一结点 */
  272. PUT_PTR(heap_listp + WSIZE * index, NULL);
  273. } else if (GET_PTR(bp) == NULL && GET_PTR((unsigned int *)bp + 1) != NULL) {
  274. /* 链表中最后一个结点, 不是唯一一个 */
  275. PUT_PTR(GET_PTR((unsigned int *)bp + 1), NULL);
  276. } else if (GET_PTR(bp) != NULL && GET_PTR((unsigned int *)bp + 1) == NULL){
  277. /* 链表中第一个结点, 不是唯一一个 */
  278. PUT_PTR(heap_listp + WSIZE * index, GET_PTR(bp));
  279. PUT_PTR(GET_PTR(bp) + 1, NULL);
  280. } else if (GET_PTR(bp) != NULL && GET_PTR((unsigned int *)bp + 1) != NULL) {
  281. /* 链表中的中间结点 */
  282. PUT_PTR(GET_PTR((unsigned int *)bp + 1), GET_PTR(bp));
  283. PUT_PTR(GET_PTR(bp) + 1, GET_PTR((unsigned int*)bp + 1));
  284. }
  285. }
  286. /*
  287. * find_fit - Search the free list for a fit
  288. */
  289. void *find_fit(size_t asize)
  290. {
  291. int index;
  292. index = getListOffset(asize);
  293. unsigned int *ptr;
  294. /* 小的class内找不到就到大的class内找 */
  295. while (index < 18) {
  296. ptr = GET_PTR(heap_listp + 4 * index);
  297. while (ptr != NULL) {
  298. if (GET_SIZE(HDRP(ptr)) >= asize) {
  299. return (void *)ptr;
  300. }
  301. ptr = GET_PTR(ptr);
  302. }
  303. index++;
  304. }
  305. return NULL;
  306. }
  307. /*
  308. * place - place the requested block at the beginning of the free block
  309. */
  310. void place(void *bp, size_t asize)
  311. {
  312. size_t csize = GET_SIZE(HDRP(bp));
  313. delete_list(bp);
  314. if ((csize - asize) >= (2 * DSIZE)) {
  315. PUT(HDRP(bp), PACK(asize, 1));
  316. PUT(FTRP(bp), PACK(asize, 1));
  317. bp = NEXT_BLKP(bp);
  318. PUT(HDRP(bp), PACK(csize - asize, 0));
  319. PUT(FTRP(bp), PACK(csize - asize, 0));
  320. insert_list(bp);
  321. } else {
  322. PUT(HDRP(bp), PACK(csize, 1));
  323. PUT(FTRP(bp), PACK(csize, 1));
  324. }
  325. }
  326. /*
  327. * mm_free - Freeing a block.
  328. */
  329. void mm_free(void *ptr)
  330. {
  331. size_t size = GET_SIZE(HDRP(ptr));
  332. PUT(HDRP(ptr), PACK(size, 0));
  333. PUT(FTRP(ptr), PACK(size, 0));
  334. coalesce(ptr);
  335. }
  336. /*
  337. * mm_realloc - malloc和free组合实现
  338. */
  339. void *mm_realloc(void *ptr, size_t size)
  340. {
  341. size_t asize;
  342. void *oldptr = ptr;
  343. void *newptr;
  344. /* free */
  345. if (0 == size) {
  346. free(oldptr);
  347. return NULL;
  348. }
  349. if (size <= DSIZE) {
  350. asize = 2 * DSIZE;
  351. } else {
  352. asize = DSIZE * ((size + (DSIZE) + (DSIZE - 1)) / DSIZE);
  353. }
  354. if (asize == GET_SIZE(HDRP(oldptr))) {
  355. return oldptr;
  356. }
  357. /* 缩小空间 */
  358. if (asize < GET_SIZE(HDRP(oldptr))) {
  359. newptr = mm_malloc(size);
  360. memmove(newptr, oldptr, size);
  361. mm_free(oldptr);
  362. return newptr;
  363. }
  364. newptr = mm_malloc(size);
  365. if (NULL == newptr)
  366. return NULL;
  367. memmove(newptr, oldptr, size);
  368. mm_free(oldptr);
  369. return newptr;
  370. }