Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
cs24-21fa
project04
Commits
6c942fb0
Commit
6c942fb0
authored
4 years ago
by
Caleb C. Sander
Browse files
Options
Download
Email Patches
Plain Diff
Clean up starter code
parent
e6a41d57
master
No related merge requests found
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
Makefile
+3
-3
Makefile
include/memlib.h
+1
-0
include/memlib.h
include/mm.h
+7
-7
include/mm.h
src/mm-explicit.c
+86
-48
src/mm-explicit.c
src/mm-implicit.c
+86
-48
src/mm-implicit.c
with
183 additions
and
106 deletions
+183
-106
Makefile
View file @
6c942fb0
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
# Makefile for the malloc lab driver
# Makefile for the malloc lab driver
#
#
CC
=
clang
CC
=
clang
CFLAGS
=
-Werror
-Wall
-Wextra
-O3
-g
-DDRIVER
CFLAGS
=
-Werror
-Wall
-Wextra
-O3
-g
all
:
bin/mdriver-implicit bin/mdriver-explicit
all
:
bin/mdriver-implicit bin/mdriver-explicit
...
@@ -15,7 +15,7 @@ bin/mdriver-explicit: out/mdriver-explicit.o out/mm-explicit.o out/memlib.o out/
...
@@ -15,7 +15,7 @@ bin/mdriver-explicit: out/mdriver-explicit.o out/mm-explicit.o out/memlib.o out/
out/mdriver-implicit.o
:
driver/mdriver.c
out/mdriver-implicit.o
:
driver/mdriver.c
$(CC)
$(CFLAGS)
-c
-DSTAGE0
$^
-o
$@
$(CC)
$(CFLAGS)
-c
-DSTAGE0
$^
-o
$@
out/mdriver-explicit.o
:
driver/mdriver.c
out/mdriver-explicit.o
:
driver/mdriver.c
$(CC)
$(CFLAGS)
-c
-DSTAGE1
$^
-o
$@
$(CC)
$(CFLAGS)
-c
-DSTAGE1
$^
-o
$@
out/%.o
:
src/%.c
out/%.o
:
src/%.c
...
@@ -25,4 +25,4 @@ out/%.o: driver/%.c
...
@@ -25,4 +25,4 @@ out/%.o: driver/%.c
$(CC)
$(CFLAGS)
-c
$^
-o
$@
$(CC)
$(CFLAGS)
-c
$^
-o
$@
clean
:
clean
:
rm
-f
*
~
out/
*
.o
bin/
*
rm
-f
out/
*
bin/
*
This diff is collapsed.
Click to expand it.
include/memlib.h
View file @
6c942fb0
#include <stddef.h>
#include <stddef.h>
#include <sys/types.h>
void
mem_init
(
void
);
void
mem_init
(
void
);
void
mem_deinit
(
void
);
void
mem_deinit
(
void
);
...
...
This diff is collapsed.
Click to expand it.
include/mm.h
View file @
6c942fb0
#ifndef MM_H
#ifndef MM_H
#define MM_H
#define MM_H
#include <stdio.h>
#include <stdbool.h>
#include <stdbool.h>
#include <stddef.h>
extern
bool
mm_init
(
void
);
bool
mm_init
(
void
);
extern
void
*
mm_malloc
(
size_t
size
);
void
*
mm_malloc
(
size_t
size
);
extern
void
mm_free
(
void
*
ptr
);
void
mm_free
(
void
*
ptr
);
extern
void
*
mm_realloc
(
void
*
ptr
,
size_t
size
);
void
*
mm_realloc
(
void
*
ptr
,
size_t
size
);
extern
void
*
mm_calloc
(
size_t
nmemb
,
size_t
size
);
void
*
mm_calloc
(
size_t
nmemb
,
size_t
size
);
extern
void
mm_checkheap
();
void
mm_checkheap
(
void
);
#endif
/* MM_H */
#endif
/* MM_H */
This diff is collapsed.
Click to expand it.
src/mm-explicit.c
View file @
6c942fb0
...
@@ -4,120 +4,158 @@
...
@@ -4,120 +4,158 @@
* TODO (bug): Uh..this is an implicit list???
* TODO (bug): Uh..this is an implicit list???
*/
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdint.h>
#include <stddef.h>
#include <unistd.h>
#include "mm.h"
#include "mm.h"
#include "memlib.h"
#include "memlib.h"
typedef
uint64_t
word_t
;
/** The required alignment of heap payloads */
const
size_t
ALIGNMENT
=
2
*
sizeof
(
word
_t
);
const
size_t
ALIGNMENT
=
2
*
sizeof
(
size
_t
);
/** The layout of each block allocated on the heap */
typedef
struct
{
typedef
struct
{
/** The size of the block and whether it is allocated (stored in the low bit) */
size_t
header
;
size_t
header
;
/*
/*
*
* We don't know what the size of the payload will be, so we will
* We don't know what the size of the payload will be, so we will
* declare it as a zero-length array. This allow us to obtain a
* declare it as a zero-length array. This allow us to obtain a
* pointer to the start of the payload.
* pointer to the start of the payload.
*/
*/
word
_t
payload
[];
uint8
_t
payload
[];
}
block_t
;
}
block_t
;
/** The first and last blocks on the heap */
static
block_t
*
mm_heap_first
=
NULL
;
static
block_t
*
mm_heap_first
=
NULL
;
static
block_t
*
mm_heap_last
=
NULL
;
static
block_t
*
mm_heap_last
=
NULL
;
/** Rounds up `size` to the nearest multiple of `n` */
static
size_t
round_up
(
size_t
size
,
size_t
n
)
{
static
size_t
round_up
(
size_t
size
,
size_t
n
)
{
return
n
*
((
size
+
(
n
-
1
))
/
n
);
return
(
size
+
(
n
-
1
))
/
n
*
n
;
}
static
size_t
get_size
(
block_t
*
block
)
{
return
block
->
header
&
~
0x7
;
}
}
/** Set's a block's header with the given size and allocation state */
static
void
set_header
(
block_t
*
block
,
size_t
size
,
bool
is_allocated
)
{
static
void
set_header
(
block_t
*
block
,
size_t
size
,
bool
is_allocated
)
{
block
->
header
=
size
|
is_allocated
;
block
->
header
=
size
|
is_allocated
;
}
}
/** Extracts a block's size from its header */
static
size_t
get_size
(
block_t
*
block
)
{
return
block
->
header
&
~
1
;
}
/** Extracts a block's allocation state from its header */
static
bool
is_allocated
(
block_t
*
block
)
{
static
bool
is_allocated
(
block_t
*
block
)
{
return
block
->
header
&
0x
1
;
return
block
->
header
&
1
;
}
}
block_t
*
find_fit
(
size_t
size
)
{
/**
for
(
block_t
*
curr
=
mm_heap_first
;
mm_heap_last
&&
curr
<=
mm_heap_last
;
curr
=
((
void
*
)
curr
+
get_size
(
curr
)))
{
* Finds the first free block in the heap with at least the given size.
size_t
curr_size
=
get_size
(
curr
);
* If no block is large enough, returns NULL.
if
(
!
is_allocated
(
curr
)
&&
curr_size
>=
size
)
{
*/
static
block_t
*
find_fit
(
size_t
size
)
{
// Traverse the blocks in the heap using the implicit list
for
(
block_t
*
curr
=
mm_heap_first
;
mm_heap_last
!=
NULL
&&
curr
<=
mm_heap_last
;
curr
=
(
void
*
)
curr
+
get_size
(
curr
)
)
{
// If the block is free and large enough for the allocation, return it
if
(
!
is_allocated
(
curr
)
&&
get_size
(
curr
)
>=
size
)
{
return
curr
;
return
curr
;
}
}
}
}
return
NULL
;
return
NULL
;
}
}
/** Gets the header corresponding to a given payload pointer */
static
block_t
*
block_from_payload
(
void
*
ptr
)
{
return
ptr
-
offsetof
(
block_t
,
payload
);
}
/**
* mm_init - Initializes the allocator state
*/
bool
mm_init
(
void
)
{
bool
mm_init
(
void
)
{
mm_heap_first
=
mem_sbrk
(
8
);
// We want the first payload to start at ALIGNMENT bytes from the start of the heap
set_header
(
mm_heap_first
,
8
,
true
);
void
*
padding
=
mem_sbrk
(
ALIGNMENT
-
sizeof
(
block_t
));
if
(
padding
==
(
void
*
)
-
1
)
{
return
false
;
}
// Initialize the heap with no blocks
mm_heap_first
=
NULL
;
mm_heap_last
=
NULL
;
mm_heap_last
=
NULL
;
return
true
;
return
true
;
}
}
/**
* mm_malloc - Allocates a block with the given size
*/
void
*
mm_malloc
(
size_t
size
)
{
void
*
mm_malloc
(
size_t
size
)
{
size_t
asize
=
round_up
(
size
+
sizeof
(
word_t
),
ALIGNMENT
);
// The block must have enough space for a header and be 16-byte aligned
size
=
round_up
(
sizeof
(
block_t
)
+
size
,
ALIGNMENT
);
// If there is a large enough free block, use it
block_t
*
block
=
find_fit
(
size
);
if
(
block
!=
NULL
)
{
set_header
(
block
,
get_size
(
block
),
true
);
return
block
->
payload
;
}
block_t
*
block
=
find_fit
(
asize
);
// Otherwise, a new block needs to be allocated at the end of the heap
block
=
mem_sbrk
(
size
);
if
(
block
==
(
void
*
)
-
1
)
{
return
NULL
;
}
if
(
!
block
)
{
// Update mm_heap_first and mm_heap_last since we extended the heap
void
*
ptr
=
mem_sbrk
(
asize
);
if
(
mm_heap_first
==
NULL
)
{
if
(
ptr
==
(
void
*
)
-
1
)
{
mm_heap_first
=
block
;
return
NULL
;
}
mm_heap_last
=
(
block_t
*
)
ptr
;
block
=
mm_heap_last
;
set_header
(
block
,
asize
,
true
);
}
}
mm_heap_last
=
block
;
set_header
(
block
,
get_size
(
block
),
true
);
// Initialize the block with the allocated size
set_header
(
block
,
size
,
true
);
return
block
->
payload
;
return
block
->
payload
;
}
}
/**
* mm_free - Releases a block to be reused for future allocations
*/
void
mm_free
(
void
*
ptr
)
{
void
mm_free
(
void
*
ptr
)
{
if
(
!
ptr
)
{
// mm_free(NULL) does nothing
if
(
ptr
==
NULL
)
{
return
;
return
;
}
}
block_t
*
block
=
(
block_t
*
)(
ptr
-
offsetof
(
block_t
,
payload
));
// Mark the block as unallocated
size
_t
block
_size
=
get_size
(
block
);
block
_t
*
block
=
block_from_payload
(
ptr
);
set_header
(
block
,
block_size
,
false
);
set_header
(
block
,
get_size
(
block
)
,
false
);
}
}
/*
/*
*
* mm_realloc - Change the size of the block by mm_mallocing a new block,
* mm_realloc - Change the size of the block by mm_mallocing a new block,
* copying its data, and mm_freeing the old block.
* copying its data, and mm_freeing the old block.
*
*/
*/
void
*
mm_realloc
(
void
*
old_ptr
,
size_t
size
)
{
void
*
mm_realloc
(
void
*
old_ptr
,
size_t
size
)
{
(
void
)
old_ptr
;
(
void
)
old_ptr
;
(
void
)
size
;
(
void
)
size
;
return
NULL
;
return
NULL
;
}
}
/**
/*
* mm_calloc - Allocate the block and set it to zero.
* mm_calloc - Allocate the block and set it to zero.
*/
*/
void
*
mm_calloc
(
size_t
nmemb
,
size_t
size
)
{
void
*
mm_calloc
(
size_t
nmemb
,
size_t
size
)
{
(
void
)
nmemb
;
(
void
)
nmemb
;
(
void
)
size
;
(
void
)
size
;
return
NULL
;
return
NULL
;
}
}
/*
/*
*
* mm_checkheap - So simple, it doesn't need a checker!
* mm_checkheap - So simple, it doesn't need a checker!
*/
*/
void
mm_checkheap
()
{
void
mm_checkheap
(
void
)
{
}
}
This diff is collapsed.
Click to expand it.
src/mm-implicit.c
View file @
6c942fb0
...
@@ -5,120 +5,158 @@
...
@@ -5,120 +5,158 @@
* TODO (bug): The allocator doesn't re-use space very well...
* TODO (bug): The allocator doesn't re-use space very well...
*/
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdint.h>
#include <stddef.h>
#include <unistd.h>
#include "mm.h"
#include "mm.h"
#include "memlib.h"
#include "memlib.h"
typedef
uint64_t
word_t
;
/** The required alignment of heap payloads */
const
size_t
ALIGNMENT
=
2
*
sizeof
(
word
_t
);
const
size_t
ALIGNMENT
=
2
*
sizeof
(
size
_t
);
/** The layout of each block allocated on the heap */
typedef
struct
{
typedef
struct
{
/** The size of the block and whether it is allocated (stored in the low bit) */
size_t
header
;
size_t
header
;
/*
/*
*
* We don't know what the size of the payload will be, so we will
* We don't know what the size of the payload will be, so we will
* declare it as a zero-length array. This allow us to obtain a
* declare it as a zero-length array. This allow us to obtain a
* pointer to the start of the payload.
* pointer to the start of the payload.
*/
*/
word
_t
payload
[];
uint8
_t
payload
[];
}
block_t
;
}
block_t
;
/** The first and last blocks on the heap */
static
block_t
*
mm_heap_first
=
NULL
;
static
block_t
*
mm_heap_first
=
NULL
;
static
block_t
*
mm_heap_last
=
NULL
;
static
block_t
*
mm_heap_last
=
NULL
;
/** Rounds up `size` to the nearest multiple of `n` */
static
size_t
round_up
(
size_t
size
,
size_t
n
)
{
static
size_t
round_up
(
size_t
size
,
size_t
n
)
{
return
n
*
((
size
+
(
n
-
1
))
/
n
);
return
(
size
+
(
n
-
1
))
/
n
*
n
;
}
static
size_t
get_size
(
block_t
*
block
)
{
return
block
->
header
&
~
0x7
;
}
}
/** Set's a block's header with the given size and allocation state */
static
void
set_header
(
block_t
*
block
,
size_t
size
,
bool
is_allocated
)
{
static
void
set_header
(
block_t
*
block
,
size_t
size
,
bool
is_allocated
)
{
block
->
header
=
size
|
is_allocated
;
block
->
header
=
size
|
is_allocated
;
}
}
/** Extracts a block's size from its header */
static
size_t
get_size
(
block_t
*
block
)
{
return
block
->
header
&
~
1
;
}
/** Extracts a block's allocation state from its header */
static
bool
is_allocated
(
block_t
*
block
)
{
static
bool
is_allocated
(
block_t
*
block
)
{
return
block
->
header
&
0x
1
;
return
block
->
header
&
1
;
}
}
block_t
*
find_fit
(
size_t
size
)
{
/**
for
(
block_t
*
curr
=
mm_heap_first
;
mm_heap_last
&&
curr
<=
mm_heap_last
;
curr
=
((
void
*
)
curr
+
get_size
(
curr
)))
{
* Finds the first free block in the heap with at least the given size.
size_t
curr_size
=
get_size
(
curr
);
* If no block is large enough, returns NULL.
if
(
!
is_allocated
(
curr
)
&&
curr_size
>=
size
)
{
*/
static
block_t
*
find_fit
(
size_t
size
)
{
// Traverse the blocks in the heap using the implicit list
for
(
block_t
*
curr
=
mm_heap_first
;
mm_heap_last
!=
NULL
&&
curr
<=
mm_heap_last
;
curr
=
(
void
*
)
curr
+
get_size
(
curr
)
)
{
// If the block is free and large enough for the allocation, return it
if
(
!
is_allocated
(
curr
)
&&
get_size
(
curr
)
>=
size
)
{
return
curr
;
return
curr
;
}
}
}
}
return
NULL
;
return
NULL
;
}
}
/** Gets the header corresponding to a given payload pointer */
static
block_t
*
block_from_payload
(
void
*
ptr
)
{
return
ptr
-
offsetof
(
block_t
,
payload
);
}
/**
* mm_init - Initializes the allocator state
*/
bool
mm_init
(
void
)
{
bool
mm_init
(
void
)
{
mm_heap_first
=
mem_sbrk
(
8
);
// We want the first payload to start at ALIGNMENT bytes from the start of the heap
set_header
(
mm_heap_first
,
8
,
true
);
void
*
padding
=
mem_sbrk
(
ALIGNMENT
-
sizeof
(
block_t
));
if
(
padding
==
(
void
*
)
-
1
)
{
return
false
;
}
// Initialize the heap with no blocks
mm_heap_first
=
NULL
;
mm_heap_last
=
NULL
;
mm_heap_last
=
NULL
;
return
true
;
return
true
;
}
}
/**
* mm_malloc - Allocates a block with the given size
*/
void
*
mm_malloc
(
size_t
size
)
{
void
*
mm_malloc
(
size_t
size
)
{
size_t
asize
=
round_up
(
size
+
sizeof
(
word_t
),
ALIGNMENT
);
// The block must have enough space for a header and be 16-byte aligned
size
=
round_up
(
sizeof
(
block_t
)
+
size
,
ALIGNMENT
);
// If there is a large enough free block, use it
block_t
*
block
=
find_fit
(
size
);
if
(
block
!=
NULL
)
{
set_header
(
block
,
get_size
(
block
),
true
);
return
block
->
payload
;
}
block_t
*
block
=
find_fit
(
asize
);
// Otherwise, a new block needs to be allocated at the end of the heap
block
=
mem_sbrk
(
size
);
if
(
block
==
(
void
*
)
-
1
)
{
return
NULL
;
}
if
(
!
block
)
{
// Update mm_heap_first and mm_heap_last since we extended the heap
void
*
ptr
=
mem_sbrk
(
asize
);
if
(
mm_heap_first
==
NULL
)
{
if
(
ptr
==
(
void
*
)
-
1
)
{
mm_heap_first
=
block
;
return
NULL
;
}
mm_heap_last
=
(
block_t
*
)
ptr
;
block
=
mm_heap_last
;
set_header
(
block
,
asize
,
true
);
}
}
mm_heap_last
=
block
;
set_header
(
block
,
get_size
(
block
),
true
);
// Initialize the block with the allocated size
set_header
(
block
,
size
,
true
);
return
block
->
payload
;
return
block
->
payload
;
}
}
/**
* mm_free - Releases a block to be reused for future allocations
*/
void
mm_free
(
void
*
ptr
)
{
void
mm_free
(
void
*
ptr
)
{
if
(
!
ptr
)
{
// mm_free(NULL) does nothing
if
(
ptr
==
NULL
)
{
return
;
return
;
}
}
block_t
*
block
=
(
block_t
*
)(
ptr
-
offsetof
(
block_t
,
payload
));
// Mark the block as unallocated
size
_t
block
_size
=
get_size
(
block
);
block
_t
*
block
=
block_from_payload
(
ptr
);
set_header
(
block
,
block_size
,
false
);
set_header
(
block
,
get_size
(
block
)
,
false
);
}
}
/*
/*
*
* mm_realloc - Change the size of the block by mm_mallocing a new block,
* mm_realloc - Change the size of the block by mm_mallocing a new block,
* copying its data, and mm_freeing the old block.
* copying its data, and mm_freeing the old block.
*
*/
*/
void
*
mm_realloc
(
void
*
old_ptr
,
size_t
size
)
{
void
*
mm_realloc
(
void
*
old_ptr
,
size_t
size
)
{
(
void
)
old_ptr
;
(
void
)
old_ptr
;
(
void
)
size
;
(
void
)
size
;
return
NULL
;
return
NULL
;
}
}
/**
/*
* mm_calloc - Allocate the block and set it to zero.
* mm_calloc - Allocate the block and set it to zero.
*/
*/
void
*
mm_calloc
(
size_t
nmemb
,
size_t
size
)
{
void
*
mm_calloc
(
size_t
nmemb
,
size_t
size
)
{
(
void
)
nmemb
;
(
void
)
nmemb
;
(
void
)
size
;
(
void
)
size
;
return
NULL
;
return
NULL
;
}
}
/*
/*
*
* mm_checkheap - So simple, it doesn't need a checker!
* mm_checkheap - So simple, it doesn't need a checker!
*/
*/
void
mm_checkheap
()
{
void
mm_checkheap
(
void
)
{
}
}
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Projects
Groups
Snippets
Help