From 65b71e11e5db0b9ed9cc5cf3838b6ce476b06045 Mon Sep 17 00:00:00 2001 From: Gene Stark Date: Sat, 5 Mar 2022 12:43:06 -0500 Subject: [PATCH 1/5] Bring in basecode from the development repo. --- .gitignore | 4 + .gitlab-ci.yml | 29 ++++ hw3/Makefile | 58 +++++++ hw3/hw3.sublime-project | 46 ++++++ hw3/include/debug.h | 88 +++++++++++ hw3/include/sfmm.h | 339 ++++++++++++++++++++++++++++++++++++++++ hw3/lib/sfutil.o | Bin 0 -> 10864 bytes hw3/src/main.c | 14 ++ hw3/src/sfmm.c | 34 ++++ hw3/tests/sfmm_tests.c | 260 ++++++++++++++++++++++++++++++ 10 files changed, 872 insertions(+) create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 hw3/Makefile create mode 100644 hw3/hw3.sublime-project create mode 100644 hw3/include/debug.h create mode 100644 hw3/include/sfmm.h create mode 100644 hw3/lib/sfutil.o create mode 100644 hw3/src/main.c create mode 100644 hw3/src/sfmm.c create mode 100644 hw3/tests/sfmm_tests.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7f239b0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +bin/ +build/ +*~ +*.out diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..922d49c --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,29 @@ +image: hwrunner:latest +variables: + GIT_SSL_NO_VERIFY: "true" + EXEC: sfmm + HW_DIR: hw3 + CPU_LIMIT: 60 + FILE_LIMIT: 1000000 +before_script: + - make clean all -C ${HW_DIR} +stages: + - build + - run + - test +build: + stage: build + script: + - echo "Build done" +run: + stage: run + script: + - ulimit -t ${CPU_LIMIT} + - ulimit -f ${FILE_LIMIT} + - cd ${HW_DIR} && bin/${EXEC} +test: + stage: test + script: + - ulimit -t ${CPU_LIMIT} + - ulimit -f ${FILE_LIMIT} + - cd ${HW_DIR} && bin/${EXEC}_tests -S --verbose=0 --timeout 30 diff --git a/hw3/Makefile b/hw3/Makefile new file mode 100644 index 0000000..1a34cbc --- /dev/null +++ b/hw3/Makefile @@ -0,0 +1,58 @@ +CC := gcc +SRCD := src +TSTD := tests +BLDD := build +BIND := bin +INCD := include +LIBD := lib + +ALL_SRCF := $(shell find $(SRCD) -type f -name *.c) +ALL_LIBF := $(shell find $(LIBD) -type f -name *.o) +ALL_OBJF := $(patsubst $(SRCD)/%,$(BLDD)/%,$(ALL_SRCF:.c=.o)) +FUNC_FILES := $(filter-out build/main.o, $(ALL_OBJF)) + +TEST_SRC := $(shell find $(TSTD) -type f -name *.c) + +INC := -I $(INCD) + +CFLAGS := -Wall -Werror -Wno-unused-function -MMD +COLORF := -DCOLOR +DFLAGS := -g -DDEBUG -DCOLOR +PRINT_STAMENTS := -DERROR -DSUCCESS -DWARN -DINFO + +STD := -std=c99 +TEST_LIB := -lcriterion +LIBS := -lm + +CFLAGS += $(STD) + +EXEC := sfmm +TEST := $(EXEC)_tests + +.PHONY: clean all setup debug + +all: setup $(BIND)/$(EXEC) $(BIND)/$(TEST) + +debug: CFLAGS += $(DFLAGS) $(PRINT_STAMENTS) $(COLORF) +debug: all + +setup: $(BIND) $(BLDD) +$(BIND): + mkdir -p $(BIND) +$(BLDD): + mkdir -p $(BLDD) + +$(BIND)/$(EXEC): $(ALL_OBJF) $(ALL_LIBF) + $(CC) $^ -o $@ $(LIBS) + +$(BIND)/$(TEST): $(FUNC_FILES) $(TEST_SRC) $(ALL_LIBF) + $(CC) $(CFLAGS) $(INC) $(FUNC_FILES) $(TEST_SRC) $(ALL_LIBF) $(TEST_LIB) $(LIBS) -o $@ + +$(BLDD)/%.o: $(SRCD)/%.c + $(CC) $(CFLAGS) $(INC) -c -o $@ $< + +clean: + rm -rf $(BLDD) $(BIND) + +.PRECIOUS: $(BLDD)/*.d +-include $(BLDD)/*.d diff --git a/hw3/hw3.sublime-project b/hw3/hw3.sublime-project new file mode 100644 index 0000000..e7b6e29 --- /dev/null +++ b/hw3/hw3.sublime-project @@ -0,0 +1,46 @@ +{ + "folders": + [ + { + "path":".", + "name":"Project Base" + }, + { + "path": "src", + "name": "C Source", + "follow_symlinks": false, + "file_include_patterns":["*.c"], + }, + { + "path": "include", + "name": "C Headers", + "follow_symlinks": false, + "file_include_patterns":["*.h"], + }, + { + "path": "tests", + "name": "Tests", + } + ], + "settings": + { + }, + "build_systems": + [ + { + "name": "Release (full build)", + "working_dir":"$project_path", + "shell_cmd": "make clean all", + }, + { + "name": "Debug (full build)", + "working_dir":"$project_path", + "shell_cmd": "make clean debug", + }, + { + "name": "Test", + "working_dir":"$project_path", + "shell_cmd": "bin/${project_base_name}_tests}", + } + ] +} diff --git a/hw3/include/debug.h b/hw3/include/debug.h new file mode 100644 index 0000000..e8fc8b6 --- /dev/null +++ b/hw3/include/debug.h @@ -0,0 +1,88 @@ +#ifndef DEBUG_H +#define DEBUG_H + +#include + +#define NL "\n" + +#ifdef COLOR +#define KNRM "\033[0m" +#define KRED "\033[1;31m" +#define KGRN "\033[1;32m" +#define KYEL "\033[1;33m" +#define KBLU "\033[1;34m" +#define KMAG "\033[1;35m" +#define KCYN "\033[1;36m" +#define KWHT "\033[1;37m" +#define KBWN "\033[0;33m" +#else +#define KNRM "" +#define KRED "" +#define KGRN "" +#define KYEL "" +#define KBLU "" +#define KMAG "" +#define KCYN "" +#define KWHT "" +#define KBWN "" +#endif + +#ifdef VERBOSE +#define DEBUG +#define INFO +#define WARN +#define ERROR +#define SUCCESS +#endif + +#ifdef DEBUG +#define debug(S, ...) \ + do { \ + fprintf(stderr, KMAG "DEBUG: %s:%s:%d " KNRM S NL, __FILE__, \ + __extension__ __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) +#else +#define debug(S, ...) +#endif + +#ifdef INFO +#define info(S, ...) \ + do { \ + fprintf(stderr, KBLU "INFO: %s:%s:%d " KNRM S NL, __FILE__, \ + __extension__ __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) +#else +#define info(S, ...) +#endif + +#ifdef WARN +#define warn(S, ...) \ + do { \ + fprintf(stderr, KYEL "WARN: %s:%s:%d " KNRM S NL, __FILE__, \ + __extension__ __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) +#else +#define warn(S, ...) +#endif + +#ifdef SUCCESS +#define success(S, ...) \ + do { \ + fprintf(stderr, KGRN "SUCCESS: %s:%s:%d " KNRM S NL, __FILE__, \ + __extension__ __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) +#else +#define success(S, ...) +#endif + +#ifdef ERROR +#define error(S, ...) \ + do { \ + fprintf(stderr, KRED "ERROR: %s:%s:%d " KNRM S NL, __FILE__, \ + __extension__ __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) +#else +#define error(S, ...) +#endif + +#endif /* DEBUG_H */ diff --git a/hw3/include/sfmm.h b/hw3/include/sfmm.h new file mode 100644 index 0000000..f62950b --- /dev/null +++ b/hw3/include/sfmm.h @@ -0,0 +1,339 @@ +/** + * === DO NOT MODIFY THIS FILE === + * If you need some other prototypes or constants in a header, please put them + * in another header file. + * + * When we grade, we will be replacing this file with our own copy. + * You have been warned. + * === DO NOT MODIFY THIS FILE === + */ +#ifndef SFMM_H +#define SFMM_H +#include +#include +#include + +/* + + Format of an allocated memory block + +-----------------------------------------------------------------------------------------+ + | 64-bit-wide row | + +-----------------------------------------------------------------------------------------+ + + +----------------------------+----------------------+--------+--------+---------+---------+ <- header + | payload size | block_size | unused | alloc |prv alloc|in qklst | + | (0/1) |(4 LSB's implicitly 0)| (0) | (1) | (0/1) | (0) | + | (32 bits) | (28 bits) | 1 bit | 1 bit | 1 bit | 1 bit | + +---------------------------------------------------+--------+--------+---------+---------+ <- (aligned) + | | + | Payload and Padding | + | (N rows) | + | | + | | + +-----------------------------------------------------------------------------------------+ + + NOTE: For an allocated block, there is no footer (it is used for payload). + NOTE: The actual stored header is obfuscated by bitwise XOR'ing with MAGIC. + The above diagram shows the un-obfuscated contents. +*/ + +/* + + Format of a memory block in a quick list + +-----------------------------------------------------------------------------------------+ + | 64-bit-wide row | + +-----------------------------------------------------------------------------------------+ + + +----------------------------+----------------------+--------+--------+---------+---------+ <- header + | unused | block_size | unused | alloc |prv alloc|in qklst | + | (0) |(4 LSB's implicitly 0)| (0) | (1) | (0/1) | (1) | + | (32 bits) | (28 bits) | 1 bit | 1 bit | 1 bit | 1 bit | + +---------------------------------------------------+--------+--------+---------+---------+ <- (aligned) + | | + | Payload and Padding | + | (N rows) | + | | + | | + +-----------------------------------------------------------------------------------------+ + + NOTE: For a block in a quick list, there is no footer. +*/ + +/* + Format of a free memory block + + + +----------------------------+----------------------+--------+--------+---------+---------+ <- header + | unused | block_size | unused | alloc |prv alloc|in qklst | + | (0) |(4 LSB's implicitly 0)| (0) | (0) | (0/1) | (0) | + | (32 bits) | (28 bits) | 1 bit | 1 bit | 1 bit | 1 bit | + +------------------------------------------------------------+--------+---------+---------+ <- (aligned) + | | + | Pointer to next free block | + | (1 row) | + +-----------------------------------------------------------------------------------------+ + | | + | Pointer to previous free block | + | (1 row) | + +-----------------------------------------------------------------------------------------+ + | | + | Unused | + | (N rows) | + | | + | | + +------------------------------------------------------------+--------+---------+---------+ <- footer + | unused | block_size | unused | alloc |prv alloc|in qklst | + | (0) |(4 LSB's implicitly 0)| (0) | (0) | (0/1) | (0) | + | (32 bits) | (28 bits) | 1 bit | 1 bit | 1 bit | 1 bit | + +------------------------------------------------------------+--------+---------+---------+ <- (aligned) + + NOTE: For a free block, footer contents must always be identical to header contents. + NOTE: The actual stored footer is obfuscated by bitwise XOR'ing with MAGIC. + The above diagram shows the un-obfuscated contents. +*/ + +#define IN_QUICK_LIST 0x1 +#define PREV_BLOCK_ALLOCATED 0x2 +#define THIS_BLOCK_ALLOCATED 0x4 + +typedef uint32_t sf_size_t; +typedef uint64_t sf_header; +typedef sf_header sf_footer; + +/* + * Structure of a block. + * The first field of this structure is actually the footer of the *previous* block. + * This must be taken into account when creating sf_block pointers from memory addresses. + */ +typedef struct sf_block { + sf_footer prev_footer; // NOTE: This actually belongs to the *previous* block. + sf_header header; // This is where the current block really starts. + union { + /* A free block contains links to other blocks in a free list. */ + struct { + struct sf_block *next; + struct sf_block *prev; + } links; + /* An allocated block contains a payload (aligned), starting here. */ + char payload[0]; // Length varies according to block size. + } body; +} sf_block; + +/* + * The heap is designed to keep the payload area of each block aligned to a two-row (16-byte) + * boundary. The header of a block precedes the payload area, and is only single-row (8-byte) + * aligned. The first block of the heap starts as soon as possible after the beginning of the + * heap, subject to the condition that its payload area is two-row aligned. + */ + +/* + Format of the heap + + +-----------------------------------------------------------------------------------------+ + | 64-bit-wide row | + +-----------------------------------------------------------------------------------------+ + + +-----------------------------------------------------------------------------------------+ <- heap start + | | (aligned) + | Unused | + | (1 row) | + +----------------------------+----------------------+--------+--------+---------+---------+ <- header + | payload size |minimum block_size(32)| unused | alloc |prv alloc|in qklst | + | (0) |(4 LSB's implicitly 0)| (0) | (1) | (0/1) | (0) | prologue block + | (32 bits) | (28 bits) | 1 bit | 1 bit | 1 bit | 1 bit | + +------------------------------------------------------------+--------+---------+---------+ <- (aligned) + | | + | Unused Payload Area | + | (3 rows) | + +------------------------------------------------------------+--------+---------+---------+ <- header + | payload size | block_size | unused | alloc |prv alloc|in qklst | + | (0/1) |(4 LSB's implicitly 0)| (0) | (0/1) | (0/1) | (0/1) | first block + | (32 bits) | (28 bits) | 1 bit | 1 bit | 1 bit | 1 bit | + +------------------------------------------------------------+--------+---------+---------+ <- (aligned) + | | + | Payload and Padding | + | (N rows) | + | | + | | + +--------------------------------------------+------------------------+---------+---------+ + | | + | | + | | + | | + | Additional allocated and free blocks | + | | + | | + | | + +-----------------------------------------------------------------------------------------+ + | payload size | block_size | unused | alloc |prv alloc|in qklst | + | (0) | (0) | (0) | (1) | (0/1) | (0) | epilogue + | (32 bits) | (28 bits) | 1 bit | 1 bit | 1 bit | 1 bit | + +------------------------------------------------------------+--------+---------+---------+ <- heap_end + (aligned) + + NOTE: The actual stored epilogue is obfuscated by bitwise XOR'ing with MAGIC. + The above diagram shows the un-obfuscated contents. +*/ + +/* sf_errno: will be set on error */ +int sf_errno; + +/* + * "Quick lists": These are used to hold recently freed blocks of small sizes, so that they + * can be used to satisfy allocations without searching lists or splitting blocks. + * Blocks on a quick list are marked as allocated, so they are not available for coalescing. + * The number of blocks in any individual quick list is limited to QUICK_LIST_MAX. + * If adding a block to a quick list would cause it to exceed QUICK_LIST_MAX, then the + * list is flushed, returning the existing blocks in the list to the main pool, and then + * the block being freed is added to the now-empty list, leaving that list containing one block. + * + * The quick lists are indexed by (size-MIN_BLOCK_SIZE)/ALIGN_SIZE, starting with blocks of the + * minimum block size at index 0, blocks of size MIN_BLOCK_SIZE+ALIGN_SIZE at index 1, and so on. + * They are maintained as singly linked lists, using a LIFO discipline. + */ + +#define NUM_QUICK_LISTS 10 /* Number of quick lists. */ +#define QUICK_LIST_MAX 5 /* Maximum number of blocks permitted on a single quick list. */ + +struct { + int length; // Number of blocks currently in the list. + struct sf_block *first; // Pointer to first block in the list. +} sf_quick_lists[NUM_QUICK_LISTS]; + +/* + * Free blocks are maintained in a set of circular, doubly linked lists, segregated by + * size class. The first list holds blocks of the minimum size M. The second list holds + * blocks of size (M, 2M]. The third list holds blocks whose size is in the interval (2M, 4M]. + * The fourth list holds blocks whose size is in the interval (4M, 8M], and so on. + * This continues up to the interval (128M, 256M], and then the last list holds all blocks + * of size greater than 256M. + * + * Each of the circular, doubly linked lists has a "dummy" block used as the list header. + * This dummy block is always linked between the last and the first element of the list. + * In an empty list, the next and free pointers of the list header point back to itself. + * In a list with something in it, the next pointer of the header points to the first node + * in the list and the previous pointer of the header points to the last node in the list. + * The header itself is never removed from the list and it contains no data (only the link + * fields are used). The reason for doing things this way is to avoid edge cases in insertion + * and deletion of nodes from the list. + */ + +#define NUM_FREE_LISTS 10 +struct sf_block sf_free_list_heads[NUM_FREE_LISTS]; + +/* + * This is your implementation of sf_malloc. It acquires uninitialized memory that + * is aligned and padded properly for the underlying system. + * + * @param size The number of bytes requested to be allocated. + * + * @return If size is 0, then NULL is returned without setting sf_errno. + * If size is nonzero, then if the allocation is successful a pointer to a valid region of + * memory of the requested size is returned. If the allocation is not successful, then + * NULL is returned and sf_errno is set to ENOMEM. + */ +void *sf_malloc(sf_size_t size); + +/* + * Resizes the memory pointed to by ptr to size bytes. + * + * @param ptr Address of the memory region to resize. + * @param size The minimum size to resize the memory to. + * + * @return If successful, the pointer to a valid region of memory is + * returned, else NULL is returned and sf_errno is set appropriately. + * + * If sf_realloc is called with an invalid pointer sf_errno should be set to EINVAL. + * If there is no memory available sf_realloc should set sf_errno to ENOMEM. + * + * If sf_realloc is called with a valid pointer and a size of 0 it should free + * the allocated block and return NULL without setting sf_errno. + */ +void *sf_realloc(void *ptr, sf_size_t size); + +/* + * Marks a dynamically allocated region as no longer in use. + * Adds the newly freed block to the free list. + * + * @param ptr Address of memory returned by the function sf_malloc. + * + * If ptr is invalid, the function calls abort() to exit the program. + */ +void sf_free(void *ptr); + +/* + * Get the current amount of internal fragmentation of the heap. + * + * @return the current amount of internal fragmentation, defined to be the + * ratio of the total amount of payload to the total size of allocated blocks. + * If there are no allocated blocks, then the returned value should be 0.0. + */ +double sf_internal_fragmentation(); + +/* + * Get the peak memory utilization for the heap. + * + * @return the peak memory utilization over the interval starting from the + * time the heap was initialized, up to the current time. The peak memory + * utilization at a given time, as defined in the lecture and textbook, + * is the ratio of the maximum aggregate payload up to that time, divided + * by the current heap size. If the heap has not yet been initialized, + * this function should return 0.0. + */ +double sf_peak_utilization(); + + +/* sfutil.c: Helper functions already created for this assignment. */ + +/* + * @return The starting address of the heap for your allocator. + */ +void *sf_mem_start(); + +/* + * @return The ending address of the heap for your allocator. + */ +void *sf_mem_end(); + +/* + * This function increases the size of your heap by adding one page of + * memory to the end. + * + * @return On success, this function returns a pointer to the start of the + * additional page, which is the same as the value that would have been returned + * by get_heap_end() before the size increase. On error, NULL is returned. + */ +void *sf_mem_grow(); + +/* The size of a page of memory returned by sf_mem_grow(). */ +#define PAGE_SZ ((sf_size_t)1024) + +/* + * @return The "magic number" used to obfuscate header and footer contents + * to make it difficult to free a block without having first succesfully + * malloc'ed one. To obtain the ability to turn off obfuscation using the + * -DWEAK_MAGIC compilation flag, you should not call this function directly + * but rather use the preprocessor symbol MAGIC where the magic number is + * required. + */ +sf_header sf_magic(); + +/* Define WEAK_MAGIC during compilation to use MAGIC of 0x0 for debugging purposes. */ +#ifndef WEAK_MAGIC +#define MAGIC (sf_magic()) +#else +#define MAGIC ((sf_header)0x0) +#endif + +/* + * Display the contents of the heap in a human-readable form. + */ +void sf_show_block(sf_block *bp); +void sf_show_blocks(); +void sf_show_free_list(int index); +void sf_show_free_lists(); +void sf_show_quick_list(int index); +void sf_show_quick_lists(); +void sf_show_heap(); + +#endif diff --git a/hw3/lib/sfutil.o b/hw3/lib/sfutil.o new file mode 100644 index 0000000000000000000000000000000000000000..440e5daffb59ce7568f0660006372e983acb5d15 GIT binary patch literal 10864 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 S&aeGWOiU=YxVYbX`~L#kA9uq5 literal 0 HcmV?d00001 diff --git a/hw3/src/main.c b/hw3/src/main.c new file mode 100644 index 0000000..2fc0614 --- /dev/null +++ b/hw3/src/main.c @@ -0,0 +1,14 @@ +#include +#include "sfmm.h" + +int main(int argc, char const *argv[]) { + double* ptr = sf_malloc(sizeof(double)); + + *ptr = 320320320e-320; + + printf("%f\n", *ptr); + + sf_free(ptr); + + return EXIT_SUCCESS; +} diff --git a/hw3/src/sfmm.c b/hw3/src/sfmm.c new file mode 100644 index 0000000..a462016 --- /dev/null +++ b/hw3/src/sfmm.c @@ -0,0 +1,34 @@ +/** + * Do not submit your assignment with a main function in this file. + * If you submit with a main function in this file, you will get a zero. + */ +#include +#include +#include +#include "debug.h" +#include "sfmm.h" + +void *sf_malloc(sf_size_t size) { + // TO BE IMPLEMENTED + abort(); +} + +void sf_free(void *pp) { + // TO BE IMPLEMENTED + abort(); +} + +void *sf_realloc(void *pp, sf_size_t rsize) { + // TO BE IMPLEMENTED + abort(); +} + +double sf_internal_fragmentation() { + // TO BE IMPLEMENTED + abort(); +} + +double sf_peak_utilization() { + // TO BE IMPLEMENTED + abort(); +} diff --git a/hw3/tests/sfmm_tests.c b/hw3/tests/sfmm_tests.c new file mode 100644 index 0000000..ed3b134 --- /dev/null +++ b/hw3/tests/sfmm_tests.c @@ -0,0 +1,260 @@ +#include +#include +#include +#include "debug.h" +#include "sfmm.h" +#define TEST_TIMEOUT 15 + +/* + * Assert the total number of free blocks of a specified size. + * If size == 0, then assert the total number of all free blocks. + */ +void assert_free_block_count(size_t size, int count) { + int cnt = 0; + for(int i = 0; i < NUM_FREE_LISTS; i++) { + sf_block *bp = sf_free_list_heads[i].body.links.next; + while(bp != &sf_free_list_heads[i]) { + if(size == 0 || size == ((bp->header ^ MAGIC) & 0xfffffff0)) + cnt++; + bp = bp->body.links.next; + } + } + if(size == 0) { + cr_assert_eq(cnt, count, "Wrong number of free blocks (exp=%d, found=%d)", + count, cnt); + } else { + cr_assert_eq(cnt, count, "Wrong number of free blocks of size %ld (exp=%d, found=%d)", + size, count, cnt); + } +} + +/* + * Assert the total number of quick list blocks of a specified size. + * If size == 0, then assert the total number of all quick list blocks. + */ +void assert_quick_list_block_count(size_t size, int count) { + int cnt = 0; + for(int i = 0; i < NUM_QUICK_LISTS; i++) { + sf_block *bp = sf_quick_lists[i].first; + while(bp != NULL) { + if(size == 0 || size == ((bp->header ^ MAGIC) & 0xfffffff0)) { + cnt++; + if(size != 0) { + // Check that the block is in the correct list for its size. + int index = (size - 32) >> 4; + cr_assert_eq(index, i, "Block %p (size %ld) is in wrong quick list for its size " + "(expected %d, was %d)", + &bp->header, (bp->header ^ MAGIC) & 0xfffffff0, index, i); + } + } + bp = bp->body.links.next; + } + } + if(size == 0) { + cr_assert_eq(cnt, count, "Wrong number of quick list blocks (exp=%d, found=%d)", + count, cnt); + } else { + cr_assert_eq(cnt, count, "Wrong number of quick list blocks of size %ld (exp=%d, found=%d)", + size, count, cnt); + } +} + +Test(sfmm_basecode_suite, malloc_an_int, .timeout = TEST_TIMEOUT) { + sf_errno = 0; + size_t sz = sizeof(int); + int *x = sf_malloc(sz); + + cr_assert_not_null(x, "x is NULL!"); + + *x = 4; + + cr_assert(*x == 4, "sf_malloc failed to give proper space for an int!"); + sf_block *bp = (sf_block *)((char *)x - 16); + cr_assert((bp->header >> 32) & 0xffffffff, + "Malloc'ed block payload size (%ld) not what was expected (%ld)!", + (bp->header >> 32) & 0xffffffff, sz); + + assert_quick_list_block_count(0, 0); + assert_free_block_count(0, 1); + assert_free_block_count(944, 1); + + cr_assert(sf_errno == 0, "sf_errno is not zero!"); + cr_assert(sf_mem_start() + PAGE_SZ == sf_mem_end(), "Allocated more than necessary!"); +} + +Test(sfmm_basecode_suite, malloc_four_pages, .timeout = TEST_TIMEOUT) { + sf_errno = 0; + + void *x = sf_malloc(4032); + cr_assert_not_null(x, "x is NULL!"); + assert_quick_list_block_count(0, 0); + assert_free_block_count(0, 0); + cr_assert(sf_errno == 0, "sf_errno is not 0!"); +} + +Test(sfmm_basecode_suite, malloc_too_large, .timeout = TEST_TIMEOUT) { + sf_errno = 0; + void *x = sf_malloc(98304); + + cr_assert_null(x, "x is not NULL!"); + assert_quick_list_block_count(0, 0); + assert_free_block_count(0, 1); + assert_free_block_count(24528, 1); + cr_assert(sf_errno == ENOMEM, "sf_errno is not ENOMEM!"); +} + +Test(sfmm_basecode_suite, free_quick, .timeout = TEST_TIMEOUT) { + sf_errno = 0; + size_t sz_x = 8, sz_y = 32, sz_z = 1; + /* void *x = */ sf_malloc(sz_x); + void *y = sf_malloc(sz_y); + /* void *z = */ sf_malloc(sz_z); + + sf_free(y); + + assert_quick_list_block_count(0, 1); + assert_quick_list_block_count(48, 1); + assert_free_block_count(0, 1); + assert_free_block_count(864, 1); + cr_assert(sf_errno == 0, "sf_errno is not zero!"); +} + +Test(sfmm_basecode_suite, free_no_coalesce, .timeout = TEST_TIMEOUT) { + sf_errno = 0; + size_t sz_x = 8, sz_y = 200, sz_z = 1; + /* void *x = */ sf_malloc(sz_x); + void *y = sf_malloc(sz_y); + /* void *z = */ sf_malloc(sz_z); + + sf_free(y); + + assert_quick_list_block_count(0, 0); + assert_free_block_count(0, 2); + assert_free_block_count(224, 1); + assert_free_block_count(688, 1); + + cr_assert(sf_errno == 0, "sf_errno is not zero!"); +} + +Test(sfmm_basecode_suite, free_coalesce, .timeout = TEST_TIMEOUT) { + sf_errno = 0; + size_t sz_w = 8, sz_x = 200, sz_y = 300, sz_z = 4; + /* void *w = */ sf_malloc(sz_w); + void *x = sf_malloc(sz_x); + void *y = sf_malloc(sz_y); + /* void *z = */ sf_malloc(sz_z); + + sf_free(y); + sf_free(x); + + assert_quick_list_block_count(0, 0); + assert_free_block_count(0, 2); + assert_free_block_count(368, 1); + assert_free_block_count(544, 1); + + cr_assert(sf_errno == 0, "sf_errno is not zero!"); +} + +Test(sfmm_basecode_suite, freelist, .timeout = TEST_TIMEOUT) { + size_t sz_u = 200, sz_v = 150, sz_w = 50, sz_x = 150, sz_y = 200, sz_z = 250; + void *u = sf_malloc(sz_u); + /* void *v = */ sf_malloc(sz_v); + void *w = sf_malloc(sz_w); + /* void *x = */ sf_malloc(sz_x); + void *y = sf_malloc(sz_y); + /* void *z = */ sf_malloc(sz_z); + + sf_free(u); + sf_free(w); + sf_free(y); + + assert_quick_list_block_count(0, 1); + assert_free_block_count(0, 3); + assert_free_block_count(224, 2); + assert_free_block_count(848, 1); + + // First block in list should be the most recently freed block not in quick list. + int i = 3; + sf_block *bp = sf_free_list_heads[i].body.links.next; + cr_assert_eq(&bp->header, (char *)y - 8, + "Wrong first block in free list %d: (found=%p, exp=%p)", + i, &bp->header, (char *)y - 8); +} + +Test(sfmm_basecode_suite, realloc_larger_block, .timeout = TEST_TIMEOUT) { + size_t sz_x = sizeof(int), sz_y = 10, sz_x1 = sizeof(int) * 20; + void *x = sf_malloc(sz_x); + /* void *y = */ sf_malloc(sz_y); + x = sf_realloc(x, sz_x1); + + cr_assert_not_null(x, "x is NULL!"); + sf_block *bp = (sf_block *)((char *)x - 16); + cr_assert((bp->header ^ MAGIC) & THIS_BLOCK_ALLOCATED, "Allocated bit is not set!"); + cr_assert(((bp->header ^ MAGIC) & 0xfffffff0) == 96, + "Realloc'ed block size (%ld) not what was expected (%ld)!", + (bp->header ^ MAGIC) & 0xfffffff0, 96); + cr_assert((((bp->header ^ MAGIC) >> 32) & 0xffffffff) == sz_x1, + "Realloc'ed block payload size (%ld) not what was expected (%ld)!", + (((bp->header ^ MAGIC) >> 32) & 0xffffffff), sz_x1); + + assert_quick_list_block_count(0, 1); + assert_quick_list_block_count(32, 1); + assert_free_block_count(0, 1); + assert_free_block_count(816, 1); +} + +Test(sfmm_basecode_suite, realloc_smaller_block_splinter, .timeout = TEST_TIMEOUT) { + size_t sz_x = sizeof(int) * 20, sz_y = sizeof(int) * 16; + void *x = sf_malloc(sz_x); + void *y = sf_realloc(x, sz_y); + + cr_assert_not_null(y, "y is NULL!"); + cr_assert(x == y, "Payload addresses are different!"); + + sf_block *bp = (sf_block *)((char *)x - 16); + cr_assert((bp->header ^ MAGIC) & THIS_BLOCK_ALLOCATED, "Allocated bit is not set!"); + cr_assert(((bp->header ^ MAGIC) & 0xfffffff0) == 96, + "Realloc'ed block size (%ld) not what was expected (%ld)!", + (bp->header ^ MAGIC) & 0xfffffff0, 96); + cr_assert((((bp->header ^ MAGIC) >> 32) & 0xffffffff) == sz_y, + "Realloc'ed block payload size (%ld) not what was expected (%ld)!", + (((bp->header ^ MAGIC) >> 32) & 0xffffffff), sz_y); + + // There should be only one free block. + assert_quick_list_block_count(0, 0); + assert_free_block_count(0, 1); + assert_free_block_count(880, 1); +} + +Test(sfmm_basecode_suite, realloc_smaller_block_free_block, .timeout = TEST_TIMEOUT) { + size_t sz_x = sizeof(double) * 8, sz_y = sizeof(int); + void *x = sf_malloc(sz_x); + void *y = sf_realloc(x, sz_y); + + cr_assert_not_null(y, "y is NULL!"); + + sf_block *bp = (sf_block *)((char *)x - 16); + cr_assert((bp->header ^ MAGIC) & THIS_BLOCK_ALLOCATED, "Allocated bit is not set!"); + cr_assert(((bp->header ^ MAGIC) & 0xfffffff0) == 32, + "Realloc'ed block size (%ld) not what was expected (%ld)!", + (bp->header ^ MAGIC) & 0xfffffff0, 32); + cr_assert((((bp->header ^ MAGIC) >> 32) & 0xffffffff) == sz_y, + "Realloc'ed block payload size (%ld) not what was expected (%ld)!", + (((bp->header ^ MAGIC) >> 32) & 0xffffffff), sz_y); + + // After realloc'ing x, we can return a block of size 48 + // to the freelist. This block will go into the main freelist and be coalesced. + // Note that we don't put split blocks into the quick lists because their sizes are not sizes + // that were requested by the client, so they are not very likely to satisfy a new request. + assert_quick_list_block_count(0, 0); + assert_free_block_count(0, 1); + assert_free_block_count(944, 1); +} + +//############################################ +//STUDENT UNIT TESTS SHOULD BE WRITTEN BELOW +//DO NOT DELETE THESE COMMENTS +//############################################ + +//Test(sfmm_student_suite, student_test_1, .timeout = TEST_TIMEOUT) { +//} From 7ae03a1c2737e464c01b8ac447591309b8b47d82 Mon Sep 17 00:00:00 2001 From: Gene Stark Date: Tue, 8 Mar 2022 15:59:13 -0500 Subject: [PATCH 2/5] Remove the -DWEAK_MAGIC preprocessor conditional and add function sf_set_magic() to set the magic number for debugging. --- hw3/include/sfmm.h | 22 +++++++++++++--------- hw3/lib/sfutil.o | Bin 10864 -> 11048 bytes 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/hw3/include/sfmm.h b/hw3/include/sfmm.h index f62950b..8429eb0 100644 --- a/hw3/include/sfmm.h +++ b/hw3/include/sfmm.h @@ -311,19 +311,23 @@ void *sf_mem_grow(); /* * @return The "magic number" used to obfuscate header and footer contents * to make it difficult to free a block without having first succesfully - * malloc'ed one. To obtain the ability to turn off obfuscation using the - * -DWEAK_MAGIC compilation flag, you should not call this function directly - * but rather use the preprocessor symbol MAGIC where the magic number is - * required. + * malloc'ed one. */ sf_header sf_magic(); -/* Define WEAK_MAGIC during compilation to use MAGIC of 0x0 for debugging purposes. */ -#ifndef WEAK_MAGIC #define MAGIC (sf_magic()) -#else -#define MAGIC ((sf_header)0x0) -#endif + +/* + * Set the "magic number" used to obfuscate header and footer contents. + * Setting the magic number to zero essentially turns off obfuscation, which will + * to make your life easier during debugging. This function will be replaced + * by a dummy version during grading, so be sure to test your code without calling + * this function. + * + * @param magic The value to set the magic number to. Setting to 0x0 disables + * obfuscation. + */ +void sf_set_magic(sf_header magic); /* * Display the contents of the heap in a human-readable form. diff --git a/hw3/lib/sfutil.o b/hw3/lib/sfutil.o index 440e5daffb59ce7568f0660006372e983acb5d15..7eca98cfd76001b2f96fc74523736005981b2d9b 100644 GIT binary patch literal 11048 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 Ue3$3fzH}j45yEyZ?zi6lKR<7lxBvhE delta 3242 zcmZ{me@IBM>9Jcsjn zpZEJb&wJkc-gD}~`RzyIp82ZrnwWr$2#8rYDtg7Ekn|Km)DsYG*`!D2c?=_aZ~on$ z;)c5Vb;-t_T|G~9_aq1Is;{eGpD1gtLk!1OjzOm{Bu1gs7lr41ak%6Qc@_=$(N`nl z;Ppqv7D)K3#gmXiKMZ|H&cO)!Z{fT@3g`UcWo3q8gy2tqg=oo^25yPweF(^Q;T1H5 z(J$1aQElCfy_%nJ@Mj^tN{SbuD=5Xw~ah2(fpd`QSX2GKbjxXJfigr@Q!&s#%bs(d<^CaFW!NX*|DOt zLKMK1l%fKTqpwrGMUm|wLQ?EhzEkloTywguX1o~|u%0%EnbLf~W$wd}GNl+){te|Pl>d%=@&;3;N-FRo`^~{? zEo>~RjD-*=mS%(|pgF5u5963|CwX&##S~$zy#lYPn2(kJO8J}0=fYI66jkKS1`P?bHdr5P;@iqU5#q;bJEe=;o0+}ye=6>xm_Zs6= zgT1G3GM!@N_9_)D!v{1PF2u{`wHDv>zolu=6KKgOK^QNxHYUWI+y>)eDY}&(CZB$b zDe$(ljFWPX-ol@_C|_amTxSMinB{Lai*JjdJ_MYv++>{hRi!yC5bvuArb?ygP=0`X z<}g#>^^7o1$}PIDF&E`CES~Fp$l^;-$9`4cTikk8{I`3X39Vog41L}?mmn7=BGN3> zqt1q_VId;LCO8_A>D?|0Pcu%f+UNRy7tMn#p11lc3`V6m0psZ3g%tWPC~tC}#q&;= z80R`(2$V^4wLZt49VOtNGAXvfPpH2Gx-fFLOXO1&lRltF?X3^`MIK_a_-|{7ag(k8 z1k>SNd`?-~XW1yN;d!0q7pBIu{J}W=80~Gbr25K-g_tzg>EoX&=NX$IRW6fT*(hba ztTU!Gr*-2QJ0TsD;&GZQdPzU?3RB?v?=uB{x=b@3WHrw*&f|0QFbIt*;VW5Uad@FT zkX)-{oV&V}aq4bHcefeFvHlJiESKgU7Q^>X9|S67@_9W<+4)iO0h`6Uz6{54)-)UC znsba(J=b+T*Qp-!FP4k1z;Y0kG83VnF`Bc-dd5jJhXT+xYVO?m_c6}1JmSLpEDpa{ z1~U6~jI)NrY%V{Zh8T}xP4@mg=A!d9i|0D;S$u=q1Q8~5!9{423qjACe$fvLYouv^ zRL-IX88t%hU=m_gGGl*8*6P<{kG@W8h_=R3#}L? P@u|1Udg@lH;duVPMcqr- From 216cc7f1682c292392d0c88eb2428c4efa1c4602 Mon Sep 17 00:00:00 2001 From: Gene Stark Date: Sat, 12 Mar 2022 02:10:51 -0500 Subject: [PATCH 3/5] Correct tests for actual assignment configuration. --- hw3/tests/sfmm_tests.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw3/tests/sfmm_tests.c b/hw3/tests/sfmm_tests.c index ed3b134..dc8b6e6 100644 --- a/hw3/tests/sfmm_tests.c +++ b/hw3/tests/sfmm_tests.c @@ -130,8 +130,8 @@ Test(sfmm_basecode_suite, free_no_coalesce, .timeout = TEST_TIMEOUT) { assert_quick_list_block_count(0, 0); assert_free_block_count(0, 2); - assert_free_block_count(224, 1); - assert_free_block_count(688, 1); + assert_free_block_count(208, 1); + assert_free_block_count(704, 1); cr_assert(sf_errno == 0, "sf_errno is not zero!"); } @@ -149,8 +149,8 @@ Test(sfmm_basecode_suite, free_coalesce, .timeout = TEST_TIMEOUT) { assert_quick_list_block_count(0, 0); assert_free_block_count(0, 2); - assert_free_block_count(368, 1); - assert_free_block_count(544, 1); + assert_free_block_count(384, 1); + assert_free_block_count(528, 1); cr_assert(sf_errno == 0, "sf_errno is not zero!"); } @@ -170,8 +170,8 @@ Test(sfmm_basecode_suite, freelist, .timeout = TEST_TIMEOUT) { assert_quick_list_block_count(0, 1); assert_free_block_count(0, 3); - assert_free_block_count(224, 2); - assert_free_block_count(848, 1); + assert_free_block_count(208, 2); + assert_free_block_count(928, 1); // First block in list should be the most recently freed block not in quick list. int i = 3; From 45c0fdbb02a151c4a0f711c2a8f945001c612b3c Mon Sep 17 00:00:00 2001 From: Gene Stark Date: Thu, 17 Mar 2022 11:55:05 -0400 Subject: [PATCH 4/5] Remove an incorrect "(aligned)" indication. --- hw3/include/sfmm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw3/include/sfmm.h b/hw3/include/sfmm.h index 8429eb0..200954c 100644 --- a/hw3/include/sfmm.h +++ b/hw3/include/sfmm.h @@ -85,7 +85,7 @@ | unused | block_size | unused | alloc |prv alloc|in qklst | | (0) |(4 LSB's implicitly 0)| (0) | (0) | (0/1) | (0) | | (32 bits) | (28 bits) | 1 bit | 1 bit | 1 bit | 1 bit | - +------------------------------------------------------------+--------+---------+---------+ <- (aligned) + +------------------------------------------------------------+--------+---------+---------+ NOTE: For a free block, footer contents must always be identical to header contents. NOTE: The actual stored footer is obfuscated by bitwise XOR'ing with MAGIC. From d50e72a3295a3fd60068083649e2f7792f1f89fc Mon Sep 17 00:00:00 2001 From: Gene Stark Date: Sun, 20 Mar 2022 05:07:04 -0400 Subject: [PATCH 5/5] Correct malloc_an_int test. --- hw3/tests/sfmm_tests.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw3/tests/sfmm_tests.c b/hw3/tests/sfmm_tests.c index dc8b6e6..2cec983 100644 --- a/hw3/tests/sfmm_tests.c +++ b/hw3/tests/sfmm_tests.c @@ -70,9 +70,9 @@ Test(sfmm_basecode_suite, malloc_an_int, .timeout = TEST_TIMEOUT) { cr_assert(*x == 4, "sf_malloc failed to give proper space for an int!"); sf_block *bp = (sf_block *)((char *)x - 16); - cr_assert((bp->header >> 32) & 0xffffffff, + cr_assert((((bp->header ^ MAGIC) >> 32) & 0xffffffff) == sz, "Malloc'ed block payload size (%ld) not what was expected (%ld)!", - (bp->header >> 32) & 0xffffffff, sz); + (((bp->header ^ MAGIC) >> 32) & 0xffffffff), sz); assert_quick_list_block_count(0, 0); assert_free_block_count(0, 1);