[gambit-list] Order for returning C->Scheme calls

Mikael mikael.rcv at gmail.com
Mon Mar 28 05:04:26 EDT 2011


Dear Marc,

Below A B C D are Scheme procedures and f g h are C procedures.

In case of nested Scheme->C calls, i.e. if A calls f which calls B which
calls g which calls C which calls h which calls D etc., then for the
application not to enter an undefined state, returning the C calls _MUST_ be
done in the exact reverse order in order, right?
     I.e., D must return to h which must return to C which must return to g
which must return to B which must return to f which must return to A.
     If any mixing of this order is done - i.e. D returns to g, or B returns
to h, etc., then the application enters an undefined state, right, or how is
it?

That is,
 * Gambit in itself does not implement any blocking feature such that while
g and h are still on the stack, a return from f to A would block until D
returned to h and C returned to G
 * Gambit does not implement any exception handling for trying to return in
the wrong order, but if returning in the wrong order the application simply
terminates at some point
 * Gambit uses one ordinary C stack for all Scheme->C and C->Scheme calling,
so it does not allocate a new C stack dynamically on the heap, or alike, for
any Scheme->C call.

I experimented a bit with returning C->Scheme calls in the wrong order, and
what happened was that at the LAST return I made, the application
terminated. I suppose this is consistent with how it should be - the Gambit
app may behave just about any way if you returned C->Scheme calls in the
wrong order, as this messed up the C stack and the app is about to 'blow'
just about any second. (I had A call f which called B which called g which
called C which called h which called D, then D returned to g which returned
to B which returned to h - and at h's return to Scheme the app terminated)

Also I suppose this is in line with the "19.7 Continuations and the
C-interface" manual section and your paper
http:/www.iro.umontreal.ca/~feeley/papers/FeeleySW00.pdf<http://www.iro.umontreal.ca/~feeley/papers/FeeleySW00.pdf>
,
which I suppose Gambit implements.

Looking forward to get clear on this one :-)

Kind regards,
Mikael

test_c_stack_rewinding.scm :

(c-define (c-run thunk) (scheme-object) void "c_run" ""
 (print "c-run entered for " thunk ".\n")
 (thunk)
 (print "c-run returned for " thunk ".\n"))

(define run-through-c (c-lambda (scheme-object) void "c_run(___arg1);"))

(define (thread-go id sleep-seconds)
  (thread-start!
   (make-thread (lambda ()
                  (print "thread " id " entered.\n")
                  (run-through-c (lambda ()
                                   (print "thread " id "'s c thunk
entered.\n")
                                   (thread-sleep! sleep-seconds)
                                   (print "thread " id "'s c thunk
returning.\n")))
                              (print "thread " id " returned.\n")))))


REPL interaction:
$ gsc
Gambit v4.5.3

> (compile-file "test_c_stack_rewinding.scm")
> (load "test_c_stack_rewinding")


;; Test one simultaneous Scheme->C->Scheme call:
> (thread-go 1 5)
#<thread #2>
> thread 1 entered.
c-run entered for #<procedure #3>.
thread 1's c thunk entered.
1
1
> thread 1's c thunk returning.
c-run returned for #<procedure #3>.
thread 1 returned.



;; Scheme->C->Scheme calls can be made many at a time, as long as the last
one made returns first:
> (thread-go 3 10) (thread-sleep! 1) (thread-go 4 5)
#<thread #8>
> thread 3 entered.
c-run entered for #<procedure #9>.
thread 3's c thunk entered.
> #<thread #10>
> thread 4 entered.
c-run entered for #<procedure #11>.
thread 4's c thunk entered.
thread 4's c thunk returning.
c-run returned for #<procedure #11>.
thread 4 returned.


thread 3's c thunk returning.
c-run returned for #<procedure #9>.
thread 3 returned.



>  (thread-go 8 15) (thread-sleep! 1) (thread-go 9 10)  (thread-sleep! 1)
(thread-go 10 5)
#<thread #2>
> thread 8 entered.
c-run entered for #<procedure #3>.
thread 8's c thunk entered.
> #<thread #4>
> thread 9 entered.
c-run entered for #<procedure #5>.
thread 9's c thunk entered.
> #<thread #6>
> thread 10 entered.
c-run entered for #<procedure #7>.
thread 10's c thunk entered.
thread 10's c thunk returning.
c-run returned for #<procedure #7>.
thread 10 returned.
thread 9's c thunk returning.
c-run returned for #<procedure #5>.
thread 9 returned.
thread 8's c thunk returning.
c-run returned for #<procedure #3>.
thread 8 returned.



;; If C->Scheme calls return in another order then the app terminates
> (thread-go 5 5) (thread-sleep! 1) (thread-go 6 10)
#<thread #12>
> thread 5 entered.
c-run entered for #<procedure #13>.
thread 5's c thunk entered.
> #<thread #14>
>
thread 6 entered.
c-run entered for #<procedure #15>.
thread 6's c thunk entered.
1
1
> thread 5's c thunk returning.
c-run returned for #<procedure #13>.
thread 5 returned.


0
0
> thread 6's c thunk returning.
c-run returned for #<procedure #15>.
$




>  (thread-go 1 6) (thread-sleep! 1) (thread-go 2 12)  (thread-sleep! 1)
(thread-go 3 9) (thread-sleep! 1) (thread-go 4 5)
#<thread #2>
> thread 1 entered.
c-run entered for #<procedure #3>.
thread 1's c thunk entered.
> #<thread #4>
> thread 2 entered.
c-run entered for #<procedure #5>.
thread 2's c thunk entered.
> #<thread #6>
> thread 3 entered.
c-run entered for #<procedure #7>.
thread 3's c thunk entered.
> #<thread #8>
> thread 4 entered.
c-run entered for #<procedure #9>.
thread 4's c thunk entered.
thread 1's c thunk returning.
c-run returned for #<procedure #3>.
thread 1 returned.
thread 4's c thunk returning.
c-run returned for #<procedure #9>.
$
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20110328/cedf76fb/attachment.htm>


More information about the Gambit-list mailing list