diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2022-10-11 15:17:09 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-11 09:17:09 +0200 |
commit | 5602183234f59ece4fd668915da848f0753cbbb9 (patch) | |
tree | b955da8037206560cdc9628d94a3b604bd9ac631 /doc | |
parent | 75873715546142a6f6f78180abdf1c1ddc0416e5 (diff) | |
download | Nim-5602183234f59ece4fd668915da848f0753cbbb9.tar.gz |
'lock levels' are deprecated, now a noop (#20539)
* 'lock levels' are deprecated, now a noop * fixes tests
Diffstat (limited to 'doc')
-rw-r--r-- | doc/manual_experimental.md | 99 |
1 files changed, 0 insertions, 99 deletions
diff --git a/doc/manual_experimental.md b/doc/manual_experimental.md index cef4ff265..59d6a407b 100644 --- a/doc/manual_experimental.md +++ b/doc/manual_experimental.md @@ -1817,105 +1817,6 @@ restrictions / changes: yet performed for ordinary slices outside of a `parallel` section. - -Lock levels -=========== - -Lock levels are used to enforce a global locking order in order to detect -potential deadlocks during semantic analysis. A lock level is an constant -integer in the range 0..1_000. Lock level 0 means that no lock is acquired at -all. - -If a section of code holds a lock of level `M`, it can also acquire any -lock of level `N < M`. Another lock of level `M` cannot be acquired. Locks -of the same level can only be acquired *at the same time* within a -single `locks` section: - - ```nim - var a, b: TLock[2] - var x: TLock[1] - # invalid locking order: TLock[1] cannot be acquired before TLock[2]: - {.locks: [x].}: - {.locks: [a].}: - ... - # valid locking order: TLock[2] acquired before TLock[1]: - {.locks: [a].}: - {.locks: [x].}: - ... - - # invalid locking order: TLock[2] acquired before TLock[2]: - {.locks: [a].}: - {.locks: [b].}: - ... - - # valid locking order, locks of the same level acquired at the same time: - {.locks: [a, b].}: - ... - ``` - - -Here is how a typical multilock statement can be implemented in Nim. Note how -the runtime check is required to ensure a global ordering for two locks `a` -and `b` of the same lock level: - - ```nim - template multilock(a, b: ptr TLock; body: untyped) = - if cast[ByteAddress](a) < cast[ByteAddress](b): - pthread_mutex_lock(a) - pthread_mutex_lock(b) - else: - pthread_mutex_lock(b) - pthread_mutex_lock(a) - {.locks: [a, b].}: - try: - body - finally: - pthread_mutex_unlock(a) - pthread_mutex_unlock(b) - ``` - - -Whole routines can also be annotated with a `locks` pragma that takes a lock -level. This then means that the routine may acquire locks of up to this level. -This is essential so that procs can be called within a `locks` section: - - ```nim - proc p() {.locks: 3.} = discard - - var a: TLock[4] - {.locks: [a].}: - # p's locklevel (3) is strictly less than a's (4) so the call is allowed: - p() - ``` - - -As usual, `locks` is an inferred effect and there is a subtype -relation: `proc () {.locks: N.}` is a subtype of `proc () {.locks: M.}` -iff (M <= N). - -The `locks` pragma can also take the special value `"unknown"`. This -is useful in the context of dynamic method dispatching. In the following -example, the compiler can infer a lock level of 0 for the `base` case. -However, one of the overloaded methods calls a procvar which is -potentially locking. Thus, the lock level of calling `g.testMethod` -cannot be inferred statically, leading to compiler warnings. By using -`{.locks: "unknown".}`, the base method can be marked explicitly as -having unknown lock level as well: - - ```nim - type SomeBase* = ref object of RootObj - type SomeDerived* = ref object of SomeBase - memberProc*: proc () - - method testMethod(g: SomeBase) {.base, locks: "unknown".} = discard - method testMethod(g: SomeDerived) = - if g.memberProc != nil: - g.memberProc() - ``` - -This feature may be removed in the future due to its practical difficulties. - - Strict definitions and `out` parameters ======================================= |