Skip to content

Commit caa8a12

Browse files
committed
Problem set 1 for 2018.
0 parents  commit caa8a12

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1808
-0
lines changed

.gitignore

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#*#
2+
*.aux
3+
*.backup
4+
*.core
5+
*.dSYM
6+
*.dvi
7+
*.gcda
8+
*.log
9+
*.noopt
10+
*.o
11+
*.optimized
12+
*.unsafe
13+
*~
14+
.DS_Store
15+
.cproject
16+
.deps
17+
.gitcheckout
18+
.goutputstream-*
19+
.project
20+
a.out
21+
core*
22+
strace.out
23+
tags
24+
tags.*
25+
typescript
26+
vgcore*

README.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CS 61 Problem Sets
2+
==================
3+
4+
This repository contains the problem sets for Harvard’s CS 61 class, Systems
5+
Programming and Machine Organization.
6+
7+
For more information, see the course wiki:
8+
https://cs61.seas.harvard.edu/

pset1/.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*.dSYM
2+
*.o
3+
.deps
4+
hhtest
5+
out
6+
test[0-9][0-9][0-9]

pset1/AUTHORS.md

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Author and collaborators
2+
========================
3+
4+
Primary student
5+
---------------
6+
(Your name.)
7+
8+
9+
Collaborators
10+
-------------
11+
(List any other collaborators and describe help you got from other students
12+
in the class.)
13+
14+
15+
Citations
16+
---------
17+
(List any other sources consulted.)

pset1/GNUmakefile

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Default optimization level
2+
O ?= -O2
3+
4+
TESTS = $(patsubst %.cc,%,$(sort $(wildcard test[0-9][0-9][0-9].cc)))
5+
6+
RUN_OPTIONS = ASAN_OPTIONS=allocator_may_return_null=1
7+
8+
all: $(TESTS) hhtest
9+
10+
-include build/rules.mk
11+
LIBS = -lm
12+
13+
%.o: %.cc $(BUILDSTAMP)
14+
$(call run,$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(O) $(DEPCFLAGS) -o $@ -c,COMPILE,$<)
15+
16+
all:
17+
@echo "*** Run 'make check' or 'make check-all' to check your work."
18+
19+
test%: m61.o basealloc.o test%.o
20+
$(call run,$(CXX) $(CXXFLAGS) $(O) -o $@ $^ $(LDFLAGS) $(LIBS),LINK $@)
21+
22+
hhtest: m61.o basealloc.o hhtest.o
23+
$(call run,$(CXX) $(CXXFLAGS) $(O) -o $@ $^ $(LDFLAGS) $(LIBS),LINK $@)
24+
25+
check: $(patsubst %,run-%,$(TESTS))
26+
@echo "*** All tests succeeded!"
27+
28+
check-all: $(TESTS)
29+
@good=true; for i in $(TESTS); do $(MAKE) --no-print-directory run-$$i || good=false; done; \
30+
if $$good; then echo "*** All tests succeeded!"; fi; $$good
31+
32+
check-%:
33+
@any=false; good=true; j=`echo "$*" | sed s/^test//`; \
34+
for i in $(TESTS); do if expr "$$i" : "test0*$$j$$" >/dev/null; then \
35+
any=true; $(MAKE) run-$$i || good=false; fi; done; \
36+
if $$any; then $$good; else echo "*** No such test" 1>&2; $$any; fi
37+
38+
run-:
39+
@echo "*** No such test" 1>&2; exit 1
40+
41+
run-%: %
42+
@test -d out || mkdir out
43+
@-$(RUN_OPTIONS) sh -c "./$^ > out/$<.output 2>&1" >/dev/null 2>&1; true
44+
@perl check.pl out/$<.output $<.cc $<
45+
46+
clean: clean-main
47+
clean-main:
48+
$(call run,rm -f $(TESTS) hhtest *.o core *.core,CLEAN)
49+
$(call run,rm -rf out *.dSYM $(DEPSDIR))
50+
51+
distclean: clean
52+
53+
MALLOC_CHECK_=0
54+
export MALLOC_CHECK_
55+
56+
.PRECIOUS: %.o
57+
.PHONY: all clean clean-main check check-all check-% run- run-%

