Skip to content

Commit 3b599a0

Browse files
committed
Problem set 1 for 2019.
0 parents  commit 3b599a0

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

+1931
-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

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

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

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#define M61_DISABLE 1
2+
#include "m61.hh"
3+
#include <unordered_map>
4+
#include <vector>
5+
#include <sys/mman.h>
6+
7+
8+
// This file contains a base memory allocator guaranteed not to
9+
// overwrite freed allocations. No need to understand it.
10+
11+
12+
using base_allocation = std::pair<uintptr_t, size_t>;
13+
14+
// `allocs` is a hash table mapping active pointer address to allocation size.
15+
// `frees` is a vector of freed allocations.
16+
static std::unordered_map<uintptr_t, size_t> allocs;
17+
static std::vector<base_allocation> frees;
18+
static int disabled;
19+
20+
static unsigned alloc_random() {
21+
static uint64_t x = 8973443640547502487ULL;
22+
x = x * 6364136223846793005ULL + 1ULL;
23+
return x >> 32;
24+
}
25+
26+
static void base_allocator_atexit();
27+
28+
void* base_malloc(size_t sz) {
29+
if (disabled) {
30+
return malloc(sz);
31+
}
32+
++disabled;
33+
uintptr_t ptr = 0;
34+
35+
static int base_alloc_atexit_installed = 0;
36+
if (!base_alloc_atexit_installed) {
37+
atexit(base_allocator_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+
ptr = f.first;
49+
f = frees.back();
50+
frees.pop_back();
51+
break;
52+
}
53+
}
54+
}
55+
56+
if (!ptr) {
57+
// need a new allocation
58+
ptr = reinterpret_cast<uintptr_t>(malloc(sz ? sz : 1));
59+
}
60+
if (ptr) {
61+
allocs[reinterpret_cast<uintptr_t>(ptr)] = sz;
62+
}
63+
64+
--disabled;
65+
return reinterpret_cast<void*>(ptr);
66+
}
67+
68+
void base_free(void* ptr) {
69+
if (disabled || !ptr) {
70+
free(ptr);
71+
} else {
72+
// mark free if found; if not found, invalid free: silently ignore
73+
++disabled;
74+
auto it = allocs.find(reinterpret_cast<uintptr_t>(ptr));
75+
if (it != allocs.end()) {
76+
frees.push_back(*it);
77+
allocs.erase(it);
78+
}
79+
--disabled;
80+
}
81+
}
82+
83+
void base_allocator_disable(bool d) {
84+
disabled = d;
85+
}
86+
87+
static void base_allocator_atexit() {
88+
// clean up freed memory to shut up leak detector
89+
for (auto& alloc : frees) {
90+
free(reinterpret_cast<void*>(alloc.first));
91+
}
92+
}

pset1/build/rules.mk

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

0 commit comments

Comments
 (0)