fix #16752: threadvar now works with importcpp types; osx now uses native TLS (--tlsEmulation:off), which can be orders of magnitude faster (#16750)
* osx now uses native TLS, which can be orders of magnitude faster
* add {.cppNonPod.}
* improve test
* changelog, docs, disable part of windows test
This commit is contained in:
parent
3c8fddbc76
commit
e112974920
13 changed files with 194 additions and 13 deletions
37
tests/misc/mtlsemulation.h
Normal file
37
tests/misc/mtlsemulation.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#include <stdio.h>
|
||||
|
||||
struct Foo1 {
|
||||
/*
|
||||
uncommenting would give:
|
||||
error: initializer for thread-local variable must be a constant expression
|
||||
N_LIB_PRIVATE NIM_THREADVAR Foo1 g1__9brEZhPEldbVrNpdRGmWESA;
|
||||
*/
|
||||
// Foo1() noexcept { }
|
||||
|
||||
/*
|
||||
uncommenting would give:
|
||||
error: type of thread-local variable has non-trivial destruction
|
||||
*/
|
||||
// ~Foo1() { }
|
||||
int x;
|
||||
};
|
||||
|
||||
struct Foo2 {
|
||||
Foo2() noexcept { }
|
||||
~Foo2() { }
|
||||
int x;
|
||||
};
|
||||
|
||||
static int ctorCalls = 0;
|
||||
static int dtorCalls = 0;
|
||||
|
||||
struct Foo3 {
|
||||
Foo3() noexcept {
|
||||
ctorCalls = ctorCalls + 1;
|
||||
x = 10;
|
||||
}
|
||||
~Foo3() {
|
||||
dtorCalls = dtorCalls + 1;
|
||||
}
|
||||
int x;
|
||||
};
|
||||
75
tests/misc/ttlsemulation.nim
Normal file
75
tests/misc/ttlsemulation.nim
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
discard """
|
||||
matrix: "-d:nimTtlsemulationCase1 --threads --tlsEmulation:on; -d:nimTtlsemulationCase2 --threads --tlsEmulation:off; -d:nimTtlsemulationCase3 --threads"
|
||||
targets: "c cpp"
|
||||
"""
|
||||
|
||||
#[
|
||||
tests for: `.cppNonPod`, `--tlsEmulation`
|
||||
]#
|
||||
|
||||
import std/sugar
|
||||
|
||||
block:
|
||||
# makes sure the logic in config/nim.cfg or testament doesn't interfere with `--tlsEmulation` so we test the right thing.
|
||||
when defined(nimTtlsemulationCase1):
|
||||
doAssert compileOption("tlsEmulation")
|
||||
elif defined(nimTtlsemulationCase2):
|
||||
doAssert not compileOption("tlsEmulation")
|
||||
elif defined(nimTtlsemulationCase3):
|
||||
when defined(osx):
|
||||
doAssert not compileOption("tlsEmulation")
|
||||
else:
|
||||
doAssert false
|
||||
|
||||
block:
|
||||
proc main1(): int =
|
||||
var g0 {.threadvar.}: int
|
||||
g0.inc
|
||||
g0
|
||||
let s = collect:
|
||||
for i in 0..<3: main1()
|
||||
doAssert s == @[1,2,3]
|
||||
|
||||
when defined(cpp): # bug #16752
|
||||
when defined(windows) and defined(nimTtlsemulationCase2):
|
||||
discard # xxx this failed with exitCode 1
|
||||
else:
|
||||
type Foo1 {.importcpp: "Foo1", header: "mtlsemulation.h".} = object
|
||||
x: cint
|
||||
type Foo2 {.cppNonPod, importcpp: "Foo2", header: "mtlsemulation.h".} = object
|
||||
x: cint
|
||||
|
||||
var ctorCalls {.importcpp.}: cint
|
||||
var dtorCalls {.importcpp.}: cint
|
||||
type Foo3 {.cppNonPod, importcpp: "Foo3", header: "mtlsemulation.h".} = object
|
||||
x: cint
|
||||
|
||||
proc sub(i: int) =
|
||||
var g1 {.threadvar.}: Foo1
|
||||
var g2 {.threadvar.}: Foo2
|
||||
var g3 {.threadvar.}: Foo3
|
||||
discard g1
|
||||
discard g2
|
||||
|
||||
# echo (g3.x, ctorCalls, dtorCalls)
|
||||
when compileOption("tlsEmulation"):
|
||||
# xxx bug
|
||||
discard
|
||||
else:
|
||||
doAssert g3.x.int == 10 + i
|
||||
doAssert ctorCalls == 2
|
||||
doAssert dtorCalls == 1
|
||||
g3.x.inc
|
||||
|
||||
proc main() =
|
||||
doAssert ctorCalls == 0
|
||||
doAssert dtorCalls == 0
|
||||
block:
|
||||
var f3: Foo3
|
||||
doAssert f3.x == 10
|
||||
doAssert ctorCalls == 1
|
||||
doAssert dtorCalls == 1
|
||||
|
||||
for i in 0..<3:
|
||||
sub(i)
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue