Skip to content

Commit

Permalink
Problem set 1 for 2019.
Browse files Browse the repository at this point in the history
  • Loading branch information
kohler committed Sep 3, 2019
0 parents commit 3b599a0
Show file tree
Hide file tree
Showing 51 changed files with 1,931 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#*#
*.aux
*.backup
*.core
*.dSYM
*.dvi
*.gcda
*.log
*.noopt
*.o
*.optimized
*.unsafe
*~
.DS_Store
.cproject
.deps
.gitcheckout
.goutputstream-*
.project
a.out
core*
strace.out
tags
tags.*
typescript
vgcore*
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CS 61 Problem Sets
==================

This repository contains the problem sets for Harvard’s CS 61 class, Systems
Programming and Machine Organization.

For more information, see the course wiki:
https://cs61.seas.harvard.edu/
6 changes: 6 additions & 0 deletions pset1/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.dSYM
*.o
.deps
hhtest
out
test[0-9][0-9][0-9]
17 changes: 17 additions & 0 deletions pset1/AUTHORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Author and collaborators
========================

Primary student
---------------
(Your name.)


Collaborators
-------------
(List any other collaborators and describe help you got from other students
in the class.)


Citations
---------
(List any other sources consulted.)
55 changes: 55 additions & 0 deletions pset1/GNUmakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Default optimization level
O ?= 2

TESTS = $(patsubst %.cc,%,$(sort $(wildcard test[0-9][0-9][0-9].cc)))

all: $(TESTS) hhtest

-include build/rules.mk

LIBS = -lm

%.o: %.cc $(BUILDSTAMP)
$(call run,$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(DEPCFLAGS) $(O) -o $@ -c,COMPILE,$<)

all:
@echo "*** Run 'make check' or 'make check-all' to check your work."

test%: m61.o basealloc.o test%.o
$(call run,$(CXX) $(CXXFLAGS) $(O) -o $@ $^ $(LDFLAGS) $(LIBS),LINK $@)

hhtest: m61.o basealloc.o hhtest.o
$(call run,$(CXX) $(CXXFLAGS) $(O) -o $@ $^ $(LDFLAGS) $(LIBS),LINK $@)

check: $(patsubst %,run-%,$(TESTS))
@echo "*** All tests succeeded!"

check-all: $(TESTS)
@good=true; for i in $(TESTS); do $(MAKE) --no-print-directory run-$$i || good=false; done; \
if $$good; then echo "*** All tests succeeded!"; fi; $$good

check-%:
@any=false; good=true; for i in `perl check.pl -e "$*"`; do \
any=true; $(MAKE) run-$$i || good=false; done; \
if $$any; then $$good; else echo "*** No such test" 1>&2; $$any; fi

run-:
@echo "*** No such test" 1>&2; exit 1

run-%: %
@test -d out || mkdir out
@perl check.pl -x $<

clean: clean-main
clean-main:
$(call run,rm -f $(TESTS) hhtest *.o core *.core,CLEAN)
$(call run,rm -rf out *.dSYM $(DEPSDIR))

distclean: clean

MALLOC_CHECK_=0
export MALLOC_CHECK_

.PRECIOUS: %.o
.PHONY: all clean clean-main clean-hook distclean \
run run- run% prepare-check check check-all check-%
14 changes: 14 additions & 0 deletions pset1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
CS 61 Problem Set 1
===================

**Fill out both this file and `AUTHORS.md` before submitting.** We grade
anonymously, so put all personally identifying information, including
collaborators, in `AUTHORS.md`.

Grading notes (if any)
----------------------



Extra credit attempted (if any)
-------------------------------
92 changes: 92 additions & 0 deletions pset1/basealloc.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#define M61_DISABLE 1
#include "m61.hh"
#include <unordered_map>
#include <vector>
#include <sys/mman.h>


// This file contains a base memory allocator guaranteed not to
// overwrite freed allocations. No need to understand it.


using base_allocation = std::pair<uintptr_t, size_t>;

// `allocs` is a hash table mapping active pointer address to allocation size.
// `frees` is a vector of freed allocations.
static std::unordered_map<uintptr_t, size_t> allocs;
static std::vector<base_allocation> frees;
static int disabled;

static unsigned alloc_random() {
static uint64_t x = 8973443640547502487ULL;
x = x * 6364136223846793005ULL + 1ULL;
return x >> 32;
}

static void base_allocator_atexit();

void* base_malloc(size_t sz) {
if (disabled) {
return malloc(sz);
}
++disabled;
uintptr_t ptr = 0;

static int base_alloc_atexit_installed = 0;
if (!base_alloc_atexit_installed) {
atexit(base_allocator_atexit);
base_alloc_atexit_installed = 1;
}

// try to use a previously-freed block 75% of the time
unsigned r = alloc_random();
if (r % 4 != 0) {
for (unsigned ntries = 0; ntries < 10 && ntries < frees.size(); ++ntries) {
auto& f = frees[alloc_random() % frees.size()];
if (f.second >= sz) {
allocs.insert(f);
ptr = f.first;
f = frees.back();
frees.pop_back();
break;
}
}
}

if (!ptr) {
// need a new allocation
ptr = reinterpret_cast<uintptr_t>(malloc(sz ? sz : 1));
}
if (ptr) {
allocs[reinterpret_cast<uintptr_t>(ptr)] = sz;
}

--disabled;
return reinterpret_cast<void*>(ptr);
}

