Skip to content

Commit e9bcf83

Browse files
committed
Lecture 4.
And adjust arena names.
1 parent 56779b1 commit e9bcf83

25 files changed

+833
-30
lines changed

fundamentals3x/GNUmakefile

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
PROGRAMS = $(patsubst mb-%.c,membench-%,$(wildcard mb-*.c))
2-
#ifeq ($(strip $(shell ld -jemalloc 2>&1 | grep -- -ljemalloc)),)
3-
#PROGRAMS += membench-jemalloc
4-
#endif
5-
#ifneq ($(wildcard /usr/lib/libtcmalloc.so.4),)
6-
#PROGRAMS += membench-tcmalloc
7-
#endif
2+
ifeq ($(strip $(shell ld -ljemalloc 2>&1 | grep -- -ljemalloc)),)
3+
PROGRAMS += membench-jemalloc
4+
endif
5+
ifneq ($(wildcard /usr/lib/libtcmalloc.so.4),)
6+
PROGRAMS += membench-tcmalloc
7+
endif
88
all: $(PROGRAMS)
99

1010
DEFS += -pthread
@@ -23,7 +23,7 @@ membench-tcmalloc: membench.o mb-malloc.o
2323
$(CC) $(CFLAGS) $(O) -o $@ $^ /usr/lib/libtcmalloc.so.4
2424

2525
clean:
26-
rm -f *.o $(PROGRAMS)
26+
rm -f *.o $(PROGRAMS) membench-jemalloc membench-tcmalloc
2727
rm -rf $(DEPSDIR) *.dSYM
2828

2929
.PHONY: all clean

fundamentals3x/mb-arena.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ struct membench_arena {
5858
};
5959

6060

