Files
sispro3/mm_v2.c
2025-01-08 02:25:09 +01:00

169 lines
5.1 KiB
C
Executable File

/*
* mm-naive.c - The fastest, least memory-efficient malloc package.
*
* In this naive approach, a block is allocated by simply incrementing
* the brk pointer. A block is pure payload. There are no headers or
* footers. Blocks are never coalesced or reused. Realloc is
* implemented directly using mm_malloc and mm_free.
*
* NOTE TO STUDENTS: Replace this header comment with your own header
* comment that gives a high level description of your solution.
*/
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include "mm.h"
#include "memlib.h"
team_t team = {
/* Team name */
"MA",
/* First member's full name */
"Marvin Aleksa",
/* First member's email address */
"marvin.aleksa@stud.uni-due.de",
/* Second member's full name (leave blank if none) */
"",
/* Second member's email address (leave blank if none) */
""
};
typedef uint16_t t2; // 2 byte wide unsigned data type
typedef uint32_t t4; // 4 byte wide unsigned data type
typedef uint64_t t8; // 8 byte wide unsigned data type
typedef struct {
uint32_t len;
uint32_t plen;
} Header;
/* single word (4) or double word (8) alignment */
#define AL 8 // word length to align to
#define HH 2048 // heap increase increment
/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(size) (((size) + (AL-1)) & ~0x7)
#define ALIGN_ADDR(addr) (void *)ALIGN((int)addr)
#define SIZE_T_SIZE (ALIGN(sizeof(t8)))
#define SET_ALL0(x) ((x) & ~1)
#define SET_ALL1(x) ((x) | 1)
#define GET_LENG(x) ((x) & ~1)
#define GET_ALLC(x) ((x) & 1)
void *heap = NULL;
void *curs = NULL;
/* mm_init - initialize the malloc package. */
int mm_init(void) {
printf("\n");
heap = mem_sbrk( HH );
if (heap == (void *)-1) {
return -1;
}
curs = heap;
printf("init -> first heap addr %p (%p)\n", mem_heap_lo(), ALIGN_ADDR(mem_heap_lo()));
// printf("init -> first heap addr %p\n", heap);
printf("init -> heap cursor at %p\n", curs);
printf("init -> heap size %i\n", mem_heapsize());
printf("init -> final heap addr %p\n", mem_heap_hi());
printf("\n");
return 0;
}
/* mm_malloc - Allocate a block by incrementing the brk pointer. Always allocate a block whose size is a multiple of the alignment. */
void *mm_malloc(size_t size) {
int nbs = ALIGN(size); //new block size
printf("malloc -> %i requested, aligned to %i\n", size, nbs);
nbs += 2 * sizeof( t8 );
printf("malloc -> extended to %i for overhead\n", nbs);
if( ( nbs ) <= ( mem_heap_hi() - curs ) ){
printf("malloc -> %i requested, %i available\n", nbs, ( mem_heap_hi() - curs ));
printf("malloc -> heap size %i\n", mem_heapsize());
} else {
printf("malloc -> %i requested, %i available, allocating extra %i bytes\n", nbs, ( mem_heap_hi() - curs ), HH);
printf("malloc -> new heap size %i\n", mem_heapsize());
heap = mem_sbrk( HH );
}
curs = curs + sizeof(t8) + size;
printf("\n");
return curs;
// int newsize = ALIGN(size + SIZE_T_SIZE);
// void *p = mem_sbrk(newsize);
// if (p == (void *)-1)
// return NULL;
// else {
// *(size_t *)p = size;
// return (void *)((char *)p + SIZE_T_SIZE);
// }
}
/* mm_free - Freeing a block does nothing. */
void mm_free(void *ptr) {
if (ptr == NULL) {
return;
}
// Adjust pointer to get the header of the block
t8 *block_header = (t8 *)ptr - 1;
// Mark the block as free
*block_header = SET_ALL0(*block_header);
// Get the footer for the block
size_t block_size = GET_LENG(*block_header);
t8 *block_footer = (t8 *)((char *)block_header + block_size - sizeof(t8));
*block_footer = *block_header;
// Try coalescing with previous block if it's free
t8 *prev_footer = (t8 *)((char *)block_header - sizeof(t8));
if (prev_footer >= (t8 *)mem_heap_lo() && !GET_ALLC(*prev_footer)) {
size_t prev_size = GET_LENG(*prev_footer);
t8 *prev_header = (t8 *)((char *)block_header - prev_size);
size_t new_size = prev_size + block_size;
*prev_header = SET_ALL0(new_size);
*block_footer = *prev_header;
block_header = prev_header;
block_size = new_size;
}
// Try coalescing with next block if it's free
t8 *next_header = (t8 *)((char *)block_header + block_size);
if (next_header < (t8 *)mem_heap_hi() && !GET_ALLC(*next_header)) {
size_t next_size = GET_LENG(*next_header);
t8 *next_footer = (t8 *)((char *)next_header + next_size - sizeof(t8));
size_t new_size = block_size + next_size;
*block_header = SET_ALL0(new_size);
*next_footer = *block_header;
}
}
/* mm_realloc - Implemented simply in terms of mm_malloc and mm_free */
void *mm_realloc(void *ptr, size_t size) {
void *oldptr = ptr;
void *newptr;
size_t copySize;
newptr = mm_malloc(size);
if (newptr == NULL)
return NULL;
copySize = *(size_t *)((char *)oldptr - SIZE_T_SIZE);
if (size < copySize)
copySize = size;
memcpy(newptr, oldptr, copySize);
mm_free(oldptr);
return newptr;
}