@@ -1313,70 +1313,66 @@ pmap(f) = f()
1313
1313
function pmap (f, lsts... ; err_retry= true , err_stop= false )
1314
1314
len = length (lsts)
1315
1315
np = nprocs ()
1316
- retrycond = Condition ()
1317
1316
1318
1317
results = Dict {Int,Any} ()
1319
- function setresult (idx,v)
1320
- results[idx] = v
1321
- notify (retrycond)
1322
- end
1323
1318
1324
1319
retryqueue = {}
1325
- function retry (idx,v,ex)
1326
- push! (retryqueue, (idx,v,ex))
1327
- notify (retrycond)
1328
- end
1329
-
1330
1320
task_in_err = false
1331
1321
is_task_in_error () = task_in_err
1332
1322
set_task_in_error () = (task_in_err = true )
1333
1323
1334
1324
nextidx = 0
1335
1325
getnextidx () = (nextidx += 1 )
1336
- getcurridx () = nextidx
1337
1326
1338
1327
states = [start (lsts[idx]) for idx in 1 : len]
1339
- function producer ()
1340
- while true
1341
- if (is_task_in_error () && err_stop)
1342
- break
1343
- elseif ! isempty (retryqueue)
1344
- produce (shift! (retryqueue)[1 : 2 ])
1345
- elseif all ([! done (lsts[idx],states[idx]) for idx in 1 : len])
1346
- nxts = [next (lsts[idx],states[idx]) for idx in 1 : len]
1347
- map (idx-> states[idx]= nxts[idx][2 ], 1 : len)
1348
- nxtvals = [x[1 ] for x in nxts]
1349
- produce ((getnextidx (), nxtvals))
1350
- elseif (length (results) == getcurridx ())
1351
- break
1352
- else
1353
- wait (retrycond)
1354
- end
1328
+ function getnext_tasklet ()
1329
+ if is_task_in_error () && err_stop
1330
+ return nothing
1331
+ elseif all ([! done (lsts[idx],states[idx]) for idx in 1 : len])
1332
+ nxts = [next (lsts[idx],states[idx]) for idx in 1 : len]
1333
+ map (idx-> states[idx]= nxts[idx][2 ], 1 : len)
1334
+ nxtvals = [x[1 ] for x in nxts]
1335
+ return (getnextidx (), nxtvals)
1336
+
1337
+ elseif ! isempty (retryqueue)
1338
+ return shift! (retryqueue)
1339
+ else
1340
+ return nothing
1355
1341
end
1356
1342
end
1357
1343
1358
- pt = Task (producer)
1359
1344
@sync begin
1360
1345
for p= 1 : np
1361
1346
wpid = PGRP. workers[p]. id
1362
1347
if wpid != myid () || np == 1
1363
1348
@async begin
1364
- for (idx,nxtvals) in pt
1349
+ tasklet = getnext_tasklet ()
1350
+ while (tasklet != nothing )
1351
+ (idx, fvals) = tasklet
1365
1352
try
1366
- result = remotecall_fetch (wpid, f, nxtvals... )
1367
- isa (result, Exception) ? ((wpid == myid ()) ? rethrow (result) : throw (result)) : setresult (idx, result)
1353
+ result = remotecall_fetch (wpid, f, fvals... )
1354
+ if isa (result, Exception)
1355
+ ((wpid == myid ()) ? rethrow (result) : throw (result))
1356
+ else
1357
+ results[idx] = result
1358
+ end
1368
1359
catch ex
1369
- err_retry ? retry (idx,nxtvals,ex) : setresult (idx, ex)
1360
+ if err_retry
1361
+ push! (retryqueue, (idx,fvals, ex))
1362
+ else
1363
+ results[idx] = ex
1364
+ end
1370
1365
set_task_in_error ()
1371
1366
break # remove this worker from accepting any more tasks
1372
1367
end
1368
+
1369
+ tasklet = getnext_tasklet ()
1373
1370
end
1374
1371
end
1375
1372
end
1376
1373
end
1377
1374
end
1378
1375
1379
- ! istaskdone (pt) && throwto (pt, InterruptException ())
1380
1376
for failure in retryqueue
1381
1377
results[failure[1 ]] = failure[3 ]
1382
1378
end
0 commit comments