Skip to content

Commit 403776c

Browse files
committed
Add: parallel eval (called execute)
1 parent e3684b8 commit 403776c

File tree

9 files changed

+93
-19
lines changed

9 files changed

+93
-19
lines changed

src/eceval.c

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
#define AREA "ECEVAL"
1818

19+
static obj parallel_execute(obj actions, obj env);
20+
1921
// ln 182
2022
static obj empty_arglist(void)
2123
{
@@ -134,6 +136,8 @@ static obj ecevalgoto(struct core *cr, bool yield)
134136
goto ev_cons_stream;
135137
if (is_time(cr->expr))
136138
goto ev_timed;
139+
if (is_parallel_execute(cr->expr))
140+
goto ev_concurrent_execute;
137141
if (is_ecapply(cr->expr))
138142
goto ev_apply;
139143
if (is_application(cr->expr))
@@ -390,6 +394,9 @@ static obj ecevalgoto(struct core *cr, bool yield)
390394
goto go_cont;
391395

392396
// new
397+
ev_concurrent_execute:
398+
return parallel_execute(cdr(cr->expr), cr->env);
399+
// new
393400
ev_apply:
394401
save(cr->cont, cr);
395402
save(cr->env, cr);
@@ -462,14 +469,59 @@ static obj ecevalgoto(struct core *cr, bool yield)
462469

463470
obj eceval(obj expression, obj _environment)
464471
{
465-
obj rslt;
466-
467472
struct core *cr = dfltcore();
468473
cr->expr = expression;
469474
cr->env = _environment;
470475
cr->cont = ev_return_caller;
471476
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;
475527
}

src/mceval.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,3 +614,8 @@ obj quasi_to_combination(obj exp)
614614
{
615615
return quasi_dat(cadr(exp));
616616
}
617+
618+
bool is_parallel_execute(obj exp)
619+
{
620+
return is_tagged_list(exp, parallel_execute_s);
621+
}

src/mceval.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,6 @@ bool is_amb(obj exp);
7070
bool is_quasiquote(obj exp);
7171
obj quasi_to_combination(obj exp);
7272

73+
bool is_parallel_execute(obj exp);
74+
7375
#endif

src/obj.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,15 @@ const obj cons_stream = SYMBOL("cons-stream");
250250
SYMBOL_VAR(define)
251251
SYMBOL_VAR(delay)
252252
const obj else_s = SYMBOL("else");
253+
SYMBOL_VAR(finished)
253254
const obj if_s = SYMBOL("if");
255+
SYMBOL_VAR(lambda)
254256
SYMBOL_VAR(let)
255257
SYMBOL_VAR(letrec)
256258
const obj letstar = SYMBOL("let*");
257259
const obj memo_proc = SYMBOL("memo-proc");
258-
SYMBOL_VAR(lambda)
259260
const obj or_s = SYMBOL("or");
261+
const obj parallel_execute_s = SYMBOL("parallel-execute");
260262
SYMBOL_VAR(quasiquote)
261263
SYMBOL_VAR(quote)
262264
const obj set = SYMBOL("set!");

src/obj.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,15 @@ extern const obj cons_stream;
132132
extern const obj define;
133133
extern const obj delay;
134134
extern const obj else_s;
135-
extern const obj failed;
135+
extern const obj finished;
136136
extern const obj if_s;
137+
extern const obj lambda;
137138
extern const obj let;
138139
extern const obj letrec;
139140
extern const obj letstar;
140-
extern const obj lambda;
141141
extern const obj memo_proc;
142142
extern const obj or_s;
143+
extern const obj parallel_execute_s;
143144
extern const obj quasiquote;
144145
extern const obj quote;
145146
extern const obj set;

src/primproc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ errno_t rand_s(unsigned *);
423423
#define PLAT_RAND_MAX RAND_MAX
424424
#endif
425425

426-
static Integer plat_rand(void)
426+
Integer plat_rand(void)
427427
{
428428
#ifdef _WIN32
429429
unsigned r;

src/primproc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ obj arctan(const obj);
2727
obj flr(const obj);
2828
obj sqroot(const obj);
2929

30+
Integer plat_rand(void);
3031
obj rnd(const obj);
3132
obj runtime(const obj);
3233
obj ticks(const obj);

src/register.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77

88
#define AREA "REGISTER"
99

10-
static struct core cores[ncore];
10+
static struct core cores[NCORE];
1111

1212
// global-env
1313
obj ambenv;
1414
obj anenv;
1515
obj svtmp;
1616

17-
const int rootlen = nother + ncore;
17+
const int rootlen = NOTHER + NCORE;
1818
static obj rootlst;
1919

2020
static void init(void)
@@ -25,14 +25,14 @@ static void init(void)
2525

2626
rootlst = emptylst;
2727
int i, j;
28-
for (i = 0; i < ncore; i++) {
28+
for (i = 0; i < NCORE; i++) {
2929
obj reglst = emptylst;
30-
for (j = 0; j < nreg; j++) {
30+
for (j = 0; j < NREG; j++) {
3131
reglst = cons(unspecified, reglst);
3232
}
3333
rootlst = cons(reglst, rootlst);
3434
}
35-
for (i = 0; i < nother; i++) {
35+
for (i = 0; i < NOTHER; i++) {
3636
rootlst = cons(unspecified, rootlst);
3737
}
3838
initdone = true;
@@ -55,7 +55,7 @@ obj getroot(void)
5555
set_car(lst, svtmp);
5656
lst = cdr(lst);
5757

58-
for (i = 0; i < ncore; i++, lst = cdr(lst)) {
58+
for (i = 0; i < NCORE; i++, lst = cdr(lst)) {
5959
struct core *cr = &cores[i];
6060
obj reglst = car(lst);
6161

@@ -104,7 +104,7 @@ void setroot(obj rlst)
104104
svtmp = car(lst);
105105
lst = cdr(lst);
106106

107-
for (i = 0; i < ncore; i++, lst = cdr(lst)) {
107+
for (i = 0; i < NCORE; i++, lst = cdr(lst)) {
108108
struct core *cr = &cores[i];
109109
obj reglst = car(lst);
110110

@@ -134,6 +134,16 @@ void setroot(obj rlst)
134134
}
135135
}
136136

137+
struct core *getcore(int idx)
138+
{
139+
if (idx < 0 || NCORE <= idx) {
140+
eprintf(AREA, "Invalid core index: %d", idx);
141+
exit(1);
142+
}
143+
init();
144+
return &cores[idx];
145+
}
146+
137147
struct core *dfltcore(void)
138148
{
139149
init();

src/register.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,16 @@ struct core {
1414
obj unev; // 7
1515
obj val; // 8
1616
};
17-
#define nreg 8
18-
#define ncore 16
17+
#define NREG 8
18+
#define NCORE 16
1919

2020
// global-env // 1
2121
extern obj ambenv; // 2
2222
extern obj anenv; // 3
2323
extern obj svtmp; // 4
24-
#define nother 4
24+
#define NOTHER 4
2525

26+
struct core *getcore(int);
2627
struct core *dfltcore(void);
2728
obj getroot(void);
2829
void setroot(obj);

0 commit comments

Comments
 (0)