diff --git a/.gitignore b/.gitignore index ec28350..9480b49 100644 --- a/.gitignore +++ b/.gitignore @@ -12,12 +12,14 @@ # ---> C # Prerequisites *.d +dep/ # Object files *.o *.ko *.obj *.elf +obj/ # Linker output *.ilk diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4ecc2ba --- /dev/null +++ b/Makefile @@ -0,0 +1,65 @@ +# +-------------+---------+-----------------------+ +# | John Breaux | jab0910 | JohnBreaux@my.unt.edu | +# +-------------+---------+-----------------------+ +# | Created 2022-04-04 Edited 2022-04-16 | +# +-----------------------------------------------+ + +# ---------- Variables listed below --------- # + +# Executable +TARGET := main.out + +# Paths to source, include, dependency, and object files +SPATH = src +IPATH = inc +DPATH = dep +OPATH = obj + +# File type of source file +STYPE = c + +VPATH = $(SPATH) $(IPATH) $(DPATH) $(OPATH) + +# compiler and compiler flags +CC = gcc +CFLAGS = -I$(IPATH) -pthread -lrt + +# list of object files +SOURCES = $(wildcard $(SPATH)/*.$(STYPE)) +OBJECTS = $(addprefix $(OPATH)/,$(notdir $(SOURCES:.$(STYPE)=.o))) + + +# ----------- Targets listed below ---------- # +# Some targets aren't real +.PHONY: all clean run dump +# Don't autodelete object files: +.PRECIOUS: $(OPATH)/%.o + +all: $(DPATH) $(OPATH) $(TARGET) + +dump: + @echo SOURCES: $(SOURCES) + @echo OBJECTS: $(OBJECTS) + @echo TARGET: $(TARGET) + @echo VPATH: $(VPATH) + +clean: + -rm $(TARGET) + -rm -r dep obj + +run: + -$(addprefix ./,$(addsuffix ;,$(TARGET))) + +$(DPATH) $(OPATH): + mkdir -p $@ + +# Make the executable(s) +%.out: $(OBJECTS) + $(CC) $(CFLAGS) -o $@ $^ +# Make the object and dependency files +$(OPATH)/%.o: $(SPATH)/%.$(STYPE) + $(CC) $(CFLAGS) -MMD -MF "$(DPATH)/$(@F:.o=.d)" -o "$@" -c "$<" + +# --------- Inclusions listed below --------- # +# use dependencies when rebuilding +-include $(wildcard $(DPATH)/*.d) diff --git a/README.md b/README.md index 07a6b6d..c6b0105 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,11 @@ # 4600-project-2 +Project 2 for CSCE4600, for Team G4 + +## Build + +Build with `make` + +Run with `make run` + +Clean with `make clean` diff --git a/inc/graph.h b/inc/graph.h new file mode 100644 index 0000000..90648f4 --- /dev/null +++ b/inc/graph.h @@ -0,0 +1,57 @@ + +// Gee, ain't pointers just the greatest? +//? Rename to'graph'? Typedef to 'graph'? +struct adjmatrix { + int num_processes; // The number of processes in the matrix + int num_resources; // The number of resources in the matrix + int *resource_counts; // The counts of each resource in the matrix + int **matrix; // Tell me, Mr. Anderson, what good is a phone call if you are unable to speak? +}; + +/* graph_reduce: + Perform the graph reduction algorithm on the adjacency matrix to detect deadlocks + This algorithm is described in section 5.2 of the Zybook + (!THIS MODIFIES THE GRAPH!) + @params: + graph: adjacency matrix containing all relevant information about the graph + @returns: + int: + 1 if graph is not reducible (deadlock) + 0 if graph is reducible (no deadlock) +*/ +int graph_reduce(struct adjmatrix *graph); + +/* knot_detect: + Perform the knot detection algorithm on the adjacency matrix to detect deadlocks + (!THIS MODIFIES THE GRAPH!) + @params: + graph: adjacency matrix containing all relevant information about the graph + @returns: + int: + 1 if graph is knotted (deadlock) + 0 if graph is not (no deadlock) +*/ +int knot_detect(struct adjmatrix *graph); + +/* create_adjmatrix: + Create a new adjmatrix (!THIS INVOLVES MEMORY ALLOCATION!) (Basically a constructor) + @params: + num_processes + num_resources + @returns: + struct adjmatrix: + Empty adjacency matrix of size (num_processes+num_resources)^2 + Fill in the blanks yourself +*/ +struct adjmatrix * create_adjmatrix(int num_processes, int num_resources); + +/* destroy_adjmatrix: + Destroy an adjmatrix (!THIS INVOLVES MEMORY DEALLOCATION!) (Basically a destructor) + @params: + matrix: + A structure containing all relevant information about the graph + @returns: + int: + 0 if operation completed successfully, else a value of type `errno` +*/ +int destroy_adjmatrix(struct adjmatrix *matrix); diff --git a/inc/read_input.h b/inc/read_input.h new file mode 100644 index 0000000..8f7f291 --- /dev/null +++ b/inc/read_input.h @@ -0,0 +1,3 @@ + + +int read_file(char *filename, struct adjmatrix *graph); \ No newline at end of file diff --git a/src/graph.c b/src/graph.c new file mode 100644 index 0000000..54e63a2 --- /dev/null +++ b/src/graph.c @@ -0,0 +1,22 @@ +#include +#include "graph.h" + +int graph_reduce(struct adjmatrix *graph) { + // TODO: Implement a function which checks if a process is blocked + // TODO: Use that function to implement the graph reduction algorithm + //? Make sure when reducing the graph, you don't try to delete the + return 0; +} + +int knot_detect(struct adjmatrix *graph) { + return 0; +} + +int destroy_adjmatrix(struct adjmatrix *matrix) { + for (int i = 0; i < matrix->num_processes + matrix->num_resources; i++) { + free(matrix->matrix[i]); + } + free(matrix->matrix); + free(matrix->resource_counts); + return 0; +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..2ededfe --- /dev/null +++ b/src/main.c @@ -0,0 +1,27 @@ +/* +-------------+---------+-----------------------+ + | John Breaux | jab0910 | JohnBreaux@my.unt.edu | //TODO put your name here + +-------------+---------+-----------------------+ + | Created 2022-04-16 | + +-----------------------------------------------+ */ +#include // printf +#include "graph.h" // Graph reduction/Knot detection, struct adjmatrix +#include "read_input.h" //TODO: Read input in the associated C file, and provide an interface to that function here + + +int main(int argc, char** argv) { + // TODO: Grab file name from args + //? Command line argument structure? + //? Other flags? What other features should this have? + char* filename = NULL; + + //TODO: Implement reading from a file + struct adjmatrix *graph; + read_file(filename, graph); + + + // TODO: Implement graph reduction and/or knot detection + + // TODO: Destroy the graph created by read_file + destroy_adjmatrix(graph); + return 0; +} \ No newline at end of file diff --git a/src/read_input.c b/src/read_input.c new file mode 100644 index 0000000..7488b89 --- /dev/null +++ b/src/read_input.c @@ -0,0 +1,39 @@ +//TODO: Include C file IO header (stdio.h? Whatever it is) +#include +#include "graph.h" // struct adjmatrix +#include "read_input.h" // read_input + +#define MAX_LINE_LEN 1024 + +// TODO: Implement reading from a file +int read_file(char *filename, struct adjmatrix *graph) { + // TODO: Open file with name filename as read-only + FILE *f = fopen(filename, "r"); + // TODO: Check for file IO errors (I might have a solution for that in another project) + + int num_processes = 0, num_resources = 0; + char line[MAX_LINE_LEN]; // Lines can be no more than 1KB in size, a sensible limitation + while (!feof(f)) { + //* A line starting with a % is a comment, and should be skipped + // if %: + continue; + //* A blank line should be skipped + // if blank: + continue; + //* A line starting with `num_processes=` contains the number of processes + //if "num_processes": + num_processes = 0; // TODO: Read file + //* A line starting with `num_resources=` contains the number of resources + //if "num_resources": + num_resources = 0; + // TODO: create graph 'object' here + //* A line containing num_resources numbers follows, indicating the number of each resource + //* Resources are comma-separated, so there can never be more than 1/2 as many as max line length + int resource_counts[MAX_LINE_LEN/2]; + //* A comma-separated, newline-separated adjacency matrix with which to reduce + + } + + // TODO: Close file + // TODO: Check for file IO errors (Shouldn't be any) +}