Skip to content

Commit 69abc8b

Browse files
committed
add std/mutexes
1 parent d0d8a43 commit 69abc8b

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed

changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@
335335

336336
- Added setCurrentException for JS backend.
337337

338+
- Added `std/mutexes`.
339+
338340
## Language changes
339341

340342
- `nimscript` now handles `except Exception as e`.

lib/std/mutexes.nim

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#
2+
#
3+
# Nim's Runtime Library
4+
# (c) Copyright 2021 Nim Contributors
5+
#
6+
# See the file "copying.txt", included in this
7+
# distribution, for details about the copyright.
8+
#
9+
10+
## This module contains Nim's support for mutexes. It provides basic
11+
## destructors supports.
12+
13+
runnableExamples("--threads:on --gc:orc"):
14+
type
15+
PassObj = object
16+
id: int
17+
18+
Pass = ptr PassObj
19+
20+
proc worker(p: Pass) {.thread.} =
21+
var m: Mutex
22+
init(m)
23+
acquire(m)
24+
inc p.id
25+
release(m)
26+
# After leaving the function scope,
27+
# the resource owned by `m` is freed.
28+
29+
var p = cast[Pass](allocShared0(sizeof(PassObj)))
30+
var ts = newSeq[Thread[Pass]](10)
31+
for i in 0..<ts.len:
32+
createThread(ts[i], worker, p)
33+
34+
joinThreads(ts)
35+
assert p.id == 10
36+
37+
38+
import locks, rlocks
39+
40+
type
41+
Mutex* = object ## Mutex; whether this is re-entrant
42+
## or not is unspecified.
43+
lock: Lock
44+
45+
ReentrantMutex* = object ## Reentrant Mutex.
46+
lock: RLock
47+
48+
proc init*(mutex: var Mutex) {.inline.} =
49+
## Initializes the given mutex.
50+
initLock(mutex.lock)
51+
52+
proc `=copy`*(x: var Mutex, y: Mutex) {.error.}
53+
54+
proc `=destroy`*(mutex: var Mutex) {.inline.} =
55+
## Frees the resources associated with the mutex.
56+
deinitLock(mutex.lock)
57+
58+
proc tryAcquire*(mutex: var Mutex): bool {.inline.} =
59+
## Tries to acquire the given mutex. Returns `true` on success.
60+
result = tryAcquire(mutex.lock)
61+
62+
proc acquire*(mutex: var Mutex) {.inline.} =
63+
## Acquires the given mutex.
64+
acquire(mutex.lock)
65+
66+
proc release*(mutex: var Mutex) {.inline.} =
67+
## Releases the given mutex.
68+
release(mutex.lock)
69+
70+
proc init*(mutex: var ReentrantMutex) {.inline.} =
71+
## Initializes the given mutex.
72+
initRLock(mutex.lock)
73+
74+
proc `=copy`*(x: var ReentrantMutex, y: ReentrantMutex) {.error.}
75+
76+
proc `=destroy`*(mutex: var ReentrantMutex) {.inline.} =
77+
## Frees the resources associated with the mutex.
78+
deinitRlock(mutex.lock)
79+
80+
proc tryAcquire*(mutex: var ReentrantMutex): bool {.inline.} =
81+
## Tries to acquire the given mutex. Returns `true` on success.
82+
result = tryAcquire(mutex.lock)
83+
84+
proc acquire*(mutex: var ReentrantMutex) {.inline.} =
85+
## Acquires the given mutex.
86+
acquire(mutex.lock)
87+
88+
proc release*(mutex: var ReentrantMutex) {.inline.} =
89+
## Releases the given mutex.
90+
release(mutex.lock)

tests/stdlib/tmutexes.nim

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
discard """
2+
matrix: "--threads:on --gc:refc; --threads:on --gc:orc"
3+
"""
4+
5+
import std/mutexes
6+
7+
type
8+
PassObj = object
9+
id: int
10+
11+
Pass = ptr PassObj
12+
13+
block:
14+
proc worker(p: Pass) {.thread.} =
15+
var m: Mutex
16+
init(m)
17+
acquire(m)
18+
inc p.id
19+
release(m)
20+
# After leaving the function scope,
21+
# the resource owned by `m` is freed.
22+
23+
var p = cast[Pass](allocShared0(sizeof(PassObj)))
24+
var ts = newSeq[Thread[Pass]](10)
25+
for i in 0..<ts.len:
26+
createThread(ts[i], worker, p)
27+
28+
joinThreads(ts)
29+
doAssert p.id == 10
30+
31+
block:
32+
proc worker(p: Pass) {.thread.} =
33+
var m: ReentrantMutex
34+
init(m)
35+
acquire(m)
36+
acquire(m)
37+
inc p.id
38+
release(m)
39+
release(m)
40+
# After leaving the function scope,
41+
# the resource owned by `m` is freed.
42+
43+
var p = cast[Pass](allocShared0(sizeof(PassObj)))
44+
var ts = newSeq[Thread[Pass]](10)
45+
for i in 0..<ts.len:
46+
createThread(ts[i], worker, p)
47+
48+
joinThreads(ts)
49+
doAssert p.id == 10

0 commit comments

Comments
 (0)