From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: ludo@gnu.org (Ludovic =?iso-8859-1?Q?Court=E8s?=) Newsgroups: gmane.lisp.guile.user Subject: Re: Long-lived Guile scripts in a mono-threaded game engine Date: Tue, 27 May 2008 20:08:52 +0200 Message-ID: <87bq2rhb63.fsf@gnu.org> References: <20080526211900.GB14261@perso.beuc.net> <87fxs4yy89.fsf@gnu.org> <20080527083324.GA16693@perso.beuc.net> <87hccjnars.fsf@gnu.org> <20080527161445.GB18239@perso.beuc.net> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1211911757 3727 80.91.229.12 (27 May 2008 18:09:17 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 27 May 2008 18:09:17 +0000 (UTC) To: guile-user@gnu.org Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Tue May 27 20:09:58 2008 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1K13cT-0005nO-Sq for guile-user@m.gmane.org; Tue, 27 May 2008 20:09:58 +0200 Original-Received: from localhost ([127.0.0.1]:44897 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1K13bi-00035Q-Hl for guile-user@m.gmane.org; Tue, 27 May 2008 14:09:10 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1K13be-00035B-DY for guile-user@gnu.org; Tue, 27 May 2008 14:09:06 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1K13bc-00034w-TN for guile-user@gnu.org; Tue, 27 May 2008 14:09:06 -0400 Original-Received: from [199.232.76.173] (port=59415 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1K13bc-00034t-Pq for guile-user@gnu.org; Tue, 27 May 2008 14:09:04 -0400 Original-Received: from main.gmane.org ([80.91.229.2]:51336 helo=ciao.gmane.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1K13bc-0004WK-Dp for guile-user@gnu.org; Tue, 27 May 2008 14:09:04 -0400 Original-Received: from list by ciao.gmane.org with local (Exim 4.43) id 1K13bY-0001g1-60 for guile-user@gnu.org; Tue, 27 May 2008 18:09:00 +0000 Original-Received: from reverse-83.fdn.fr ([80.67.176.83]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 27 May 2008 18:09:00 +0000 Original-Received: from ludo by reverse-83.fdn.fr with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 27 May 2008 18:09:00 +0000 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 79 Original-X-Complaints-To: usenet@ger.gmane.org X-Gmane-NNTP-Posting-Host: reverse-83.fdn.fr X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: 9 Prairial an 216 de la =?iso-8859-1?Q?R=E9volution?= X-PGP-Key-ID: 0xEA52ECF4 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 821D 815D 902A 7EAB 5CEE D120 7FBA 3D4F EB1F 5364 X-OS: i686-pc-linux-gnu User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux) Cancel-Lock: sha1:1ZOyfNAI4Dh9OYqv+ubgB68LLlY= X-detected-kernel: by monty-python.gnu.org: Linux 2.6, seldom 2.4 (older, 4) X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-user-bounces+guile-user=m.gmane.org@gnu.org Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.user:6582 Archived-At: Hi, Sylvain Beucler 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