Fixed mutex usage in SharedList and SharedTable. Closes #6988 (#6990)

This commit is contained in:
Yuriy Glukhov 2017-12-31 11:28:51 +03:00 • committed by Andreas Rumpf
commit d1e10f9aa3
6 changed files with 31 additions and 13 deletions

View file

@ -73,10 +73,10 @@ proc add*[A](x: var SharedList[A]; y: A) =
node.d[node.dataLen] = y node.d[node.dataLen] = y
inc(node.dataLen) inc(node.dataLen)
proc initSharedList*[A](): SharedList[A] = proc init*[A](t: var SharedList[A]) =
initLock result.lock initLock t.lock
result.head = nil t.head = nil
result.tail = nil t.tail = nil
proc clear*[A](t: var SharedList[A]) = proc clear*[A](t: var SharedList[A]) =
withLock(t): withLock(t):
@ -92,4 +92,11 @@ proc deinitSharedList*[A](t: var SharedList[A]) =
clear(t) clear(t)
deinitLock t.lock deinitLock t.lock
proc initSharedList*[A](): SharedList[A] {.deprecated.} =
## Deprecated. Use `init` instead.
## This is not posix compliant, may introduce undefined behavior.
initLock result.lock
result.head = nil
result.tail = nil
{.pop.} {.pop.}

View file

@ -192,19 +192,29 @@ proc del*[A, B](t: var SharedTable[A, B], key: A) =
withLock t: withLock t:
delImpl() delImpl()
proc initSharedTable*[A, B](initialSize=64): SharedTable[A, B] = proc init*[A, B](t: var SharedTable[A, B], initialSize=64) =
## creates a new hash table that is empty. ## creates a new hash table that is empty.
## ##
## `initialSize` needs to be a power of two. If you need to accept runtime ## `initialSize` needs to be a power of two. If you need to accept runtime
## values for this you could use the ``nextPowerOfTwo`` proc from the ## values for this you could use the ``nextPowerOfTwo`` proc from the
## `math <math.html>`_ module or the ``rightSize`` proc from this module. ## `math <math.html>`_ module or the ``rightSize`` proc from this module.
assert isPowerOfTwo(initialSize) assert isPowerOfTwo(initialSize)
result.counter = 0 t.counter = 0
result.dataLen = initialSize t.dataLen = initialSize
result.data = cast[KeyValuePairSeq[A, B]](allocShared0( t.data = cast[KeyValuePairSeq[A, B]](allocShared0(
sizeof(KeyValuePair[A, B]) * initialSize)) sizeof(KeyValuePair[A, B]) * initialSize))
initLock result.lock initLock t.lock
proc deinitSharedTable*[A, B](t: var SharedTable[A, B]) = proc deinitSharedTable*[A, B](t: var SharedTable[A, B]) =
deallocShared(t.data) deallocShared(t.data)
deinitLock t.lock deinitLock t.lock
proc initSharedTable*[A, B](initialSize=64): SharedTable[A, B] {.deprecated.} =
## Deprecated. Use `init` instead.
## This is not posix compliant, may introduce undefined behavior.
assert isPowerOfTwo(initialSize)
result.counter = 0
result.dataLen = initialSize
result.data = cast[KeyValuePairSeq[A, B]](allocShared0(
sizeof(KeyValuePair[A, B]) * initialSize))
initLock result.lock

View file

@ -318,7 +318,7 @@ proc initGC() =
init(gch.marked) init(gch.marked)
init(gch.additionalRoots) init(gch.additionalRoots)
when hasThreadSupport: when hasThreadSupport:
gch.toDispose = initSharedList[pointer]() init(gch.toDispose)
when useMarkForDebug or useBackupGc: when useMarkForDebug or useBackupGc:
type type

View file

@ -133,7 +133,7 @@ proc initGC() =
init(gch.additionalRoots) init(gch.additionalRoots)
init(gch.greyStack) init(gch.greyStack)
when hasThreadSupport: when hasThreadSupport:
gch.toDispose = initSharedList[pointer]() init(gch.toDispose)
# Which color to use for new objects is tricky: When we're marking, # Which color to use for new objects is tricky: When we're marking,
# they have to be *white* so that everything is marked that is only # they have to be *white* so that everything is marked that is only

View file

@ -233,7 +233,7 @@ proc initGC() =
init(gch.allocated) init(gch.allocated)
init(gch.marked) init(gch.marked)
when hasThreadSupport: when hasThreadSupport:
gch.toDispose = initSharedList[pointer]() init(gch.toDispose)
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.benign.} = proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.benign.} =
var d = cast[ByteAddress](dest) var d = cast[ByteAddress](dest)

View file

@ -213,7 +213,8 @@ block clearCountTableTest:
assert t.len() == 0 assert t.len() == 0
block withKeyTest: block withKeyTest:
var t = initSharedTable[int, int]() var t: SharedTable[int, int]
t.init()
t.withKey(1) do (k: int, v: var int, pairExists: var bool): t.withKey(1) do (k: int, v: var int, pairExists: var bool):
assert(v == 0) assert(v == 0)
pairExists = true pairExists = true