Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change deadlock cycle detection algorithm to a general one for directed graphs #195

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,4 @@ williamsentosa95 <[email protected]>
Pradyumna Shome <[email protected]>
Benjamin West Pollak <[email protected]>
姜芃越 Pengyue Jiang <[email protected]>
Cay Zhang <[email protected]>
67 changes: 41 additions & 26 deletions deadlock/deadlock.tex
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,49 @@ \section{Resource Allocation Graphs}
If there is a cycle in the Resource Allocation Graph and each resource in the cycle provides only one instance, then the processes will deadlock.
For example, if process 1 holds resource A, process 2 holds resource B and process 1 is waiting for B and process 2 is waiting for A, then processes 1 and 2 will be deadlocked \ref{ragfigure}.
We'll make the distinction that the system is in deadlock by definition if all workers cannot perform an operation other than waiting.
We can detect a deadlock by traversing the graph and searching for a cycle using a graph traversal algorithm, such as the Depth First Search (DFS).

This graph is considered as a directed graph and we can treat both the processes and resources as nodes.
We can detect a deadlock by traversing the directed graph and searching for a cycle using a graph traversal algorithm, such as the Depth First Search (DFS).

\begin{minted}{C}
typedef struct {
int node_id; // Node in this particular graph
Graph **reachable_nodes; // List of nodes that can be reached from this node
int size_reachable_nodes; // Size of the List
} Graph;

// isCyclic() traverses a graph using DFS and detects whether it has a cycle
// isCyclic() uses a recursive approach
// G points to a node in a graph, which can be either a resource or a process
// is_visited is an array indexed with node_id and initialized with zeros (false) to record whether a particular node has been visited
int isCyclic(Graph *G, int* is_visited) {
if (this graph has been visited) {
// Oh! the cycle is found
return true;
} else {
1. Mark this node as visited
2. Traverse through all nodes in the reachable_nodes
3. Call isCyclic() for each node
4. Evaluate the return value of isCyclic()
}
// Nope, this graph is acyclic
return false;
}
\end{minted}
\begin{lstlisting}[language=C]
// is_cyclic() traverses a graph using DFS and detects whether it has a cycle
// a node in the graph can be either a resource or a process
bool is_cyclic(const graph* g) {
set visited_vertices = set_create();
for (each vertex in g) {
set current_path = set_create();
if (_graph_contains_cycle(g, vertex, &visited_vertices, &current_path)) {
/* deallocate resources */
return true;
}
/* deallocate resources */
}
/* deallocate resources */
return false;
}

bool _is_cyclic(const graph* g, const void* root, set* visited, set* current_path) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_graph_contains_cycle?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function names are now consistent.

// if the vertex has already been visited, don't visit it again
// the graph is cyclic if and only if the vertex is in the current path, i.e. a back edge exists
if (set_contains(visited, root)) return set_contains(current_path, root);

set_add(visited, root);
set_add(current_path, root);

for (each neighbor of root) {
if (_is_cyclic(graph, neighbor, visited, current_path)) {
/* deallocate resources */
return true;
}
});

// pop the vertex from the current path when we are done with it
set_remove(current_path, root);

/* deallocate resources */
return false;
}
\end{lstlisting}

\begin{figure}[H]
\centering
Expand Down