mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 01:14:41 +00:00
pi test compiles, but crashes randomly
This commit is contained in:
@@ -197,18 +197,21 @@ proc createNimCreatePromiseCall(prom, threadParam: PNode): PNode =
|
||||
result = newFastAsgnStmt(prom, castExpr)
|
||||
|
||||
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)
|
||||
if barrier != nil:
|
||||
body.add callCodeGenProc("barrierEnter", barrier)
|
||||
body.add varSection
|
||||
if prom != nil:
|
||||
if prom != nil and spawnKind != srByVar:
|
||||
body.add createNimCreatePromiseCall(prom, threadParam.newSymNode)
|
||||
if barrier == nil:
|
||||
body.add callCodeGenProc("nimPromiseCreateCondVar", prom)
|
||||
|
||||
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
|
||||
if fk == promInvalid:
|
||||
localError(f.info, "cannot create a promise of type: " &
|
||||
@@ -471,9 +474,16 @@ proc wrapProcForSpawn*(owner: PSym; n: PNode; retType: PType;
|
||||
objType.addField(field)
|
||||
promField = newDotExpr(scratchObj, field)
|
||||
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,
|
||||
barrierAsExpr, promAsExpr)
|
||||
barrierAsExpr, promAsExpr, spawnKind)
|
||||
result.add callCodeGenProc("nimSpawn", wrapper.newSymNode,
|
||||
genAddrOf(scratchObj.newSymNode))
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ type
|
||||
generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile
|
||||
lastGenericIdx*: int # used for the generics stack
|
||||
hloLoopDetector*: int # used to prevent endless loops in the HLO
|
||||
inParallelStmt*: int
|
||||
|
||||
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
|
||||
result.genericSym = s
|
||||
|
||||
@@ -1615,13 +1615,17 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
|
||||
result = setMs(n, s)
|
||||
var x = n.lastSon
|
||||
if x.kind == nkDo: x = x.sons[bodyPos]
|
||||
inc c.inParallelStmt
|
||||
result.sons[1] = semStmt(c, x)
|
||||
dec c.inParallelStmt
|
||||
of mSpawn:
|
||||
result = setMs(n, s)
|
||||
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:
|
||||
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)
|
||||
|
||||
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))
|
||||
Reference in New Issue
Block a user