Commit e7361eaf authored by Lindsay Knupp's avatar Lindsay Knupp
Browse files

Initial upload

parent 2cd8454a
This diff is collapsed.
CC = gcc -I ./include
CFLAGS = -std=gnu99 -Wall -g #-DDEBUG
INC = ./include
SRC = ./src
OBJ = ./obj
DOC = ./doc
BIN = ./bin
vpath %.h ./include
vpath %.c ./src
EXECS = dlisttest alloc-dlist_test memory-test memory-test2 memory-test3
all: $(EXECS)
doc:
doxygen
$(OBJ)/dnode.o: dnode.h dnode.c
$(CC) $(CFLAGS) -c $(SRC)/dnode.c -o $(OBJ)/dnode.o
$(OBJ)/dlist.o: dlist.h dlist.c dnode.h
$(CC) $(CFLAGS) -c $(SRC)/dlist.c -o $(OBJ)/dlist.o
$(OBJ)/allocator.o: allocator.h allocator.c dlist.h dnode.h
$(CC) $(CFLAGS) -c $(SRC)/allocator.c -o $(OBJ)/allocator.o
dlisttest: $(SRC)/dlisttest.c $(OBJ)/dnode.o $(OBJ)/dlist.o
$(CC) $(CFLAGS) $(OBJ)/dnode.o $(OBJ)/dlist.o $(SRC)/dlisttest.c -o $(BIN)/dlisttest
alloc-dlist_test: $(SRC)/alloc-dlist_test.c $(OBJ)/dnode.o $(OBJ)/dlist.o
$(CC) $(CFLAGS) $(OBJ)/dnode.o $(OBJ)/dlist.o $(SRC)/alloc-dlist_test.c -o $(BIN)/alloc-dlist_test
memory-test: $(SRC)/memory-test.c $(OBJ)/dnode.o $(OBJ)/dlist.o $(OBJ)/allocator.o
$(CC) $(CFLAGS) $(OBJ)/dnode.o $(OBJ)/dlist.o $(OBJ)/allocator.o $(SRC)/memory-test.c -o $(BIN)/memory-test
memory-test2: $(SRC)/memory-test2.c $(OBJ)/dnode.o $(OBJ)/dlist.o $(OBJ)/allocator.o
$(CC) $(CFLAGS) $(OBJ)/dnode.o $(OBJ)/dlist.o $(OBJ)/allocator.o $(SRC)/memory-test2.c -o $(BIN)/memory-test2
memory-test3: $(SRC)/memory-test3.c $(OBJ)/dnode.o $(OBJ)/dlist.o $(OBJ)/allocator.o
$(CC) $(CFLAGS) $(OBJ)/dnode.o $(OBJ)/dlist.o $(OBJ)/allocator.o $(SRC)/memory-test3.c -o $(BIN)/memory-test3
.PHONY: clean
clean:
/bin/rm -rf $(BIN)/* $(OBJ)/* core* *~
Lindsay Knupp
11/09/21
Lab 7 - designAPI.txt
In order to deal with various policies for contiguous memory allocation, my allocate function requires a size and a allocation type. The size refers to the block of memory that you are trying to request and the allocation type refers to the type of memory allocation policy that you want to implement. 0 specifies First-Fit, 1 specifies Best-Fit, and 2 specifies Worst-Fit.
/**
* Lindsay Knupp
* 1026/21
* Lab 7 - allocator. h
*/
#ifndef _ALLOCATOR_H_
#define _ALLOCATOR_H_
struct dlist *free_list;
struct dlist *allocated_list;
/**
* Create and initialize two linked lists, one for
* free memory and one for allocated memory.
* @param size number of bytes to allocate contiguous memory
* @return 0 if successful, -1 if any error condition is found
*/
int allocator_init(size_t size);
/**
* Allocate a block of memory from the free memory
* list. Node gets placed into allocated list.
* @param size number of bytes to allocate
* @param alloc_type to specify allocation procedure
* @return NULL if any error condition is found
*/
void *allocate(size_t size, int alloc_type);
/**
* Deallocate a block of memory from the allocated
* memory list.
* @param ptr of corresponding node in allocated
* list
* @return 0 if successful, -1 if any error condition is found
*/
int deallocate(void * ptr);
#endif /* _ALLOCATOR_H_ */
/*
* Copyright (c) 2012 Bucknell University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: L. Felipe Perrone (perrone@bucknell.edu)
*/
#ifndef _DLIST_H_
#define _DLIST_H_
#include <stdint.h>
#include <stdbool.h>
#include "dnode.h"
/**
* Doubly-linked list.
*/
struct dlist {
struct dnode *front;
struct dnode *back;
struct dnode *iter;
uint32_t counter;
};
/**
* Allocates new dlist dynamically.
*
* @return pointer to the list.
*/
struct dlist *dlist_create();
/**
* Deallocates all nodes in a dlist and the data they point to, but
* preserve the list.
*
* @param l pointer to the list (non-NULL)
*/
void dlist_destroy(struct dlist *l);
/**
* Deallocates all nodes in a dlist and the data they point to; deallocate
* the list itself as well. This is the inverse of dlist_create.
* @param l pointer to the list (non-NULL)
*/
void dlist_obliterate(struct dlist *l);
/**
* Inserts new node in dlist before the first node.
*
* @param l pointer to the list (non_NULL)
* @param ptr pointer to generic data to store in new list node
* @param size of data
*/
void dlist_add_front(struct dlist *l, void *ptr, size_t size);
/**
* Inserts new node in dlist after the last node.
*
* @param l pointer to the list (non-NULL)
* @param ptr pointer to generic data to store in new list node
* @param size of data
*/
void dlist_add_back(struct dlist *l, void *ptr, size_t size);
/**
* Remove the first node and return pointer to the data. It is the
* responsibility of the caller to free the memory pointed by the return
* value.
*
* @param l pointer to the list (non-NULL)
* @return pointer to data stored in front node
*/
struct dnode *dlist_remove_front(struct dlist *l);
/**
* Remove the last node and return pointer to the data. It is the
* responsibility of the caller to free the memory pointed by the return
* value.
*
* @param l pointer to the list (non-NULL)
* @return pointer to data stored in back node
*/
struct dnode *dlist_remove_back(struct dlist *l);
/**
* Seek out the node that contains a pointer and remove from list returning
* the pointer to the data. It is the
* responsibility of the caller to free the memory pointed by the return
* value.
*
* @param l pointer to the list (non-NULL)
* @param ptr pointer to the data item been sought
* @return pointer to data stored in the node that was found node
*/
struct dnode *dlist_find_remove(struct dlist *l, void *ptr);
/**
* Returns the number of elements in the list (nodes).
*
* @param l pointer to the list (non-NULL)
*/
uint32_t dlist_num_elems(struct dlist *l);
/**
* Initialize iterator for traversing a dlist forwards.
*/
struct dnode *dlist_iter_begin(struct dlist *l);
/**
* Returns current item and advances iterator to next item in list.
*/
struct dnode *dlist_iter_next(struct dlist *l);
/**
* Check if iterator has reached the end of the list.
*/
bool dlist_iter_has_next(struct dlist *l);
/**
* Initialize iterator for traversing a dlist backwards.
*/
struct dnode *dlist_iter_end(struct dlist *l);
/**
* Returns current item and advances iterator to previous item in list.
*/
struct dnode *dlist_iter_prev(struct dlist *l);
/**
* Check if iterator has reached the start of the list.
*/
bool dlist_iter_has_prev(struct dlist *l);
/**
* Prints contents of the list
*/
void dlist_print(struct dlist *l);
#endif /* _DLIST_H_ */
/*
* Copyright (c) 2012 Bucknell University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: L. Felipe Perrone (perrone@bucknell.edu)
*/
#ifndef _DNODE_H_
#define _DNODE_H_
/**
* Node in a doubly-linked list.
*/
struct dnode {
struct dnode *prev;
struct dnode *next;
void *data;
size_t size;
};
/**
* Allocates a new dnode leaving the pointer to data as null.
*
* @return pointer to a new dnode
*/
struct dnode *dnode_create();
/**
* Sets the pointer to data with the value passed in.
*
* @param n pointer to the dnone
* @param ptr pointer to a generic data type to store in dnode
*/
void dnode_setdata(struct dnode *n, void *ptr, size_t size);
/**
* Deallocates a dnode but not the data it points to. The caller must take
* the responsibility of deallocating the data later on.
*
* @param n pointer to the dnode
* @return pointer to the generic data type associated with node
*/
void *dnode_destroy(struct dnode *n);
/**
* Deallocates a dnode and also the data it points to.
*
* @param ptr pointer to the dnode
*/
void dnode_obliterate(struct dnode *n);
void dnode_print(struct dnode *n);
#endif /* _DNODE_H_ */
/*
* Copyright (c) 2012 Bucknell University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: L. Felipe Perrone (perrone@bucknell.edu)
*/
#ifndef _READLINE_H_
#define _READLINE_H_
/**
* This function implements a safer way to read strings from a C stream
* (that is, safer than scanf and gets).
*
* The function causes characters to be read one at a time and placed into
* an input buffer that is automatically enlarged to fit the entire string.
* The returned value is a pointer to a dynamically allocated area of
* memory. Note that the caller of this function becomes responsible for
* disposing of the memory allocated for the string read in.
*
* @parm stream Pointer to an open C stream (such as stdin)
* @return A pointer to the line read from source on success or NULL on failure.
*/
extern char*
readline(FILE* stream);
#endif /* _READLINE_H_ */
/*
* Copyright (c) 2014 Bucknell University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: L. Felipe Perrone (perrone@bucknell.edu)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dlist.h"
int main(int argc, char *argv[]) {
struct dlist *mylist = dlist_create();
printf("dlisttest running...\n");
char *str1 = malloc(20);
strncpy(str1, "animal", 20);
char *str2 = malloc(20);
strncpy(str2, "barnacle", 20);
char *str3 = malloc(20);
strncpy(str3, "carnage", 20);
char *str4 = malloc(20);
strncpy(str4, "demented", 20);
char *str5 = malloc(20);
strncpy(str5, "error", 20);
printf("\ntesting dlist_add_back\n");
dlist_add_back(mylist, str1,strlen(str1));
dlist_add_back(mylist, str2,strlen(str2));
dlist_add_back(mylist, str3,strlen(str3));
dlist_add_back(mylist, str4,strlen(str4));
dlist_add_back(mylist, str5,strlen(str5));
dlist_print(mylist);
dlist_destroy(mylist);
printf("\nlist destroyed\n");
dlist_print(mylist);
printf("\ntraversal of empty list completed\n");
str1 = malloc(20);
strncpy(str1, "folly", 20);
str2 = malloc(20);
strncpy(str2, "gunk", 20);
str3 = malloc(20);
strncpy(str3, "hospital", 20);
str4 = malloc(20);
strncpy(str4, "ignorant", 20);
str5 = malloc(20);
strncpy(str5, "jelly", 20);
printf("\ntesting dlist_add_front\n");
dlist_add_front(mylist, str1,strlen(str1));
dlist_add_front(mylist, str2,strlen(str2));
dlist_add_front(mylist, str3,strlen(str3));
dlist_add_front(mylist, str4,strlen(str4));
dlist_add_front(mylist, str5,strlen(str5));
dlist_print(mylist);
printf("\ntesting remove front\n");
printf("list length= %d\n\n", dlist_num_elems(mylist));
dlist_print(mylist);
printf("\ntesting remove back\n");
printf("list length= %d\n\n", dlist_num_elems(mylist));
dlist_print(mylist);
printf("\ntesting find_remove\n");
printf("contents of the list\n");
dlist_print(mylist);
}
/**
* Lindsay Knupp
* 10/26/21
* Lab 7 - allocator.c
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include "allocator.h"
#include "dlist.h"
int allocator_init(size_t size){
// Initalize free list
void *free_list_p = malloc(size);
free_list = dlist_create();
dlist_add_front(free_list,free_list_p,size);
// Initalize allocated list
allocated_list = dlist_create();
allocated_list->front = NULL;
allocated_list->back = NULL;
// Check if lists successfully created
if (!(free_list || allocated_list) == 1) {
return -1;
}
return 0;
}
void *allocate(size_t size, int alloc_type){
struct dnode *curr_data;
void *ptr = NULL;
int counter = 0;
// First-fit policy
if (alloc_type == 0){
for (curr_data = dlist_iter_begin(free_list); curr_data != NULL; curr_data = dlist_iter_next(free_list)) {
counter ++;
if(curr_data->size >= size){
ptr = curr_data->data;
dlist_add_back(allocated_list,ptr,size);
curr_data->size = curr_data->size - size;
curr_data->data = curr_data->data + size;
break;
}
if ((counter == dlist_num_elems(free_list)) && (ptr == NULL)) {
printf("No space to allocate this\n");
return NULL;
}
}
}
// Best-fit policy
if (alloc_type == 1){
size_t min = RAND_MAX;
struct dnode *smallest_block = NULL;
for (curr_data = dlist_iter_begin(free_list); curr_data != NULL; curr_data = dlist_iter_next(free_list)) {
if( (curr_data->size >= size) && (curr_data->size - size < min) ){
smallest_block = curr_data;
min = curr_data->size - size;
}
}
if (min == RAND_MAX) {
printf("No space to allocate this\n");
return NULL;
}
ptr = smallest_block->data;
dlist_add_back(allocated_list,ptr,size);
smallest_block->size = smallest_block->size - size;
smallest_block->data = smallest_block->data + size;
}
// Worst-fit policy
if (alloc_type == 2){
size_t max = 0;
struct dnode *largest_block = NULL;
for (curr_data = dlist_iter_begin(free_list); curr_data != NULL; curr_data = dlist_iter_next(free_list)) {
if((curr_data->size - size > max) && (curr_data->size > size) ){
largest_block = curr_data;
max = curr_data->size - size;
}
}
if (max == 0) {
printf("No space to allocate this\n");
return NULL;
}
ptr = largest_block->data;
dlist_add_back(allocated_list,ptr,size);
largest_block->size = largest_block->size - size;
largest_block->data = largest_block->data + size;
}
return ptr;
}
int deallocate(void *ptr){
struct dnode *removed_data;
removed_data = dlist_find_remove(allocated_list, ptr);
dlist_add_back(free_list,removed_data->data,removed_data->size);
return 0;
}
/*
* Copyright (c) 2012 Bucknell University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: L. Felipe Perrone (perrone@bucknell.edu)
*/
#include <stdlib.h>
#include <stdio.h>
#include "dnode.h"
#include "dlist.h"
struct dlist *
dlist_create() {
return calloc(1, sizeof(struct dlist));
}
void
dlist_destroy(struct dlist *l) {
struct dnode *p = l->front;
do {
l->front = l->front->next;
free(p->data);
free(p);