tester: threading tests added
This commit is contained in:
parent
a497b4d1cf
commit
62aa8bed3b
9 changed files with 96 additions and 29 deletions
|
|
@ -93,6 +93,7 @@ proc symChoice(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
result = newNodeIT(nkSymChoice, n.info, newTypeS(tyNone, c))
|
result = newNodeIT(nkSymChoice, n.info, newTypeS(tyNone, c))
|
||||||
a = initOverloadIter(o, c, n)
|
a = initOverloadIter(o, c, n)
|
||||||
while a != nil:
|
while a != nil:
|
||||||
|
incl(a.flags, sfUsed)
|
||||||
addSon(result, newSymNode(a))
|
addSon(result, newSymNode(a))
|
||||||
a = nextOverloadIter(o, c, n)
|
a = nextOverloadIter(o, c, n)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -857,11 +857,11 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
|
||||||
of tyOpenArray, tyVarargs:
|
of tyOpenArray, tyVarargs:
|
||||||
result = (kind == skParam) and typeAllowedAux(marker, t.sons[0], skVar)
|
result = (kind == skParam) and typeAllowedAux(marker, t.sons[0], skVar)
|
||||||
of tySequence:
|
of tySequence:
|
||||||
result = typeAllowedAux(marker, t.sons[0], skVar) or
|
result = t.sons[0].kind == tyEmpty or
|
||||||
t.sons[0].kind == tyEmpty
|
typeAllowedAux(marker, t.sons[0], skVar)
|
||||||
of tyArray:
|
of tyArray:
|
||||||
result = typeAllowedAux(marker, t.sons[1], skVar) or
|
result = t.sons[1].kind == tyEmpty or
|
||||||
t.sons[1].kind == tyEmpty
|
typeAllowedAux(marker, t.sons[1], skVar)
|
||||||
of tyPtr, tyRef:
|
of tyPtr, tyRef:
|
||||||
result = typeAllowedAux(marker, t.sons[0], skVar)
|
result = typeAllowedAux(marker, t.sons[0], skVar)
|
||||||
of tyArrayConstr, tyTuple, tySet, tyConst, tyMutable, tyIter, tyProxy:
|
of tyArrayConstr, tyTuple, tySet, tyConst, tyMutable, tyIter, tyProxy:
|
||||||
|
|
|
||||||
|
|
@ -127,16 +127,18 @@ template PutImpl() =
|
||||||
else:
|
else:
|
||||||
AddImpl()
|
AddImpl()
|
||||||
|
|
||||||
template HasKeyOrPutImpl() =
|
when false:
|
||||||
var index = RawGet(t, key)
|
# not yet used:
|
||||||
if index >= 0:
|
template HasKeyOrPutImpl() =
|
||||||
t.data[index].val = val
|
var index = RawGet(t, key)
|
||||||
result = true
|
if index >= 0:
|
||||||
else:
|
t.data[index].val = val
|
||||||
if mustRehash(len(t.data), t.counter): Enlarge(t)
|
result = true
|
||||||
RawInsert(t, t.data, key, val)
|
else:
|
||||||
inc(t.counter)
|
if mustRehash(len(t.data), t.counter): Enlarge(t)
|
||||||
result = false
|
RawInsert(t, t.data, key, val)
|
||||||
|
inc(t.counter)
|
||||||
|
result = false
|
||||||
|
|
||||||
proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) =
|
proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) =
|
||||||
## puts a (key, value)-pair into `t`.
|
## puts a (key, value)-pair into `t`.
|
||||||
|
|
|
||||||
|
|
@ -120,9 +120,13 @@ proc runThreadTests(r: var TResults, options: string) =
|
||||||
#test "threadex"
|
#test "threadex"
|
||||||
#test "threadring"
|
#test "threadring"
|
||||||
#test "tthreadanalysis"
|
#test "tthreadanalysis"
|
||||||
#test "tthreadanalysis2"
|
|
||||||
#test "tthreadsort"
|
#test "tthreadsort"
|
||||||
|
|
||||||
|
proc rejectThreadTests(r: var TResults, options: string) =
|
||||||
|
rejectSingleTest(r, "tests/threads/tthreadanalysis2", options)
|
||||||
|
rejectSingleTest(r, "tests/threads/tthreadanalysis3", options)
|
||||||
|
rejectSingleTest(r, "tests/threads/tthreadheapviolation1", options)
|
||||||
|
|
||||||
# ------------------------- register special tests here -----------------------
|
# ------------------------- register special tests here -----------------------
|
||||||
proc runSpecialTests(r: var TResults, options: string) =
|
proc runSpecialTests(r: var TResults, options: string) =
|
||||||
runRodFiles(r, options)
|
runRodFiles(r, options)
|
||||||
|
|
@ -131,8 +135,8 @@ proc runSpecialTests(r: var TResults, options: string) =
|
||||||
runThreadTests(r, options & " --threads:on")
|
runThreadTests(r, options & " --threads:on")
|
||||||
|
|
||||||
proc rejectSpecialTests(r: var TResults, options: string) =
|
proc rejectSpecialTests(r: var TResults, options: string) =
|
||||||
|
rejectThreadTests(r, options)
|
||||||
|
|
||||||
proc compileSpecialTests(r: var TResults, options: string) =
|
proc compileSpecialTests(r: var TResults, options: string) =
|
||||||
nil
|
compileRodFiles(r, options)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,32 +108,35 @@ var
|
||||||
peg"{[^(]*} '(' {\d+} ', ' \d+ ') ' ('Error'/'Warning') ':' \s* {.*}"
|
peg"{[^(]*} '(' {\d+} ', ' \d+ ') ' ('Error'/'Warning') ':' \s* {.*}"
|
||||||
pegOtherError = peg"'Error:' \s* {.*}"
|
pegOtherError = peg"'Error:' \s* {.*}"
|
||||||
pegSuccess = peg"'Hint: operation successful'.*"
|
pegSuccess = peg"'Hint: operation successful'.*"
|
||||||
pegOfInterest = pegLineError / pegOtherError / pegSuccess
|
pegOfInterest = pegLineError / pegOtherError
|
||||||
|
|
||||||
proc callCompiler(cmdTemplate, filename, options: string): TSpec =
|
proc callCompiler(cmdTemplate, filename, options: string): TSpec =
|
||||||
var c = parseCmdLine(cmdTemplate % [options, filename])
|
var c = parseCmdLine(cmdTemplate % [options, filename])
|
||||||
var p = startProcess(command=c[0], args=c[1.. -1],
|
var p = startProcess(command=c[0], args=c[1.. -1],
|
||||||
options={poStdErrToStdOut, poUseShell})
|
options={poStdErrToStdOut, poUseShell})
|
||||||
var outp = p.outputStream
|
var outp = p.outputStream
|
||||||
var s = ""
|
var suc = ""
|
||||||
|
var err = ""
|
||||||
while running(p) or not atEnd(outp):
|
while running(p) or not atEnd(outp):
|
||||||
var x = outp.readLine().string
|
var x = outp.readLine().string
|
||||||
if x =~ pegOfInterest:
|
if x =~ pegOfInterest:
|
||||||
# `s` should contain the last error/warning message
|
# `s` should contain the last error/warning message
|
||||||
s = x
|
err = x
|
||||||
|
elif x =~ pegSuccess:
|
||||||
|
suc = x
|
||||||
close(p)
|
close(p)
|
||||||
result.msg = ""
|
result.msg = ""
|
||||||
result.file = ""
|
result.file = ""
|
||||||
result.outp = ""
|
result.outp = ""
|
||||||
result.err = true
|
result.err = true
|
||||||
result.line = -1
|
result.line = -1
|
||||||
if s =~ pegLineError:
|
if err =~ pegLineError:
|
||||||
result.file = extractFilename(matches[0])
|
result.file = extractFilename(matches[0])
|
||||||
result.line = parseInt(matches[1])
|
result.line = parseInt(matches[1])
|
||||||
result.msg = matches[2]
|
result.msg = matches[2]
|
||||||
elif s =~ pegOtherError:
|
elif err =~ pegOtherError:
|
||||||
result.msg = matches[0]
|
result.msg = matches[0]
|
||||||
elif s =~ pegSuccess:
|
elif suc =~ pegSuccess:
|
||||||
result.err = false
|
result.err = false
|
||||||
|
|
||||||
proc initResults: TResults =
|
proc initResults: TResults =
|
||||||
|
|
@ -328,12 +331,13 @@ proc main() =
|
||||||
of "reject":
|
of "reject":
|
||||||
var rejectRes = initResults()
|
var rejectRes = initResults()
|
||||||
reject(rejectRes, "tests/reject", p.cmdLineRest.string)
|
reject(rejectRes, "tests/reject", p.cmdLineRest.string)
|
||||||
|
rejectSpecialTests(rejectRes, p.cmdLineRest.string)
|
||||||
writeResults(rejectJson, rejectRes)
|
writeResults(rejectJson, rejectRes)
|
||||||
of "compile":
|
of "compile":
|
||||||
var compileRes = initResults()
|
var compileRes = initResults()
|
||||||
compile(compileRes, "tests/accept/compile/t*.nim", p.cmdLineRest.string)
|
compile(compileRes, "tests/accept/compile/t*.nim", p.cmdLineRest.string)
|
||||||
compile(compileRes, "tests/ecmas.nim", p.cmdLineRest.string)
|
compile(compileRes, "tests/ecmas.nim", p.cmdLineRest.string)
|
||||||
compileRodFiles(compileRes, p.cmdLineRest.string)
|
compileSpecialTests(compileRes, p.cmdLineRest.string)
|
||||||
writeResults(compileJson, compileRes)
|
writeResults(compileJson, compileRes)
|
||||||
of "examples":
|
of "examples":
|
||||||
var compileRes = readResults(compileJson)
|
var compileRes = readResults(compileJson)
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ proc threadFunc(interval: tuple[a, b: int]) {.thread.} =
|
||||||
var r = buildTree(i)
|
var r = buildTree(i)
|
||||||
echoLeTree(r) # for local data
|
echoLeTree(r) # for local data
|
||||||
root = buildTree(2) # BAD!
|
root = buildTree(2) # BAD!
|
||||||
echoLeTree(root) # and the same for foreign data :-)
|
#echoLeTree(root) # and the same for foreign data :-)
|
||||||
|
|
||||||
proc main =
|
proc main =
|
||||||
root = buildTree(5)
|
root = buildTree(5)
|
||||||
|
|
|
||||||
51
tests/threads/tthreadanalysis3.nim
Normal file
51
tests/threads/tthreadanalysis3.nim
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
discard """
|
||||||
|
file: "tthreadanalysis3.nim"
|
||||||
|
line: 35
|
||||||
|
errormsg: "write to foreign heap"
|
||||||
|
cmd: "nimrod cc --hints:on --threads:on $# $#"
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
var
|
||||||
|
thr: array [0..5, TThread[tuple[a, b: int]]]
|
||||||
|
|
||||||
|
proc doNothing() = nil
|
||||||
|
|
||||||
|
type
|
||||||
|
PNode = ref TNode
|
||||||
|
TNode = object {.pure.}
|
||||||
|
le, ri: PNode
|
||||||
|
data: string
|
||||||
|
|
||||||
|
var
|
||||||
|
root: PNode
|
||||||
|
|
||||||
|
proc buildTree(depth: int): PNode =
|
||||||
|
if depth == 3: return nil
|
||||||
|
new(result)
|
||||||
|
result.le = buildTree(depth-1)
|
||||||
|
result.ri = buildTree(depth-1)
|
||||||
|
result.data = $depth
|
||||||
|
|
||||||
|
proc echoLeTree(n: PNode) =
|
||||||
|
var it = n
|
||||||
|
while it != nil:
|
||||||
|
echo it.data
|
||||||
|
it = it.le
|
||||||
|
|
||||||
|
proc threadFunc(interval: tuple[a, b: int]) {.thread.} =
|
||||||
|
doNothing()
|
||||||
|
for i in interval.a..interval.b:
|
||||||
|
var r = buildTree(i)
|
||||||
|
echoLeTree(r) # for local data
|
||||||
|
echoLeTree(root) # and the same for foreign data :-)
|
||||||
|
|
||||||
|
proc main =
|
||||||
|
root = buildTree(5)
|
||||||
|
for i in 0..high(thr):
|
||||||
|
createThread(thr[i], threadFunc, (i*100, i*100+50))
|
||||||
|
joinThreads(thr)
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
|
discard """
|
||||||
|
line: 12
|
||||||
|
errormsg: "write to foreign heap"
|
||||||
|
cmd: "nimrod cc --hints:on --threads:on $# $#"
|
||||||
|
"""
|
||||||
|
|
||||||
var
|
var
|
||||||
global: string = "test string"
|
global: string = "test string"
|
||||||
t: TThread[string]
|
t: TThread[void]
|
||||||
|
|
||||||
proc horrible() {.thread.} =
|
proc horrible() {.thread.} =
|
||||||
global = "string in thread local heap!"
|
global = "string in thread local heap!"
|
||||||
|
|
|
||||||
3
todo.txt
3
todo.txt
|
|
@ -2,8 +2,7 @@ Version 0.8.14
|
||||||
==============
|
==============
|
||||||
|
|
||||||
- optimize unused constants away (affected by HLO)
|
- optimize unused constants away (affected by HLO)
|
||||||
- fix actors.nim: fix thread local storage emulation;
|
- fix thread tests
|
||||||
add thread tests to test suite
|
|
||||||
|
|
||||||
version 0.9.0
|
version 0.9.0
|
||||||
=============
|
=============
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue