| 1443 | |
| 1444 | |
| 1445 | static void prt_owner_wait_cycle(OUTFILE outfile, |
| 1446 | const lhb* LOCK_header, |
| 1447 | const own* owner, |
| 1448 | USHORT indent, waitque* waiters) |
| 1449 | { |
| 1450 | /************************************** |
| 1451 | * |
| 1452 | * p r t _ o w n e r _ w a i t _ c y c l e |
| 1453 | * |
| 1454 | ************************************** |
| 1455 | * |
| 1456 | * Functional description |
| 1457 | * For the given owner, print out the list of owners |
| 1458 | * being waited on. The printout is recursive, up to |
| 1459 | * a limit. It is recommended this be used with |
| 1460 | * the -c consistency mode. |
| 1461 | * |
| 1462 | **************************************/ |
| 1463 | for (USHORT i = indent; i; i--) |
| 1464 | FPRINTF(outfile, " "); |
| 1465 | |
| 1466 | // Check to see if we're in a cycle of owners - this might be |
| 1467 | // a deadlock, or might not, if the owners haven't processed |
| 1468 | // their blocking queues |
| 1469 | |
| 1470 | for (USHORT i = 0; i < waiters->waitque_depth; i++) |
| 1471 | if (SRQ_REL_PTR(owner) == waiters->waitque_entry[i]) |
| 1472 | { |
| 1473 | FPRINTF(outfile, "%s (potential deadlock).\n", |
| 1474 | (const TEXT*) HtmlLink(preOwn, SRQ_REL_PTR(owner))); |
| 1475 | return; |
| 1476 | } |
| 1477 | |
| 1478 | FPRINTF(outfile, "%s waits on ", (const TEXT*) HtmlLink(preOwn, SRQ_REL_PTR(owner))); |
| 1479 | |
| 1480 | bool found = false; |
| 1481 | |
| 1482 | srq* lock_srq; |
| 1483 | SRQ_LOOP(owner->own_pending, lock_srq) |
| 1484 | { |
| 1485 | if (waiters->waitque_depth >= FB_NELEM(waiters->waitque_entry)) |
| 1486 | { |
| 1487 | FPRINTF(outfile, "Dependency too deep\n"); |
| 1488 | return; |
| 1489 | } |
| 1490 | |
| 1491 | found = true; |
| 1492 | |
| 1493 | waiters->waitque_entry[waiters->waitque_depth++] = SRQ_REL_PTR(owner); |
| 1494 | |
| 1495 | FPRINTF(outfile, "\n"); |
| 1496 | const lrq* const owner_request = (lrq*) ((UCHAR*) lock_srq - offsetof(lrq, lrq_own_pending)); |
| 1497 | fb_assert(owner_request->lrq_type == type_lrq); |
| 1498 | const bool owner_conversion = (owner_request->lrq_state > LCK_null); |
| 1499 | |
| 1500 | const lbl* const lock = (lbl*) SRQ_ABS_PTR(owner_request->lrq_lock); |
| 1501 | fb_assert(lock->lbl_type == type_lbl); |
| 1502 | |