A newer version of this document is available. Customers should click here to go to the newest version.
Lock Hierarchy Violation
Occurs when two or more locks are acquired in a different order in two task executions, potentially leading to a deadlock when the program's tasks execute in parallel.
A Lock hierarchy violation problem indicates the following timeline:
Task 1  |  
         
         
  |  
       
Task 2  |  
         
         
  |  
       
If these time lines are interleaved when the two tasks execute in parallel, a Deadlock occurs:
Task 1: Acquire lock A.
Task 2: Acquire lock B.
Task 1: Try to acquire lock B; wait until task 2 releases it.
Task 2: Try to acquire lock A; wait until task 1 releases it.
The Dependencies tool reports a Lock hierarchy violation as multiple problems in a problem set. Each problem shows a portion of the Lock hierarchy violation from the perspective of a single thread.
Lock hierarchy violation problems are the most common cause of Deadlock problems, and a report of a Lock hierarchy violation problem indicates a Deadlock problem might occur when the target executes in parallel.
Syntax

ID  |  
        Code Location  |  
        Description  |  
       
|---|---|---|
1  |  
        Allocation site  |  
        If present, represents the location and its associated call stack where the synchronization object acquired by a thread (usually the object acquired first) was created.  |  
       
2  |  
        Parallel site  |  
        If present, represents the location and associated call stack of the parallel site containing the Lock Hierarchy Violation problem.  |  
       
3  |  
        Lock owned  |  
        Represents the location and associated call stack where a task acquired a lock.  |  
       
4  |  
        Lock owned  |  
        Represents the location and associated call stack where a task acquired a second lock while the task still held the first lock.  |  
       
Example
// in task 1  |  
        ANNOTATE_LOCK_ACQUIRE(&lahv_lock1); ANNOTATE_LOCK_ACQUIRE(&lahv_lock2); /* lock hierarchy violation */ ANNOTATE_LOCK_RELEASE(&lahv_lock2); ANNOTATE_LOCK_RELEASE(&lahv_lock1);  |  
       
// in task 2  |  
        ANNOTATE_LOCK_ACQUIRE(&lahv_lock2); ANNOTATE_LOCK_ACQUIRE(&lahv_lock1); /* lock hierarchy violation */ ANNOTATE_LOCK_RELEASE(&lahv_lock1); ANNOTATE_LOCK_RELEASE(&lahv_lock2);  |  
       
Possible Correction Strategies
Determine if interleaving is possible, or whether some other synchronization exists that might prevent interleaving. If interleaving is possible, consider the following options.
Use a single lock instead of multiple locks:
// in task 1  |  
        ANNOTATE_LOCK_ACQUIRE(&lahv_lock1); a++; b += a; ANNOTATE_LOCK_RELEASE(&lahv_lock1);  |  
       
// in task 2  |  
        ANNOTATE_LOCK_ACQUIRE(&lahv_lock2); b += x[i]; a -= b; ANNOTATE_LOCK_RELEASE(&lahv_lock2);  |  
       
Try to define a consistent order for your locks, so that any task that acquires the same set of locks, will acquire them in the same order:
// in task 1  |  
        ANNOTATE_LOCK_ACQUIRE(&lahv_lock1); a++; b += a; ANNOTATE_LOCK_RELEASE(&lahv_lock1);  |  
       
// in task 2  |  
        ANNOTATE_LOCK_ACQUIRE(&lahv_lock2); b += x[i]; a -= b; ANNOTATE_LOCK_RELEASE(&lahv_lock2);  |  
       
When a task acquires multiple locks, make sure that it always releases them in the opposite order that it acquired them.