void base_free(void* ptr) {
if (disabled || !ptr) {
free(ptr);
} else {
// mark free if found; if not found, invalid free: silently ignore
++disabled;
auto it = allocs.find(reinterpret_cast<uintptr_t>(ptr));
if (it != allocs.end()) {
frees.push_back(*it);
allocs.erase(it);
}
--disabled;
}
}

void base_allocator_disable(bool d) {
disabled = d;
}

static void base_allocator_atexit() {
// clean up freed memory to shut up leak detector
for (auto& alloc : frees) {
free(reinterpret_cast<void*>(alloc.first));
}
}
105 changes: 105 additions & 0 deletions pset1/build/rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# are we using clang?
ISCLANG := $(shell if $(CC) --version | grep -e 'LLVM\|clang' >/dev/null; then echo 1; fi)
ISLINUX := $(if $(wildcard /usr/include/linux/*.h),1,)

CFLAGS := -std=gnu11 -W -Wall -Wshadow -Wno-unused-command-line-argument -g $(DEFS) $(CFLAGS)
CXXFLAGS := -std=gnu++1z -W -Wall -Wshadow -Wno-unused-command-line-argument -g $(DEFS) $(CXXFLAGS)
O ?= -O3
ifeq ($(filter 0 1 2 3 s,$(O)$(NOOVERRIDEO)),$(strip $(O)))
override O := -O$(O)
endif
LDFLAGS := -no-pie

# sanitizer arguments
ifndef SAN
SAN := $(SANITIZE)
endif
ifndef TSAN
ifeq ($(WANT_TSAN),1)
TSAN := $(SAN)
endif
endif

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)
ifeq ($(TSAN),1)
ifeq ($(or $(ISCLANG),$(filter-out 3.% 4.% 5.% 6.%,$(shell $(CC) -dumpversion)),$(filter-out Linux%,$(shell uname))),)
$(info ** WARNING: If ThreadSanitizer fails, try `make SAN=1 CC=clang`.)
endif
ifeq ($(call check_for_sanitizer,thread),1)
CFLAGS += -fsanitize=thread
CXXFLAGS += -fsanitize=thread
endif
else
ifeq ($(or $(ASAN),$(SAN)),1)
ifeq ($(call check_for_sanitizer,address),1)
CFLAGS += -fsanitize=address
CXXFLAGS += -fsanitize=address
endif
endif
ifeq ($(or $(LSAN),$(LEAKSAN)),1)
ifeq ($(call check_for_sanitizer,leak),1)
CFLAGS += -fsanitize=leak
CXXFLAGS += -fsanitize=leak
endif
endif
endif
ifeq ($(or $(UBSAN),$(SAN)),1)
ifeq ($(call check_for_sanitizer,undefined),1)
CFLAGS += -fsanitize=undefined
CXXFLAGS += -fsanitize=undefined
endif
endif

# profiling
ifeq ($(or $(PROFILE),$(PG)),1)
CFLAGS += -pg
CXXFLAGS += -pg
endif

# these rules ensure dependencies are created
DEPCFLAGS = -MD -MF $(DEPSDIR)/$*.d -MP
DEPSDIR := .deps
BUILDSTAMP := $(DEPSDIR)/rebuildstamp
DEPFILES := $(wildcard $(DEPSDIR)/*.d)
ifneq ($(DEPFILES),)
include $(DEPFILES)
endif

# when the C compiler or optimization flags change, rebuild all objects
ifneq ($(strip $(DEP_CC)),$(strip $(CC) $(CPPFLAGS) $(CFLAGS) $(O)))
DEP_CC := $(shell mkdir -p $(DEPSDIR); echo >$(BUILDSTAMP); echo "DEP_CC:=$(CC) $(CPPFLAGS) $(CFLAGS) $(O)" >$(DEPSDIR)/_cc.d)
endif
ifneq ($(strip $(DEP_CXX)),$(strip $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(O)))
DEP_CXX := $(shell mkdir -p $(DEPSDIR); echo >$(BUILDSTAMP); echo "DEP_CXX:=$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(O)" >$(DEPSDIR)/_cxx.d)
endif


V = 0
ifeq ($(V),1)
run = $(1) $(3)
xrun = /bin/echo "$(1) $(3)" && $(1) $(3)
else
run = @$(if $(2),/bin/echo " $(2) $(3)" &&,) $(1) $(3)
xrun = $(if $(2),/bin/echo " $(2) $(3)" &&,) $(1) $(3)
endif
runquiet = @$(1) $(3)

# cancel implicit rules we don't want
%: %.c
%.o: %.c
%: %.cc
%.o: %.cc
%: %.o

$(BUILDSTAMP):
@mkdir -p $(@D)
@echo >$@

always:
@:

clean-hook:
@:

.PHONY: always clean-hook
.PRECIOUS: %.o
Loading

0 comments on commit 3b599a0

Please sign in to comment.