Skip to content

Commit c6f0503

Browse files
authored
Merge pull request #5653 from MicrosoftDocs/main
8/23/2024 AM Publish
2 parents 3ab8cd9 + 2000d4f commit c6f0503

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

docs/code-quality/annotating-locking-behavior.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ ms.assetid: 07769c25-9b97-4ab7-b175-d1c450308d7a
3333

3434
To avoid concurrency bugs in your multithreaded program, always follow an appropriate locking discipline and use SAL annotations.
3535

36-
Concurrency bugs are notoriously hard to reproduce, diagnose, and debug because they're non-deterministic. Reasoning about thread interleaving is difficult at best, and becomes impractical when you're designing a body of code that has more than a few threads. Therefore, it's good practice to follow a locking discipline in your multithreaded programs. For example, obeying a lock order while acquiring multiple locks helps avoid deadlocks, and acquiring the proper guarding lock before accessing a shared resource helps prevent race conditions.
36+
Concurrency bugs are notoriously hard to reproduce, diagnose, and debug because they're nondeterministic. Reasoning about thread interleaving is difficult at best, and becomes impractical when you're designing a body of code that has more than a few threads. Therefore, it's good practice to follow a locking discipline in your multithreaded programs. For example, obeying a lock order while acquiring multiple locks helps avoid deadlocks, and acquiring the proper guarding lock before accessing a shared resource helps prevent race conditions.
3737

38-
Unfortunately, seemingly simple locking rules can be surprisingly hard to follow in practice. A fundamental limitation in today's programming languages and compilers is that they do not directly support the specification and analysis of concurrency requirements. Programmers have to rely on informal code comments to express their intentions about how they use locks.
38+
Unfortunately, seemingly simple locking rules can be surprisingly hard to follow in practice. A fundamental limitation in today's programming languages and compilers is that they don't directly support the specification and analysis of concurrency requirements. Programmers have to rely on informal code comments to express their intentions about how they use locks.
3939

4040
Concurrency SAL annotations are designed to help you specify locking side effects, locking responsibility, data guardianship, lock order hierarchy, and other expected locking behavior. By making implicit rules explicit, SAL concurrency annotations provide a consistent way for you to document how your code uses locking rules. Concurrency annotations also enhance the ability of code analysis tools to find race conditions, deadlocks, mismatched synchronization operations, and other subtle concurrency errors.
4141

