guile-user
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]