pset1/README.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CS 61 Problem Set 1
2+
===================
3+
4+
**Fill out both this file and `AUTHORS.md` before submitting.** We grade
5+
anonymously, so put all personally identifying information, including
6+
collaborators, in `AUTHORS.md`.
7+
8+
Grading notes (if any)
9+
----------------------
10+
11+
12+
13+
Extra credit attempted (if any)
14+
-------------------------------

pset1/basealloc.cc

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#define M61_DISABLE 1
2+
#include "m61.hh"
3+
#include <unordered_map>
4+
#include <vector>
5+
6+
7+
// This file contains a base memory allocator guaranteed not to
8+
// overwrite freed allocations. No need to understand it.
9+
10+
11+
using base_allocation = std::pair<uintptr_t, size_t>;
12+
13+
// `allocs` is a hash table mapping active pointer address to allocation size.
14+
// `frees` is a vector of freed allocations.
15+
// Both structures are specialized to use the *system* allocator (not m61).
16+
static std::unordered_map<uintptr_t, size_t,
17+
std::hash<uintptr_t>, std::equal_to<uintptr_t>,
18+
system_allocator<std::pair<const uintptr_t, size_t>>> allocs;
19+
static std::vector<base_allocation, system_allocator<base_allocation>> frees;
20+
static int disabled;
21+
22+
static unsigned alloc_random() {
23+
static uint64_t x = 8973443640547502487ULL;
24+
x = x * 6364136223846793005ULL + 1ULL;
25+
return x >> 32;
26+
}
27+
28+
static void base_allocate_atexit();
29+
30+
void* base_malloc(size_t sz) {
31+
if (disabled) {
32+
return malloc(sz);
33+
}
34+
35+
static int base_alloc_atexit_installed = 0;
36+
if (!base_alloc_atexit_installed) {
37+
atexit(base_allocate_atexit);
38+
base_alloc_atexit_installed = 1;
39+
}
40+
41+
// try to use a previously-freed block 75% of the time
42+
unsigned r = alloc_random();
43+
if (r % 4 != 0) {
44+
for (unsigned ntries = 0; ntries < 10 && ntries < frees.size(); ++ntries) {
45+
auto& f = frees[alloc_random() % frees.size()];
46+
if (f.second >= sz) {
47+
allocs.insert(f);
48+
uintptr_t ptr = f.first;
49+
f = frees.back();
50+
frees.pop_back();
51+
return reinterpret_cast<void*>(ptr);
52+
}
53+
}
54+
}
55+
56+
// need a new allocation
57+
void* ptr = malloc(sz);
58+
if (ptr) {
59+
allocs[reinterpret_cast<uintptr_t>(ptr)] = sz;
60+
}
61+
return ptr;
62+
}
63+
64+
void base_free(void* ptr) {
65+
if (disabled || !ptr) {
66+
free(ptr);
67+
} else {
68+
// mark free if found; if not found, invalid free: silently ignore
69+
auto it = allocs.find(reinterpret_cast<uintptr_t>(ptr));
70+
if (it != allocs.end()) {
71+
frees.push_back(*it);
72+
allocs.erase(it);
73+
}
74+
}
75+
}
76+
77+
void base_allocate_disable(int d) {
78+
disabled = d;
79+
}
80+
81+
static void base_allocate_atexit() {
82+
// clean up freed memory to shut up leak detector
83+
for (auto& alloc : allocs) {
84+
free(reinterpret_cast<void*>(alloc.first));
85+
}
86+
}

