Implement graph reduction algorithm

This commit is contained in:
John 2022-04-23 04:48:47 -05:00
parent ddaa60a5ec
commit 8044ba68e3

View File

@ -5,22 +5,71 @@
+-----------------------------------------------+ */
#include "graph.hpp"
using std::vector;
bool blocked(const int num_processes, const int num_resources, const vector<int> resource_counts, const graph::matrix &matrix, int process_id);
/* reducible:
Perform the graph reduction algorithm on the adjacency matrix to detect deadlocks
This algorithm is described in section 5.2 of the Zybook
The graph reduction algorithm is implemented here with a few obvious optimizations:
The algorithm should clear at least one blocked process per iteration;
This leads to an easy failure condition, since fewer processes should be blocked than there are remaining iterations.
By extension,
@params: none, uses class-internal data
@returns:
bool:
true if graph is not reducible (deadlock)
false if graph is reducible (no deadlock)
true if graph is deadlocked (not reducible)
false if graph is not deadlocked (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;
// Make a copy of the matrix, so we don't overwrite it
matrix m_copy = m;
// run for num_processes iterations; there's no point to doing more, since at least one process should clear each time
for (int num_iterations = 0; num_iterations < num_processes; num_iterations++) {
int num_blocked = 0;
// calculate whether every process is blocked or not
for(int p = 0; p < num_processes; p++) {
// check if process is blocked
if (blocked(num_processes,num_resources,resource_counts,m_copy, p)) {
//indicate process is blocked
num_blocked++;
} else {
// erase unblocked process from the graph
m_copy[p][p] = 0;
for (int r = num_processes; r < num_processes + num_resources; r++) {
m_copy[r][p] = 0; m_copy[p][r] = 0;
}
}
}
// print the number of blocked processes
printf("\nIteration %d:\nnum_blocked: %d\n", num_iterations+1, num_blocked);
// If more processes are blocked than can be cleared before the algorithm finishes, give up
if (num_blocked == num_processes - num_iterations) return true;
// Print the new matrix
printf("| ");for(auto x:m_copy){for(auto y:x)printf("%d, ",y);printf("\b\b |\n| ");}printf("\b\b \b\b");
// If no processes are blocked, we won!
if (num_blocked == 0) return false;
}
return true;
}
bool graph::is_blocked(int process_id) {
return true;
bool blocked(const int np, const int nr, const vector<int> rc, const graph::matrix &m, int process_id) {
//* Calculate free resources, and compare free units to requests
vector<int> resources = rc;
for (int r = 0; r < nr; r++) {
// Calculate the number of units available
for (int p = 0; p < np; p++) {
// subtract units currently in use
// a resource is in use when >0 in the allocation quadrant of the table, i.e. [(np,0), (nr+np, np))
resources[r] -= m[r+np][p];
}
// If the program requests more resources than are available, it's blocked
if (m[process_id][r+np] > resources[r]) {
return true;
}
}
// else process is not blocked
return false;
}