mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 22:10:33 +00:00
tester: threading tests added
This commit is contained in:
@@ -92,7 +92,8 @@ proc symChoice(c: PContext, n: PNode, s: PSym): PNode =
|
||||
# appropriately
|
||||
result = newNodeIT(nkSymChoice, n.info, newTypeS(tyNone, c))
|
||||
a = initOverloadIter(o, c, n)
|
||||
while a != nil:
|
||||
while a != nil:
|
||||
incl(a.flags, sfUsed)
|
||||
addSon(result, newSymNode(a))
|
||||
a = nextOverloadIter(o, c, n)
|
||||
|
||||
|
||||
@@ -857,11 +857,11 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
|
||||
of tyOpenArray, tyVarargs:
|
||||
result = (kind == skParam) and typeAllowedAux(marker, t.sons[0], skVar)
|
||||
of tySequence:
|
||||
result = typeAllowedAux(marker, t.sons[0], skVar) or
|
||||
t.sons[0].kind == tyEmpty
|
||||
result = t.sons[0].kind == tyEmpty or
|
||||
typeAllowedAux(marker, t.sons[0], skVar)
|
||||
of tyArray:
|
||||
result = typeAllowedAux(marker, t.sons[1], skVar) or
|
||||
t.sons[1].kind == tyEmpty
|
||||
result = t.sons[1].kind == tyEmpty or
|
||||
typeAllowedAux(marker, t.sons[1], skVar)
|
||||
of tyPtr, tyRef:
|
||||
result = typeAllowedAux(marker, t.sons[0], skVar)
|
||||
of tyArrayConstr, tyTuple, tySet, tyConst, tyMutable, tyIter, tyProxy:
|
||||
|
||||
@@ -127,16 +127,18 @@ template PutImpl() =
|
||||
else:
|
||||
AddImpl()
|
||||
|
||||
template HasKeyOrPutImpl() =
|
||||
var index = RawGet(t, key)
|
||||
if index >= 0:
|
||||
t.data[index].val = val
|
||||
result = true
|
||||
else:
|
||||
if mustRehash(len(t.data), t.counter): Enlarge(t)
|
||||
RawInsert(t, t.data, key, val)
|
||||
inc(t.counter)
|
||||
result = false
|
||||
when false:
|
||||
# not yet used:
|
||||
template HasKeyOrPutImpl() =
|
||||
var index = RawGet(t, key)
|
||||
if index >= 0:
|
||||
t.data[index].val = val
|
||||
result = true
|
||||
else:
|
||||
if mustRehash(len(t.data), t.counter): Enlarge(t)
|
||||
RawInsert(t, t.data, key, val)
|
||||
inc(t.counter)
|
||||
result = false
|
||||
|
||||
proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) =
|
||||
## puts a (key, value)-pair into `t`.
|
||||
|
||||
@@ -120,9 +120,13 @@ proc runThreadTests(r: var TResults, options: string) =
|
||||
#test "threadex"
|
||||
#test "threadring"
|
||||
#test "tthreadanalysis"
|
||||
#test "tthreadanalysis2"
|
||||
#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 -----------------------
|
||||
proc runSpecialTests(r: var TResults, options: string) =
|
||||
runRodFiles(r, options)
|
||||
@@ -131,8 +135,8 @@ proc runSpecialTests(r: var TResults, options: string) =
|
||||
runThreadTests(r, options & " --threads:on")
|
||||
|
||||
proc rejectSpecialTests(r: var TResults, options: string) =
|
||||
|
||||
rejectThreadTests(r, options)
|
||||
|
||||
proc compileSpecialTests(r: var TResults, options: string) =
|
||||
nil
|
||||
compileRodFiles(r, options)
|
||||
|
||||
|
||||
@@ -108,32 +108,35 @@ var
|
||||
peg"{[^(]*} '(' {\d+} ', ' \d+ ') ' ('Error'/'Warning') ':' \s* {.*}"
|
||||
pegOtherError = peg"'Error:' \s* {.*}"
|
||||
pegSuccess = peg"'Hint: operation successful'.*"
|
||||
pegOfInterest = pegLineError / pegOtherError / pegSuccess
|
||||
pegOfInterest = pegLineError / pegOtherError
|
||||
|
||||
proc callCompiler(cmdTemplate, filename, options: string): TSpec =
|
||||
var c = parseCmdLine(cmdTemplate % [options, filename])
|
||||
var p = startProcess(command=c[0], args=c[1.. -1],
|
||||
options={poStdErrToStdOut, poUseShell})
|
||||
var outp = p.outputStream
|
||||
var s = ""
|
||||
var suc = ""
|
||||
var err = ""
|
||||
while running(p) or not atEnd(outp):
|
||||
var x = outp.readLine().string
|
||||
if x =~ pegOfInterest:
|
||||
# `s` should contain the last error/warning message
|
||||
s = x
|
||||
err = x
|
||||
elif x =~ pegSuccess:
|
||||
suc = x
|
||||
close(p)
|
||||
result.msg = ""
|
||||
result.file = ""
|
||||
result.outp = ""
|
||||
result.err = true
|
||||
result.line = -1
|
||||
if s =~ pegLineError:
|
||||
if err =~ pegLineError:
|
||||
result.file = extractFilename(matches[0])
|
||||
result.line = parseInt(matches[1])
|
||||
result.msg = matches[2]
|
||||
elif s =~ pegOtherError:
|
||||
elif err =~ pegOtherError:
|
||||
result.msg = matches[0]
|
||||
elif s =~ pegSuccess:
|
||||
elif suc =~ pegSuccess:
|
||||
result.err = false
|
||||
|
||||
proc initResults: TResults =
|
||||
@@ -328,12 +331,13 @@ proc main() =
|
||||
of "reject":
|
||||
var rejectRes = initResults()
|
||||
reject(rejectRes, "tests/reject", p.cmdLineRest.string)
|
||||
rejectSpecialTests(rejectRes, p.cmdLineRest.string)
|
||||
writeResults(rejectJson, rejectRes)
|
||||
of "compile":
|
||||
var compileRes = initResults()
|
||||
compile(compileRes, "tests/accept/compile/t*.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)
|
||||
of "examples":
|
||||
var compileRes = readResults(compileJson)
|
||||
|
||||
@@ -40,7 +40,7 @@ proc threadFunc(interval: tuple[a, b: int]) {.thread.} =
|
||||
var r = buildTree(i)
|
||||
echoLeTree(r) # for local data
|
||||
root = buildTree(2) # BAD!
|
||||
echoLeTree(root) # and the same for foreign data :-)
|
||||
#echoLeTree(root) # and the same for foreign data :-)
|
||||
|
||||
proc main =
|
||||
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
|
||||
global: string = "test string"
|
||||
t: TThread[string]
|
||||
t: TThread[void]
|
||||
|
||||
proc horrible() {.thread.} =
|
||||
global = "string in thread local heap!"
|
||||
|
||||
Reference in New Issue
Block a user