pset1/build/rules.mk

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# are we using clang?
2+
ISCLANG := $(shell if $(CC) --version | grep -e 'LLVM\|clang' >/dev/null; then echo 1; else echo 0; fi)
3+
4+
CFLAGS := -std=gnu11 -W -Wall -Wshadow -g $(DEFS) $(CFLAGS)
5+
CXXFLAGS := -std=gnu++1z -W -Wall -Wshadow -g $(DEFS) $(CXXFLAGS)
6+
7+
O ?= -O3
8+
ifeq ($(filter 0 1 2 3 s,$(O)$(NOOVERRIDEO)),$(strip $(O)))
9+
override O := -O$(O)
10+
endif
11+
12+
ifndef SAN
13+
SAN := $(SANITIZE)
14+
endif
15+
ifndef TSAN
16+
ifeq ($(WANT_TSAN),1)
17+
TSAN := $(SAN)
18+
endif
19+
endif
20+
21+
check_for_sanitizer = $(if $(strip $(shell $(CC) -fsanitize=$(1) -x c -E /dev/null 2>&1 | grep sanitize=)),$(info ** WARNING: The `$(CC)` compiler does not support `-fsanitize=$(1)`.),1)
22+
ifeq ($(TSAN),1)
23+
ifeq ($(or $(ISCLANG),$(filter-out 3.% 4.% 5.% 6.%,$(shell $(CC) -dumpversion)),$(filter-out Linux%,$(shell uname))),)
24+
$(info ** WARNING: If ThreadSanitizer fails, try `make SAN=1 CC=clang`.)
25+
endif
26+
ifeq ($(call check_for_sanitizer,thread),1)
27+
CFLAGS += -fsanitize=thread
28+
CXXFLAGS += -fsanitize=thread
29+
endif
30+
else
31+
ifeq ($(or $(ASAN),$(SAN)),1)
32+
ifeq ($(call check_for_sanitizer,address),1)
33+
CFLAGS += -fsanitize=address
34+
CXXFLAGS += -fsanitize=address
35+
endif
36+
endif
37+
ifeq ($(LEAKSAN),1)
38+
ifeq ($(call check_for_sanitizer,leak),1)
39+
CFLAGS += -fsanitize=leak
40+
CXXFLAGS += -fsanitize=leak
41+
endif
42+
endif
43+
endif
44+
ifeq ($(or $(UBSAN),$(SAN)),1)
45+
ifeq ($(call check_for_sanitizer,undefined),1)
46+
CFLAGS += -fsanitize=undefined
47+
CXXFLAGS += -fsanitize=undefined
48+
endif
49+
endif
50+
51+
# these rules ensure dependencies are created
52+
DEPCFLAGS = -MD -MF $(DEPSDIR)/$*.d -MP
53+
DEPSDIR := .deps
54+
BUILDSTAMP := $(DEPSDIR)/rebuildstamp
55+
DEPFILES := $(wildcard $(DEPSDIR)/*.d)
56+
ifneq ($(DEPFILES),)
57+
include $(DEPFILES)
58+
endif
59+
60+
# when the C compiler or optimization flags change, rebuild all objects
61+
ifneq ($(strip $(DEP_CC)),$(strip $(CC) $(CPPFLAGS) $(CFLAGS) $(O)))
62+
DEP_CC := $(shell mkdir -p $(DEPSDIR); echo >$(BUILDSTAMP); echo "DEP_CC:=$(CC) $(CPPFLAGS) $(CFLAGS) $(O)" >$(DEPSDIR)/_cc.d)
63+
endif
64+
ifneq ($(strip $(DEP_CXX)),$(strip $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(O)))
65+
DEP_CXX := $(shell mkdir -p $(DEPSDIR); echo >$(BUILDSTAMP); echo "DEP_CXX:=$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(O)" >$(DEPSDIR)/_cxx.d)
66+
endif
67+
68+
69+
V = 0
70+
ifeq ($(V),1)
71+
run = $(1) $(3)
72+
xrun = /bin/echo "$(1) $(3)" && $(1) $(3)
73+
else
74+
run = @$(if $(2),/bin/echo " $(2) $(3)" &&,) $(1) $(3)
75+
xrun = $(if $(2),/bin/echo " $(2) $(3)" &&,) $(1) $(3)
76+
endif
77+
runquiet = @$(1) $(3)
78+
79+
# cancel implicit rules we don't want
80+
%: %.c
81+
%.o: %.c
82+
%: %.cc
83+
%.o: %.cc
84+
%: %.o
85+
86+
$(BUILDSTAMP):
87+
@mkdir -p $(@D)
88+
@echo >$@
89+
90+
always:
91+
@:
92+
93+
clean-hook:
94+
@:
95+
96+
.PHONY: always clean-hook
97+
.PRECIOUS: %.o

0 commit comments

Comments
 (0)