@@ -64,10 +64,10 @@ The following table lists the locking annotations.
6464
|`_Acquires_nonreentrant_lock_(expr)`|The lock that's named by `expr` is acquired. An error is reported if the lock is already held.|
6565
|`_Acquires_shared_lock_(expr)`|Annotates a function and indicates that in post state the function increments by one the shared lock count of the lock object that's named by `expr`.|
6666
|`_Create_lock_level_(name)`|A statement that declares the symbol `name` to be a lock level so that it may be used in the annotations `_Has_Lock_level_` and `_Lock_level_order_`.|
67-
|`_Has_lock_kind_(kind)`|Annotates any object to refine the type information of a resource object. Sometimes a common type is used for different kinds of resources and the overloaded type isn't sufficient to distinguish the semantic requirements among various resources. Here's a list of pre-defined `kind` parameters:<br /><br /> `_Lock_kind_mutex_`<br /> Lock kind ID for mutexes.<br /><br /> `_Lock_kind_event_`<br /> Lock kind ID for events.<br /><br /> `_Lock_kind_semaphore_`<br /> Lock kind ID for semaphores.<br /><br /> `_Lock_kind_spin_lock_`<br /> Lock kind ID for spin locks.<br /><br /> `_Lock_kind_critical_section_`<br /> Lock kind ID for critical sections.|
67+
|`_Has_lock_kind_(kind)`|Annotates any object to refine the type information of a resource object. Sometimes a common type is used for different kinds of resources and the overloaded type isn't sufficient to distinguish the semantic requirements among various resources. Here's a list of predefined `kind` parameters:<br /><br /> `_Lock_kind_mutex_`<br /> Lock kind ID for mutexes.<br /><br /> `_Lock_kind_event_`<br /> Lock kind ID for events.<br /><br /> `_Lock_kind_semaphore_`<br /> Lock kind ID for semaphores.<br /><br /> `_Lock_kind_spin_lock_`<br /> Lock kind ID for spin locks.<br /><br /> `_Lock_kind_critical_section_`<br /> Lock kind ID for critical sections.|
6868
|`_Has_lock_level_(name)`|Annotates a lock object and gives it the lock level of `name`.|
6969
|`_Lock_level_order_(name1, name2)`|A statement that gives the lock ordering between `name1` and `name2`. Locks that have level `name1` must be acquired before locks that have level `name2`.|
70-
|`_Post_same_lock_(expr1, expr2)`|Annotates a function and indicates that in post state the two locks, `expr1` and `expr2`, are treated as if they're the same lock object.|
70+
|`_Post_same_lock_(dst, src)`|Annotates a function and indicates that in post state the two locks, `dst` and `src`, are treated as if they're the same lock object, by applying lock properties from `src` to `dst`.|
7171
|`_Releases_exclusive_lock_(expr)`|Annotates a function and indicates that in post state the function decrements by one the exclusive lock count of the lock object that's named by `expr`.|
7272
|`_Releases_lock_(expr)`|Annotates a function and indicates that in post state the function decrements by one the lock count of the lock object that's named by `expr`.|
7373
|`_Releases_nonreentrant_lock_(expr)`|The lock that's named by `expr` is released. An error is reported if the lock isn't currently held.|
@@ -97,17 +97,17 @@ The following table lists the annotations for shared data access.
9797
|----------------|-----------------|
9898
|`_Guarded_by_(expr)`|Annotates a variable and indicates that whenever the variable is accessed, the lock count of the lock object that's named by `expr` is at least one.|
9999
|`_Interlocked_`|Annotates a variable and is equivalent to `_Guarded_by_(_Global_interlock_)`.|
100-
|`_Interlocked_operand_`|The annotated function parameter is the target operand of one of the various Interlocked functions. Those operands must have specific additional properties.|
100+
|`_Interlocked_operand_`|The annotated function parameter is the target operand of one of the various Interlocked functions. Those operands must have other specific properties.|
101101
|`_Write_guarded_by_(expr)`|Annotates a variable and indicates that whenever the variable is modified, the lock count of the lock object that's named by `expr` is at least one.|
102102

103103
## Smart Lock and RAII Annotations
104104

105-
Smart locks typically wrap native locks and manage their lifetime. The following table lists annotations that can be used with smart locks and RAII coding patterns with support for `move` semantics.
105+
Smart locks typically wrap native locks and manage their lifetime. The following table lists annotations that can be used with smart locks and Resource Acquisition Is Initialization (RAII) coding patterns with support for `move` semantics.
106106

107107
|Annotation|Description|
108108
|----------------|-----------------|
109-
|`_Analysis_assume_smart_lock_acquired_(lock)`|Tells the analyzer to assume that a smart lock has been acquired. This annotation expects a reference lock type as its parameter.|
110-
|`_Analysis_assume_smart_lock_released_(lock)`|Tells the analyzer to assume that a smart lock has been released. This annotation expects a reference lock type as its parameter.|
109+
|`_Analysis_assume_smart_lock_acquired_(lock)`|Tells the analyzer to assume that a smart lock was acquired. This annotation expects a reference lock type as its parameter.|
110+
|`_Analysis_assume_smart_lock_released_(lock)`|Tells the analyzer to assume that a smart lock was released. This annotation expects a reference lock type as its parameter.|
111111
|`_Moves_lock_(target, source)`|Describes a `move constructor` operation, which transfers lock state from the `source` object to the `target`. The `target` is considered a newly constructed object, so any state it had before is lost and replaced by the `source` state. The `source` is also reset to a clean state with no lock counts or aliasing target, but aliases pointing to it remain unchanged.|
112112
|`_Replaces_lock_(target, source)`|Describes `move assignment operator` semantics where the target lock is released before transferring the state from the source. You can regard it as a combination of `_Moves_lock_(target, source)` preceded by a `_Releases_lock_(target)`.|
113113
|`_Swaps_locks_(left, right)`|Describes the standard `swap` behavior, which assumes that objects `left` and `right` exchange their state. The state exchanged includes lock count and aliasing target, if present. Aliases that point to the `left` and `right` objects remain unchanged.|

0 commit comments

Comments
 (0)