pi test compiles, but crashes randomly

This commit is contained in:
Araq 2014-06-01 01:45:44 +02:00
commit 40baebebfe
4 changed files with 43 additions and 6 deletions

View file

@ -197,18 +197,21 @@ proc createNimCreatePromiseCall(prom, threadParam: PNode): PNode =
result = newFastAsgnStmt(prom, castExpr) result = newFastAsgnStmt(prom, castExpr)
proc createWrapperProc(f: PNode; threadParam, argsParam: PSym; proc createWrapperProc(f: PNode; threadParam, argsParam: PSym;
varSection, call, barrier, prom: PNode): PSym = varSection, call, barrier, prom: PNode;
spawnKind: TSpawnResult): PSym =
var body = newNodeI(nkStmtList, f.info) var body = newNodeI(nkStmtList, f.info)
if barrier != nil: if barrier != nil:
body.add callCodeGenProc("barrierEnter", barrier) body.add callCodeGenProc("barrierEnter", barrier)
body.add varSection body.add varSection
if prom != nil: if prom != nil and spawnKind != srByVar:
body.add createNimCreatePromiseCall(prom, threadParam.newSymNode) body.add createNimCreatePromiseCall(prom, threadParam.newSymNode)
if barrier == nil: if barrier == nil:
body.add callCodeGenProc("nimPromiseCreateCondVar", prom) body.add callCodeGenProc("nimPromiseCreateCondVar", prom)
body.add callCodeGenProc("nimArgsPassingDone", threadParam.newSymNode) body.add callCodeGenProc("nimArgsPassingDone", threadParam.newSymNode)
if prom != nil: if spawnKind == srByVar:
body.add newAsgnStmt(genDeref(prom), call)
elif prom != nil:
let fk = prom.typ.sons[1].promiseKind let fk = prom.typ.sons[1].promiseKind
if fk == promInvalid: if fk == promInvalid:
localError(f.info, "cannot create a promise of type: " & localError(f.info, "cannot create a promise of type: " &
@ -471,9 +474,16 @@ proc wrapProcForSpawn*(owner: PSym; n: PNode; retType: PType;
objType.addField(field) objType.addField(field)
promField = newDotExpr(scratchObj, field) promField = newDotExpr(scratchObj, field)
promAsExpr = indirectAccess(castExpr, field, n.info) promAsExpr = indirectAccess(castExpr, field, n.info)
elif spawnKind == srByVar:
var field = newSym(skField, getIdent"prom", owner, n.info)
field.typ = newType(tyPtr, objType.owner)
field.typ.rawAddSon(retType)
objType.addField(field)
promAsExpr = indirectAccess(castExpr, field, n.info)
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), genAddrOf(dest))
let wrapper = createWrapperProc(fn, threadParam, argsParam, varSection, call, let wrapper = createWrapperProc(fn, threadParam, argsParam, varSection, call,
barrierAsExpr, promAsExpr) barrierAsExpr, promAsExpr, spawnKind)
result.add callCodeGenProc("nimSpawn", wrapper.newSymNode, result.add callCodeGenProc("nimSpawn", wrapper.newSymNode,
genAddrOf(scratchObj.newSymNode)) genAddrOf(scratchObj.newSymNode))

View file

@ -91,6 +91,7 @@ type
generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile
lastGenericIdx*: int # used for the generics stack lastGenericIdx*: int # used for the generics stack
hloLoopDetector*: int # used to prevent endless loops in the HLO hloLoopDetector*: int # used to prevent endless loops in the HLO
inParallelStmt*: int
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair = proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
result.genericSym = s result.genericSym = s

View file

@ -1615,12 +1615,16 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
result = setMs(n, s) result = setMs(n, s)
var x = n.lastSon var x = n.lastSon
if x.kind == nkDo: x = x.sons[bodyPos] if x.kind == nkDo: x = x.sons[bodyPos]
inc c.inParallelStmt
result.sons[1] = semStmt(c, x) result.sons[1] = semStmt(c, x)
dec c.inParallelStmt
of mSpawn: of mSpawn:
result = setMs(n, s) result = setMs(n, s)
result.sons[1] = semExpr(c, n.sons[1]) result.sons[1] = semExpr(c, n.sons[1])
# later passes may transform the type 'Promise[T]' back into 'T'
if not result[1].typ.isEmptyType: if not result[1].typ.isEmptyType:
if c.inParallelStmt > 0:
result.typ = result[1].typ
else:
result.typ = createPromise(c, result[1].typ, n.info) result.typ = createPromise(c, result[1].typ, n.info)
else: result = semDirectOp(c, n, flags) else: result = semDirectOp(c, n, flags)

22
tests/parallel/tpi.nim Normal file
View file

@ -0,0 +1,22 @@
import strutils, math, threadpool
proc term(k: float): float = 4 * math.pow(-1, k) / (2*k + 1)
proc piU(n: int): float =
var ch = newSeq[Promise[float]](n+1)
for k in 0..n:
ch[k] = spawn term(float(k))
for k in 0..n:
result += ^ch[k]
proc piS(n: int): float =
var ch = newSeq[float](n+1)
parallel:
for k in 0..ch.high:
ch[k] = spawn term(float(k))
for k in 0..ch.high:
result += ch[k]
echo formatFloat(piU(5000))
echo formatFloat(piS(5000))