[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Long-lived Guile scripts in a mono-threaded game engine
From: |
Ludovic Courtès |
Subject: |
Re: Long-lived Guile scripts in a mono-threaded game engine |
Date: |
Tue, 27 May 2008 20:08:52 +0200 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux) |
Hi,
Sylvain Beucler <address@hidden> writes:
> So the script does not (sleep). In this game, the engine is a mini-OS
> with a non-preemptive process model.
So "scripts" are supposed to be cooperative, and invoking `say_stop'
amounts to doing a `yield', right?
Then your question boils down to how to implement `yield'. Using
continuations, that would be something like this:
(define (my-hook schedule)
(define (yield)
(call/cc schedule))
;; do stuff...
(yield)
;; do more stuff
)
Where `my-hook' is invoked by the engine and SCHEDULE is a continuation
to invoke the engine, which may in turn schedule another co-routine, and
so on.
You could save one `call/cc' by abusing exceptions (which do not involve
stack copying, unlike `call/cc'):
(define (my-hook)
(define (yield)
(call/cc
(lambda (resume)
(throw 'yield-to-scheduler resume))))
;; do stuff...
(yield)
;; do more stuff
)
... where the `yield-to-scheduler' exception would be caught by the
engine. With a bit of syntactic sugar, this could be hidden from
programmers.
But again, I would avoid `call/cc' at all because of its performance
hit. Avoiding it would require explicit CPS, which may admittedly be
unsuitable given the audience:
(define (my-hook)
(define (yield resume)
(throw 'yield-to-scheduler resume))
;; do stuff...
(yield (lambda ()
;; do more stuff
)))
Given the drawbacks of these solutions, evaluating scripts in a separate
pthread looks like a good solution. :-)
> Yeah, I was trying to avoid introducing threads in the engine :)
> But it sounds like the only usable solution as of now.
It's actually not silly now that we've entered the multicore era.
> Ideally Guile would offer a '(pause)' function that would return from
> 'scm_eval_string' or similar, with another 'scm_resume()' function
> that would unfreeze it :)
That would most likely have to be implemented in terms of `call/cc' as
shown above, so it wouldn't help much.
Thanks,
Ludovic