Support thread-local variables declared inside procs; fixes #7565

This commit is contained in:
Zahary Karadjov
2018-04-29 13:50:21 +03:00
committed by Andreas Rumpf
parent b0d85b0adf
commit ae5c946a32
4 changed files with 85 additions and 3 deletions

View File

@@ -103,6 +103,9 @@
- The command syntax now supports keyword arguments after the first comma.
- Thread-local variables can now be declared inside procs. This implies all
the effects of the `global` pragma.
### Tool changes
- ``jsondoc2`` has been renamed ``jsondoc``, similar to how ``doc2`` was renamed

View File

@@ -777,7 +777,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
incl(sym.flags, sfRegister)
of wThreadVar:
noVal(it)
incl(sym.flags, sfThread)
incl(sym.flags, {sfThread, sfGlobal})
of wDeadCodeElimUnused: discard # deprecated, dead code elim always on
of wNoForward: pragmaNoForward(c, it)
of wReorder: pragmaNoForward(c, it, sfReorder)

View File

@@ -7798,8 +7798,9 @@ Future directions:
Threadvar pragma
----------------
A global variable can be marked with the ``threadvar`` pragma; it is
a `thread-local`:idx: variable then:
A variable can be marked with the ``threadvar`` pragma, which makes it a
`thread-local`:idx: variable; Additionally, this implies all the effects
of the ``global`` pragma.
.. code-block:: nim
var checkpoints* {.threadvar.}: seq[string]

View File

@@ -0,0 +1,78 @@
discard """
output: '''
10
1111
1222
3030303
3060606
6060606
6121212
3030903
3061206
3031503
3061806
5050505
5101010
'''
"""
import typetraits
var tls1 {.threadvar.}: int
var g0: int
var g1 {.global.}: int
proc customInc(x: var int, delta: int) =
x += delta
customInc(tls1, 10)
echo tls1
proc nonGenericProc: int =
var local: int
var nonGenericTls {.threadvar.}: int
var nonGenericGlobal {.global.}: int
var nonGenericMixedPragmas {.global, threadvar.}: int
customInc local, 1000
customInc nonGenericTls, 1
customInc nonGenericGlobal, 10
customInc nonGenericMixedPragmas, 100
return local + nonGenericTls + nonGenericGlobal + nonGenericMixedPragmas
proc genericProc(T: typedesc): int =
var local: int
var genericTls {.threadvar.}: int
var genericGlobal {.global.}: int
var genericMixedPragmas {.global, threadvar.}: int
customInc local, T.name.len * 1000000
customInc genericTls, T.name.len * 1
customInc genericGlobal, T.name.len * 100
customInc genericMixedPragmas, T.name.len * 10000
return local + genericTls + genericGlobal + genericMixedPragmas
echo nonGenericProc()
echo nonGenericProc()
echo genericProc(int)
echo genericProc(int)
echo genericProc(string)
echo genericProc(string)
proc echoInThread[T]() {.thread.} =
echo genericProc(T)
echo genericProc(T)
proc newEchoThread(T: typedesc) =
var t: Thread[void]
createThread(t, echoInThread[T])
joinThreads(t)
newEchoThread int
newEchoThread int
newEchoThread float