diff --git a/LICENSE b/LICENSE index 0b8ae76..5ecebf3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) YEAR by AUTHOR EMAIL +Copyright (C) 2022 by JohnBreaux@my.unt.edu Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..88ef99b --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ + +CC = g++ +CFLAGS = + +OBJECTS := %.o list.o +EXECUTE := main.out + +.PHONY: all clean + +all: $(EXECUTE) + +clean: + rm $(EXECUTE) + +%.out: $(OBJECTS) + $(CC) $(CFLAGS) -o $@ $^ +%.o: %.cpp + $(CC) $(CFLAGS) -c $< diff --git a/list.cpp b/list.cpp new file mode 100644 index 0000000..668a364 --- /dev/null +++ b/list.cpp @@ -0,0 +1,75 @@ +#include "list.hpp" +#include + +// pop the last block +block* list_unlink (list* l) { + // we need a list + if (!l) return nullptr; + block* b = l->end; + // can't unlink from an empty list + if (!b) return nullptr; + // remove b + if (b->prev) { + // b is not the only element of the list + // chop of the tail + l->end = b->prev; + // bandage the wound + l->end->next = nullptr; + // wrap the severed end + b->prev = nullptr; + } else { + // b is the only element of the list + l->start = nullptr; + l->end = nullptr; + } + // if we get here, we've removed element b from the list + l->length--; + return b; +} + +// push a block +void list_link (list* l, block* b) { + // can't link to a nonexistent list + if (!l) return; + // can't append nullptr; + if (!b) return; + if (l->start == nullptr) { + // b is the only element of the list + l->start = b; + l->end = b; + } else { + // make b the next element of the list + b->prev = l->end; + l->end->next = b; + // terminate the list + b->next = nullptr; + // update end + l->end = b; + } + l->length++; +} + +// push a lot of blocks +// this is slow, but the pointer arithmetic *has* to be done for each block +// so it's not really as slow as it would be, were that not the case. +void list_init (list *l, block *m, int size) { + // move each block of memory into the freelist, by linking it to the end + for (int b = 0; b < size; b++) { + list_link(l, &(m[b])); + } +} + +// YAML-like, because I like YAML +void list_print(list *l) { + if (!l) return; + std::printf("l_%p:\n - start: '%p',\n - end: '%p',\n - length: '%d',\n - blocks:",l,l->start,l->end,l->length); + block* b = l->start; + if (b) { + do { + std::printf("\n - b_%p: [prev: '%p', next: '%p', data: '%d']",b,b->prev,b->next,b->data); + } while (b = b->next); + std::printf("\n"); + } else { + std::printf(" []\n"); + } +} \ No newline at end of file diff --git a/list.hpp b/list.hpp new file mode 100644 index 0000000..4222b8a --- /dev/null +++ b/list.hpp @@ -0,0 +1,23 @@ + +struct block { + block *prev; + block *next; + // data goes here + int data; +}; + +struct list { + block *start; + block *end; + int length; +}; + +// list operations: +// list_unlink: unlinks the last block in the list, and returns a pointer to it +block *list_unlink (list *l); +// list_link: links the block b onto the end of the list +void list_link (list *l, block *b); +// list_init: links an array of blocks onto the end of a list +void list_init (list *l, block *m, int size); +// list_print: prints a list +void list_print (list *l); \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..33f5773 --- /dev/null +++ b/main.cpp @@ -0,0 +1,29 @@ +#include +#include +#include "list.hpp" + +#define N 0x8 + +// Create all of memory +block memory[N] = {0}; +// create the three lists +list freelist = {0}, list1 = {0}, list2 = {0}; + +int main (int argc, char* argv[]) { + // initialize the freelist + list_init(&freelist, memory, N); + + // print the list + list_print(&freelist); + list_print(&list1); + + // move a block + block* b; + while (b = list_unlink(&freelist)) { + list_link(&list1, b); + // print the list + std::printf("\n"); + list_print(&freelist); + list_print(&list1); + } +}