|
16 | 16 |
|
17 | 17 | #define AREA "ECEVAL"
|
18 | 18 |
|
| 19 | +static obj parallel_execute(obj actions, obj env); |
| 20 | + |
19 | 21 | // ln 182
|
20 | 22 | static obj empty_arglist(void)
|
21 | 23 | {
|
@@ -134,6 +136,8 @@ static obj ecevalgoto(struct core *cr, bool yield)
|
134 | 136 | goto ev_cons_stream;
|
135 | 137 | if (is_time(cr->expr))
|
136 | 138 | goto ev_timed;
|
| 139 | + if (is_parallel_execute(cr->expr)) |
| 140 | + goto ev_concurrent_execute; |
137 | 141 | if (is_ecapply(cr->expr))
|
138 | 142 | goto ev_apply;
|
139 | 143 | if (is_application(cr->expr))
|
@@ -390,6 +394,9 @@ static obj ecevalgoto(struct core *cr, bool yield)
|
390 | 394 | goto go_cont;
|
391 | 395 |
|
392 | 396 | // new
|
| 397 | +ev_concurrent_execute: |
| 398 | + return parallel_execute(cdr(cr->expr), cr->env); |
| 399 | +// new |
393 | 400 | ev_apply:
|
394 | 401 | save(cr->cont, cr);
|
395 | 402 | save(cr->env, cr);
|
@@ -462,14 +469,59 @@ static obj ecevalgoto(struct core *cr, bool yield)
|
462 | 469 |
|
463 | 470 | obj eceval(obj expression, obj _environment)
|
464 | 471 | {
|
465 |
| - obj rslt; |
466 |
| - |
467 | 472 | struct core *cr = dfltcore();
|
468 | 473 | cr->expr = expression;
|
469 | 474 | cr->env = _environment;
|
470 | 475 | cr->cont = ev_return_caller;
|
471 | 476 | save_nogc(ev_eval_dispatch, cr);
|
472 |
| - while (is_yielded(rslt = ecevalgoto(cr, false))) |
473 |
| - ; |
474 |
| - return rslt; |
| 477 | + return ecevalgoto(cr, false); |
| 478 | +} |
| 479 | + |
| 480 | +static int rand_below(int n) |
| 481 | +{ |
| 482 | + return plat_rand() % n; |
| 483 | +} |
| 484 | + |
| 485 | +static obj parallel_execute(obj actions, obj env) |
| 486 | +{ |
| 487 | + static bool running[NCORE]; |
| 488 | + static int free = 0; |
| 489 | + int i, j, runcount; |
| 490 | + |
| 491 | + while (is_pair(actions)) { |
| 492 | + free++; |
| 493 | + if (free == NCORE) { |
| 494 | + return error_arity( |
| 495 | + AREA, |
| 496 | + "parallel-execute takes at most %d expressions", |
| 497 | + (NCORE - 1)); |
| 498 | + } |
| 499 | + struct core *cr = getcore(free); |
| 500 | + running[free] = true; |
| 501 | + cr->expr = car(actions); |
| 502 | + cr->env = env; |
| 503 | + cr->cont = ev_return_caller; |
| 504 | + save_nogc(ev_eval_dispatch, cr); |
| 505 | + actions = cdr(actions); |
| 506 | + } |
| 507 | + |
| 508 | + runcount = free; |
| 509 | + |
| 510 | + while (runcount) { |
| 511 | + for (i = 1; i <= free; i++) { |
| 512 | + if (!running[i]) { |
| 513 | + continue; |
| 514 | + } |
| 515 | + int clicks = rand_below(32); |
| 516 | + for (j = 0; j < clicks; j++) { |
| 517 | + if (!is_yielded(ecevalgoto(getcore(i), true))) { |
| 518 | + running[i] = false; |
| 519 | + runcount--; |
| 520 | + break; |
| 521 | + } |
| 522 | + } |
| 523 | + } |
| 524 | + } |
| 525 | + |
| 526 | + return finished; |
475 | 527 | }
|
0 commit comments