Lock Hierarchy Violation
Occurs when the acquisition order of multiple synchronization objects (such as mutexes, critical sections, and thread handles) in one thread differs from the acquisition order in another thread, and these synchronization objects are owned by the acquiring thread and must be released by the same thread.
The
Intel Inspector
reports a
Lock hierarchy violation
problem as multiple problems in a problem set. Each problem shows a portion of the
Lock hierarchy violation
from the perspective of a single thread.

ID
| Code Location
| Description
|
---|---|---|
1
| Allocation site
| If present, represents the location and associated call stack where the synchronization object acquired by a thread (usually the object acquired first) was created.
|
2
| Lock owned
| Represents the location and associated call stack where a synchronization object was acquired by a thread.
|
3
| Lock owned
| Represents the location and associated call stack where another synchronization object was later acquired by the same thread.
|
Deadlock
problems are usually, but not always, caused by
Lock hierarchy violation
problems. If the
Intel Inspector
detects a
Deadlock
problem caused by a
Lock hierarchy violation
problem, it reports only the
Deadlock
problem.
C Example
Preparation
|
|
Thread #1
|
|
Thread #2
|
|
If thread #1 and thread #2 are concurrent and there is no other synchronization between them, the
Intel Inspector
detects a
Lock hierarchy violation
problem instead of a
Deadlock
problem if synchronization occurs in the following order:
- EnterCriticalSection(&cs1);in thread #1
- EnterCriticalSection(&cs2);in thread #1
- EnterCriticalSection(&cs2);in thread #2
- EnterCriticalSection(&cs1);in thread #2
Fortran Example
Preparation
|
|
Thread #1
|
|
Thread #2
|
|
If thread #1 and thread #2 are concurrent and there is no other synchronization between them, the
Intel Inspector
detects a
Lock hierarchy violation
problem instead of a
Deadlock
problem if synchronization occurs in the following order:
- call omp_set_lock(lock1)in thread #1
- call omp_set_lock(lock2)in thread #1
- call omp_set_lock(lock2)in thread #2
- call omp_set_lock(lock1)in thread #2
Possible Correction Strategies
- Do not use multiple synchronization objects if one synchronization object is sufficient.
- Use recursive synchronization objects such as recursive mutexes if a thread must acquire the same object more than once.
- Avoid the case where two threads wait for each other to terminate. Instead, use a third thread to wait for both threads to terminate.
- Establish a global lock hierarchy and honor the same lock hierarchy in each thread. For example:
- C language: If you have critical sectionscs1andcs2and establish a global lock hierarchy (cs1,cs2), always acquirecs1before acquiringcs2and releasecs1after releasingcs2.
- Fortran language: If you have lockslock1andlock2and establish a global lock hierarchy (lock1,lock2), always acquirelock1before acquiringlock2and releaselock1after releasinglock2.
- C language: Consider acquiring multiple synchronization objects at the same time using, for example, Microsoft Windows* system APIs such asWaitForMultipleObjects().