Skip to content

Commit c02ba00

Browse files
committed
Add: serializer
1 parent f23daf2 commit c02ba00

File tree

6 files changed

+62
-2
lines changed

6 files changed

+62
-2
lines changed

src/custom.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,37 @@ static obj add_extras(int ex, obj env)
278278
define_variable(of_identifier("set-cdr!"),
279279
of_function(set_cdr_p), env);
280280
}
281+
if (ex >= 338) {
282+
evalstr("(define (clear! cell)"
283+
" (set-car! cell false))",
284+
env);
285+
evalstr("(define (test-and-set! cell)"
286+
" (__%%lock"
287+
" (if (car cell)"
288+
" true"
289+
" (begin (set-car! cell true)"
290+
" false))))",
291+
env);
292+
evalstr("(define (make-mutex)"
293+
" (let ((cell (list false))) "
294+
" (define (the-mutex m)"
295+
" (cond ((eq? m 'acquire)"
296+
" (if (test-and-set! cell)"
297+
" (the-mutex 'acquire)))"
298+
" ((eq? m 'release) (clear! cell))))"
299+
" the-mutex))",
300+
env);
301+
evalstr("(define (make-serializer)"
302+
" (let ((mutex (make-mutex)))"
303+
" (lambda (p)"
304+
" (define (serialized-p . args)"
305+
" (mutex 'acquire)"
306+
" (let ((val (apply p args)))"
307+
" (mutex 'release)"
308+
" val))"
309+
" serialized-p)))",
310+
env);
311+
}
281312
if (ex >= 350) {
282313
evalstr("(define (force delayed-obj) (delayed-obj))", env);
283314
add_stream(env);

src/eceval.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ static void set_proc_name(struct core *cr)
8888

8989
static obj ecevalgoto(struct core *cr, bool yield)
9090
{
91+
bool locked = false;
9192
obj go_obj = restore(cr);
9293
goto go_obj;
9394

@@ -141,6 +142,8 @@ static obj ecevalgoto(struct core *cr, bool yield)
141142
goto ev_parallel_eval;
142143
if (is_parallel_execute(cr->expr))
143144
goto ev_parallel_execute;
145+
if (is_lock(cr->expr))
146+
goto ev_lock;
144147
if (is_ecapply(cr->expr))
145148
goto ev_apply;
146149
if (is_application(cr->expr))
@@ -407,6 +410,21 @@ static obj ecevalgoto(struct core *cr, bool yield)
407410
go_obj = cr->cont;
408411
goto go_obj;
409412

413+
ev_lock:
414+
if (locked) {
415+
return error_internal(AREA, "Attempted to lock twice");
416+
}
417+
save(cr->cont, cr);
418+
locked = true;
419+
cr->cont = ev_lock_done;
420+
cr->expr = cons(begin, cdr(cr->expr));
421+
goto eval_dispatch;
422+
423+
ev_lock_done:
424+
cr->cont = restore(cr);
425+
locked = false;
426+
goto go_cont;
427+
410428
// new
411429
ev_apply:
412430
save(cr->cont, cr);
@@ -442,13 +460,12 @@ static obj ecevalgoto(struct core *cr, bool yield)
442460
return error_eval(AREA, "Unknown procedure type: %s", errstr(cr->proc));
443461

444462
go_cont:
445-
if (yield) {
463+
if (yield && !locked) {
446464
save(cr->cont, cr);
447465
return yielded;
448466
}
449467
go_obj = cr->cont;
450468
go_obj:
451-
// printf("obj: %s\n", to_string(go_obj));
452469
if (is_eq(go_obj, ev_return_caller))
453470
return cr->val;
454471
if (is_eq(go_obj, ev_appl_accum_last_arg))
@@ -469,6 +486,8 @@ static obj ecevalgoto(struct core *cr, bool yield)
469486
goto eval_dispatch;
470487
if (is_eq(go_obj, ev_if_decide))
471488
goto ev_if_decide;
489+
if (is_eq(go_obj, ev_lock_done))
490+
goto ev_lock_done;
472491
if (is_eq(go_obj, ev_quoted))
473492
goto ev_quoted;
474493
if (is_eq(go_obj, ev_sequence_continue))

src/mceval.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,3 +626,8 @@ bool is_parallel_eval(obj exp)
626626
{
627627
return is_tagged_list(exp, parallel_eval_s);
628628
}
629+
630+
bool is_lock(obj exp)
631+
{
632+
return is_tagged_list(exp, lock);
633+
}

src/mceval.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,6 @@ obj quasi_to_combination(obj exp);
7272

7373
bool is_parallel_execute(obj exp);
7474
bool is_parallel_eval(obj exp);
75+
bool is_lock(obj exp);
7576

7677
#endif

src/obj.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ SYMBOL_VAR(lambda)
256256
SYMBOL_VAR(let)
257257
SYMBOL_VAR(letrec)
258258
const obj letstar = SYMBOL("let*");
259+
const obj lock = SYMBOL("__%%lock");
259260
const obj memo_proc = SYMBOL("memo-proc");
260261
const obj or_s = SYMBOL("or");
261262
const obj parallel_eval_s = SYMBOL("parallel-eval");
@@ -279,6 +280,7 @@ SYMBOL_VAR(ev_assignment_1)
279280
SYMBOL_VAR(ev_definition_1)
280281
SYMBOL_VAR(ev_eval_dispatch)
281282
SYMBOL_VAR(ev_if_decide)
283+
SYMBOL_VAR(ev_lock_done)
282284
SYMBOL_VAR(ev_quoted)
283285
SYMBOL_VAR(ev_sequence_continue)
284286
SYMBOL_VAR(ev_timed_done)

src/obj.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ extern const obj lambda;
138138
extern const obj let;
139139
extern const obj letrec;
140140
extern const obj letstar;
141+
extern const obj lock;
141142
extern const obj memo_proc;
142143
extern const obj or_s;
143144
extern const obj parallel_eval_s;
@@ -161,6 +162,7 @@ extern const obj ev_assignment_1;
161162
extern const obj ev_definition_1;
162163
extern const obj ev_eval_dispatch;
163164
extern const obj ev_if_decide;
165+
extern const obj ev_lock_done;
164166
extern const obj ev_quoted;
165167
extern const obj ev_sequence_continue;
166168
extern const obj ev_timed_done;

0 commit comments

Comments
 (0)