pi test compiles, but crashes randomly
This commit is contained in:
parent
9953e0bbca
commit
40baebebfe
4 changed files with 43 additions and 6 deletions
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -1615,13 +1615,17 @@ 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:
|
||||||
result.typ = createPromise(c, result[1].typ, n.info)
|
if c.inParallelStmt > 0:
|
||||||
|
result.typ = result[1].typ
|
||||||
|
else:
|
||||||
|
result.typ = createPromise(c, result[1].typ, n.info)
|
||||||
else: result = semDirectOp(c, n, flags)
|
else: result = semDirectOp(c, n, flags)
|
||||||
|
|
||||||
proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
||||||
|
|
|
||||||
22
tests/parallel/tpi.nim
Normal file
22
tests/parallel/tpi.nim
Normal 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))
|
||||||
Loading…
Add table
Add a link
Reference in a new issue