61-
membench_arena* membench_arena_new(void) {
61+
membench_arena* membench_arena_create(void) {
6262
// An arena initially contains a single chunk, which is free.
6363
// TODO: Change this!
6464
membench_arena* arena = (membench_arena*) malloc(sizeof(membench_arena));
@@ -77,6 +77,6 @@ void membench_free(membench_arena* arena, chunk* x) {
7777
arena->free = (free_chunk*) x; // OK because of the union
7878
}
7979

80-
void membench_arena_free(membench_arena* arena) {
80+
void membench_arena_destroy(membench_arena* arena) {
8181
free(arena);
8282
}

fundamentals3x/mb-cheat.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
static chunk the_only_chunk;
66

7-
membench_arena* membench_arena_new(void) {
7+
membench_arena* membench_arena_create(void) {
88
return NULL;
99
}
1010

@@ -17,6 +17,6 @@ void membench_free(membench_arena* arena, chunk* x) {
1717
(void) arena, (void) x;
1818
}
1919

20-
void membench_arena_free(membench_arena* arena) {
20+
void membench_arena_destroy(membench_arena* arena) {
2121
(void) arena;
2222
}

fundamentals3x/mb-malloc.c

+2-12
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,20 @@
11
#include "membench.h"
22
#include <stdlib.h>
33

4-
// membench_arena_new()
5-
// Allocate and initialize a new arena, returning the arena.
6-
membench_arena* membench_arena_new(void) {
4+
membench_arena* membench_arena_create(void) {
75
return NULL;
86
}
97

10-
// membench_alloc(arena)
11-
// Allocate and return a new chunk using the arena.
128
chunk* membench_alloc(membench_arena* arena) {
139
(void) arena;
1410
return (chunk*) malloc(sizeof(chunk));
1511
}
1612

17-
// membench_free(arena)
18-
// Free a chunk `x` that was previously allocated from this arena.
19-
//
20-
// REQUIREMENT: `x` was previously returned by
21-
// `membench_alloc(arena)` for this arena, and not previously
22-
// freed, and `x != NULL`.
2313
void membench_free(membench_arena* arena, chunk* x) {
2414
(void) arena;
2515
free(x);
2616
}
2717

28-
void membench_arena_free(membench_arena* arena) {
18+
void membench_arena_destroy(membench_arena* arena) {
2919
(void) arena;
3020
}

fundamentals3x/membench.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ void benchmark(void) {
1212
// Allocate a new memory arena for this thread.
1313
// An "arena" is an object that encapsulates a set of memory allocations.
1414
// Arenas can capture allocation statistics and improve speed.
15-
membench_arena* arena = membench_arena_new();
15+
membench_arena* arena = membench_arena_create();
1616

1717
// Allocate `k` chunks.
1818
chunk** cs = (chunk**) malloc(sizeof(chunk*) * k);
@@ -33,7 +33,7 @@ void benchmark(void) {
3333
// Free the chunks and the arena.
3434
for (unsigned i = 0; i != k; ++i)
3535
membench_free(arena, cs[i]);
36-
membench_arena_free(arena);
36+
membench_arena_destroy(arena);
3737
free(cs);
3838
}
3939

fundamentals3x/membench.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ typedef struct chunk {
1010
typedef struct membench_arena membench_arena;
1111

1212

13-
// membench_arena_new()
13+
// membench_arena_create()
1414
// Allocate and initialize a new arena, returning the arena.
15-
membench_arena* membench_arena_new(void);
15+
membench_arena* membench_arena_create(void);
1616

1717

1818
// membench_alloc(arena)
@@ -29,12 +29,12 @@ chunk* membench_alloc(membench_arena* arena);
2929
void membench_free(membench_arena* arena, chunk* x);
3030

3131

32-
// membench_arena_free(arena)
32+
// membench_arena_destroy(arena)
3333
// Clean up the arena and free its memory.
3434
//
35-
// REQUIREMENT: Before `membench_arena_free(arena)` is called, all
35+
// REQUIREMENT: Before `membench_arena_destroy(arena)` is called, all
3636
// chunks previously returned by `membench_alloc(arena)` have been
3737
// freed.
38-
void membench_arena_free(membench_arena* arena);
38+
void membench_arena_destroy(membench_arena* arena);
3939

4040
#endif

fundamentals4/.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
add
2+
addu
3+
fib
4+
membench-malloc
5+
membench-arena
6+
membench-arena[0-9]

fundamentals4/GNUmakefile

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
PROGRAMS = add addu fib membench-malloc membench-arena \
2+
membench-arena1 membench-arena2 membench-arena3 \
3+
membench-arena4
4+
5+
all: $(PROGRAMS)
6+
7+
DEFS += -pthread
8+
include ../common/rules.mk
9+
10+
%.o: %.c $(BUILDSTAMP)
11+
$(CC) $(CPPFLAGS) $(CFLAGS) $(DEPCFLAGS) $(O) -o $@ -c $<
12+
13+
add: add.o
14+
$(CC) $(CFLAGS) $(O) -o $@ $^
15+
16+
addu: addu.o
17+
$(CC) $(CFLAGS) $(O) -o $@ $^
18+
19+
membench-%: membench.o mb-%.o
20+
$(CC) $(CFLAGS) $(O) -o $@ $^
21+
22+
clean:
23+
rm -f $(PROGRAMS) *.o
24+
rm -rf $(DEPSDIR) *.dSYM
25+
26+
.PHONY: all clean

fundamentals4/add.c

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <assert.h>
4+
5+
int add(int a, int b) {
6+
assert(a + 1 > a);
7+
return a + b;
8+
}
9+
10+
int main(int argc, char* argv[]) {
11+
if (argc <= 2) {
12+
fprintf(stderr, "Usage: add A B\n\
13+
Prints A + B.\n");
14+
exit(1);
15+
}
16+
17+
int a = strtol(argv[1], 0, 0);
18+
int b = strtol(argv[2], 0, 0);
19+
printf("%d + %d = %d\n", a, b, add(a, b));
20+
}

fundamentals4/addu.c

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <assert.h>
4+
5+
unsigned add(unsigned a, unsigned b) {
6+
assert(a + 1 > a);
7+
return a + b;
8+
}
9+
10+
int main(int argc, char* argv[]) {
11+
if (argc <= 2) {
12+
fprintf(stderr, "Usage: add A B\n\
13+
Prints A + B.\n");
14+
exit(1);
15+
}
16+
17+
unsigned a = strtoul(argv[1], 0, 0);
18+
unsigned b = strtoul(argv[2], 0, 0);
19+
printf("%u + %u = %u\n", a, b, add(a, b));
20+
}

fundamentals4/fib.c

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
int fib(int n) {
5+
if (n < 2)
6+
return n;
7+
else
8+
return fib(n - 1) + fib(n - 2);
9+
}
10+
11+
int main(int argc, char* argv[]) {
12+
int n = 6;
13+
if (argc > 1)
14+
n = strtol(argv[1], NULL, 0);
15+
16+
printf("%d\n", fib(n));
17+
}

fundamentals4/mb-arena.c

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#include "membench.h"
2+
#include <stdlib.h>
3+
#include <assert.h>
4+
#include <stdint.h>
5+
#include <stddef.h>
6+
7+
/*
8+
9+
Write an arena allocator for `chunk` objects. Your allocator should:
10+
11+
* Allocate a chunk in O(1) time.
12+
* Free a chunk in O(1) time.
13+
* Use memory proportional to the peak number of actively allocated
14+
chunks (rather than, say, the total number of allocated chunks).
15+
* Run out of memory only if the system has no more memory available.
16+
17+
More on arenas:
18+
https://en.wikipedia.org/wiki/Region-based_memory_management
19+
20+
See "membench.h" for function semantics.
21+
22+
*/
23+
24+
25+
#define GROUPSIZE 4096
26+
typedef struct membench_group {
27+
int pos;
28+
chunk chunks[GROUPSIZE];
29+
} membench_group;
30+
31+
struct membench_arena {
32+
membench_group* group;
33+
};
34+
35+
36+
static membench_group* membench_group_new(void) {
37+
membench_group* g = (membench_group*) malloc(sizeof(membench_group));
38+
g->pos = 0;
39+
return g;
40+
}
41+
42+
membench_arena* membench_arena_create(void) {
43+
membench_arena* arena = (membench_arena*) malloc(sizeof(membench_arena));
44+
arena->group = membench_group_new();
45+
return arena;
46+
}
47+
48+
chunk* membench_alloc(membench_arena* arena) {
49+
membench_group* g = arena->group;
50+
assert(g->pos < GROUPSIZE);
51+
chunk* result = &g->chunks[g->pos];
52+
++g->pos;
53+
return result;
54+
}
55+
56+
void membench_free(membench_arena* arena, chunk* x) {
57+
(void) arena, (void) x;
58+
}
59+
60+
void membench_arena_destroy(membench_arena* arena) {
61+
free(arena->group);
62+
free(arena);
63+
}

fundamentals4/mb-arena1.c

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include "membench.h"
2+
#include <stdlib.h>
3+
#include <assert.h>
4+
#include <stdint.h>
5+
#include <stddef.h>
6+
7+
/*
8+
9+
Write an arena allocator for `chunk` objects. Your allocator should:
10+
11+
* Allocate a chunk in O(1) time.
12+
* Free a chunk in O(1) time.
13+
* Use memory proportional to the peak number of actively allocated
14+
chunks (rather than, say, the total number of allocated chunks).
15+
* Run out of memory only if the system has no more memory available.
16+
17+
More on arenas:
18+
https://en.wikipedia.org/wiki/Region-based_memory_management
19+
20+
See "membench.h" for function semantics.
21+
22+
*/
23+
24+
25+
#define GROUPSIZE 1
26+
typedef struct membench_group {
27+
int pos;
28+
chunk chunks[GROUPSIZE];
29+
} membench_group;
30+
31+
struct membench_arena {
32+
membench_group* group;
33+
};
34+
35+
36+
membench_arena* membench_arena_create(void) {
37+
membench_arena* arena = (membench_arena*) malloc(sizeof(membench_arena));
38+
arena->group = (membench_group*) malloc(sizeof(membench_group));
39+
arena->group->pos = 0;
40+
return arena;
41+
}
42+
43+
chunk* membench_alloc(membench_arena* arena) {
44+
membench_group* g = arena->group;
45+
assert(g->pos < GROUPSIZE);
46+
chunk* result = &g->chunks[g->pos];
47+
++g->pos;
48+
return result;
49+
}
50+
51+
void membench_free(membench_arena* arena, chunk* x) {
52+
(void) arena, (void) x;
53+
}
54+
55+
void membench_arena_destroy(membench_arena* arena) {
56+
free(arena->group);
57+
free(arena);
58+
}

0 commit comments

Comments
 (0)