| 2229 | } |
| 2230 | |
| 2231 | static int |
| 2232 | graph_add_edge(struct owner_graph *g, struct owner_vertex *x, |
| 2233 | struct owner_vertex *y) |
| 2234 | { |
| 2235 | struct owner_edge *e; |
| 2236 | struct owner_vertex_list deltaF, deltaB; |
| 2237 | int nF, n, vi, i; |
| 2238 | int *indices; |
| 2239 | int nB __unused; |
| 2240 | |
| 2241 | sx_assert(&lf_owner_graph_lock, SX_XLOCKED); |
| 2242 | |
| 2243 | LIST_FOREACH(e, &x->v_outedges, e_outlink) { |
| 2244 | if (e->e_to == y) { |
| 2245 | e->e_refs++; |
| 2246 | return (0); |
| 2247 | } |
| 2248 | } |
| 2249 | |
| 2250 | #ifdef LOCKF_DEBUG |
| 2251 | if (lockf_debug & 8) { |
| 2252 | printf("adding edge %d:", x->v_order); |
| 2253 | lf_print_owner(x->v_owner); |
| 2254 | printf(" -> %d:", y->v_order); |
| 2255 | lf_print_owner(y->v_owner); |
| 2256 | printf("\n"); |
| 2257 | } |
| 2258 | #endif |
| 2259 | if (y->v_order < x->v_order) { |
| 2260 | /* |
| 2261 | * The new edge violates the order. First find the set |
| 2262 | * of affected vertices reachable from y (deltaF) and |
| 2263 | * the set of affect vertices affected that reach x |
| 2264 | * (deltaB), using the graph generation number to |
| 2265 | * detect whether we have visited a given vertex |
| 2266 | * already. We re-order the graph so that each vertex |
| 2267 | * in deltaB appears before each vertex in deltaF. |
| 2268 | * |
| 2269 | * If x is a member of deltaF, then the new edge would |
| 2270 | * create a cycle. Otherwise, we may assume that |
| 2271 | * deltaF and deltaB are disjoint. |
| 2272 | */ |
| 2273 | g->g_gen++; |
| 2274 | if (g->g_gen == 0) { |
| 2275 | /* |
| 2276 | * Generation wrap. |
| 2277 | */ |
| 2278 | for (vi = 0; vi < g->g_size; vi++) { |
| 2279 | g->g_vertices[vi]->v_gen = 0; |
| 2280 | } |
| 2281 | g->g_gen++; |
| 2282 | } |
| 2283 | nF = graph_delta_forward(g, x, y, &deltaF); |
| 2284 | if (nF < 0) { |
| 2285 | #ifdef LOCKF_DEBUG |
| 2286 | if (lockf_debug & 8) { |
| 2287 | struct owner_vertex_list path; |
| 2288 | printf("deadlock: "); |
no test coverage detected