Bas van den Heuvel
2024-05-31
A group of threads, each of which is blocked trying to acquire a lock held by another.
Graph: nodes with (directed) edges between.
Lock graph of a given trace:
Efficient, but problematic false positives (cycles from a single thread, guard locks).
Improves over lock graphs by accounting for threads and guard locks.
Lock dependencies of a given trace:
Better than lock graphs, but still false positives (cross-thread critical sections)… We’re still searching for better solutions!
T1 T2 T3 T4
e1. fork(T4)
e2. fork(T3)
e3. fork(T2)
e4. acq(x)
e5. acq(y)
e6. wr(b)
e7. rel(y)
e8. acq(y)
e9. wr(a)
e10. wr(b)
e11. rel(y)
e12. acq(y)
e13. rd(b)
e14. rel(y)
e15. rel(x)
e16. acq(x)
e17. acq(y)
e18. rd(a)
e19. rel(y)
e20. rel(x)
e21. wr(c)
Lock graph:
No cycle, so no deadlock predicted.
Lock dependencies:
No cycle, so no deadlock predicted.
True negative. T1 T2 T3 T4
e1. fork(T4)
e2. fork(T3)
e3. fork(T2)
e4. acq(x)
e5. acq(y)
e6. wr(b)
e7. rel(y)
e8. acq(y)
e9. wr(a)
e10. wr(b)
e11. rel(y)
e12. acq(y)
e13. rd(b)
e14. rel(y)
e15. rel(x)
e16. acq(y)
e17. acq(x)
e18. rd(a)
e19. rel(x)
e20. rel(y)
e21. wr(c)
Lock graph:
Cycle, so deadlock predicted.
Lock dependencies:
Cycle, so deadlock predicted.
False positive: last-write. T1 T2 T3 T4
e1. fork(T4)
e2. fork(T3)
e3. fork(T2)
e4. acq(x)
e5. acq(y)
e6. wr(b)
e7. rel(y)
e8. acq(z)
e9. wr(a)
e10. wr(b)
e11. rel(z)
e12. acq(y)
e13. rd(b)
e14. rel(y)
e15. rel(x)
e16. acq(z)
e17. acq(x)
e18. rd(a)
e19. rel(x)
e20. rel(z)
e21. wr(c)
Lock graph:
No cycle, no deadlock predicted.
Lock dependencies:
No cycle, no deadlock predicted.
Appears to be a false negative: ~~~ T1 T2 T3 T4
e1. fork(T4) e2. fork(T3) e3. fork(T2) e4. acq(x) e16. acq(z) e5. acq(y) e6. wr(b) e7. rel(y) e8. B-acq(z) e12. acq(y) e13. B-rd(b) e17. B-acq(x) ~~~ Not a resource deadlock: T2 not blocked on a lock acquire!