Implement graph reduction algorithm
This commit is contained in:
parent
ddaa60a5ec
commit
8044ba68e3
@ -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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user