// 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);