diff --git a/inc/graph.hpp b/inc/graph.hpp index 6c3422c..e6db554 100644 --- a/inc/graph.hpp +++ b/inc/graph.hpp @@ -1,23 +1,25 @@ class graph { -private: - int num_processes; - int num_resources; - int *resource_counts; - struct m{ - int x, y; - std::vector> data; - } matrix; // Tell me, Mr. Anderson, what good is a phone call if you are unable to speak? - public: // Constructors + graph() {} graph(const int processes, const int resources); - // Destructors - ~graph(); // Initializers: - void init(const int **data); + void read(std::string filename); // check functions: // is the graph... bool reducible();// ? bool knotted();// ? + + struct m{ + int x, y; + std::vector> data; + }; + +private: + int num_processes = 0; + int num_resources = 0; + std::vector resource_counts; + struct m matrix; // Tell me, Mr. Anderson, what good is a phone call if you are unable to speak? + bool is_blocked(int process_id); }; \ No newline at end of file diff --git a/inc/read_input.hpp b/inc/read_input.hpp deleted file mode 100644 index b72931f..0000000 --- a/inc/read_input.hpp +++ /dev/null @@ -1,3 +0,0 @@ - - -void read_file(std::string filename); \ No newline at end of file diff --git a/src/graph.cpp b/src/graph.cpp index 5f02e3d..ca7b48b 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "graph.hpp" @@ -20,7 +21,3 @@ graph::graph (const int processes, const int resources) { } } } - -graph::~graph() { - /* clean up..? */ -} diff --git a/src/knotted.cpp b/src/knotted.cpp index e49ce57..6fe570e 100644 --- a/src/knotted.cpp +++ b/src/knotted.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "graph.hpp" diff --git a/src/main.cpp b/src/main.cpp index ebbf572..bfdfa5f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,10 +4,10 @@ +-------------+---------+-----------------------+ | Created 2022-04-16 | +-----------------------------------------------+ */ +#include #include +#include #include "graph.hpp" // Graph reduction/Knot detection, struct adjmatrix -#include "read_input.hpp" //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 @@ -15,9 +15,10 @@ int main(int argc, char** argv) { //? Other flags? What other features should this have? if (argc < 2) return 1; std::string filename = argv[1]; + graph g; //TODO: Implement reading from a file - read_file(filename); + g.read(filename); // TODO: Implement graph reduction and/or knot detection diff --git a/src/read_input.cpp b/src/read_input.cpp index 75c4084..1c6744b 100644 --- a/src/read_input.cpp +++ b/src/read_input.cpp @@ -1,51 +1,60 @@ //TODO: Include C file IO header (stdio.h? Whatever it is) #include +#include #include #include #include #include -#include "graph.hpp" // struct adjmatrix -#include "read_input.hpp" // read_input +#include "graph.hpp" #define MAX_LINE_LEN 1024 // Vector of regices std::vector patterns = { - //* A line starting with a % is a comment, and should be skipped - //* A blank line should be skipped - //* A line starting with `num_processes=` contains the number of processes - std::regex("^.*(num_processes)\\s*=\\s*(\\d+).*"), - //* A line starting with `num_resources=` contains the number of resources - std::regex("^.*(num_resources)\\s*=\\s*(\\d+)"), - //* A line containing comma-separated values should be returned as-is, for manual disassembly - std::regex("^([0-9, ]+)") -}; + //* A line starting with a % is a comment, and should be skipped + //* A blank line should be skipped + //* A line starting with `num_processes=` contains the number of processes + std::regex("^.*(num_processes)\\s*=\\s*(\\d+).*"), + //* A line starting with `num_resources=` contains the number of resources + std::regex("^.*(num_resources)\\s*=\\s*(\\d+)"), + //* A line containing comma-separated values should be returned as-is, for manual disassembly + std::regex("^([\\-0-9, ]+)")}; // matches comma-separated space-separated signed decimal integers + +// convert comma-separated string s to vector +std::vector stovi (const std::string &s); // TODO: Implement reading from a file -void read_file(std::string filename) { +void graph::read(std::string filename) { + printf("graph::read(%s)\n", filename.c_str()); + // Open file with name filename as read-only std::fstream f; f.open(filename, f.in); - // TODO: Check for file IO errors (I might have a solution for that in another project) - int num_processes = 0, num_resources = 0; - std::vector rescount; - std::vector> matrix; + // TODO: Check for file IO errors (I might have a solution for that in another project) std::string line; // Lines can be no more than 1KB in size, a sensible limitation + while (!f.eof()) { std::getline (f, line); + std::smatch res; // Iterate over each pattern, and grab the associated data for (auto pattern: patterns) { if (std::regex_search (line, res, pattern)) { // get the pattern type, value std::string type = res.format("$1"), value = res.format("$2"); - // Handle the pattern - if (type == "num_processes") { num_processes = std::stoi(value); } else - if (type == "num_resources") { num_resources = std::stoi(value); } else - if (type.length()/2 <= num_resources) { - // This is the resource count structure - } + // Handle the pattern + // If num_processes= matched, assign value to num_processes + if (type == "num_processes") { num_processes = std::stoi(value); } else + // If num_resources= matched, assign value to num_resources + if (type == "num_resources") { num_resources = std::stoi(value); } else + // If this line is a comma-separated list of numbers, + // and this is the first match, assign it to resource counts + if (!resource_counts.size()) { resource_counts = stovi(type); } else + // and this is a subsequent match, push it onto the matrix + { matrix.data.push_back(stovi(type)); } + + // If a pattern is matched, go to the next line and skip evaluating other patterns break; } } @@ -54,5 +63,25 @@ void read_file(std::string filename) { // Close file f.close(); // TODO: Check for file IO errors (Shouldn't be any) + + // print information about the graph + printf("np: %d\tnr: %d\n", num_processes, num_resources); + printf("resource_counts:\n"); for (auto e: resource_counts) printf("%d\t", e); printf("\n"); + printf("matrix:\n"); for (auto x: matrix.data) {for (auto y: x) printf("%d\t", y); printf("\n");} return; } + +std::vector stovi (const std::string &s) { + std::stringstream ss(s); + printf("%s\n", s.c_str()); + size_t idx = 0; + std::vector vi; + // reserve enough space for an entire string of one-character ints + vi.reserve((s.length()+1)/2); + while (!ss.eof()) { + char integer[16]; // " -WXXXYYYZZZ," + ss.getline(integer, 16, ','); + vi.push_back(atoi( (const char* ) &integer)); + } + return vi; +} diff --git a/src/reducible.cpp b/src/reducible.cpp index 4bec6da..d2c9a26 100644 --- a/src/reducible.cpp +++ b/src/reducible.cpp @@ -1,21 +1,24 @@ #include +#include #include #include "graph.hpp" /* reducible: 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: none, uses class-internal data @returns: bool: - false if graph is not reducible (deadlock) - true if graph is reducible (no deadlock) + true if graph is not reducible (deadlock) + false if graph is reducible (no deadlock) */ -bool graph::reducible() -{ +bool graph::reducible() { // 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 false; +} + +bool graph::is_blocked(int process_id) { + return true; } \ No newline at end of file