[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-users] Chicken + swig + C unions = infinite loop
From: |
felix |
Subject: |
Re: [Chicken-users] Chicken + swig + C unions = infinite loop |
Date: |
Fri, 16 May 2003 10:56:49 +0200 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020529 |
Dave wrote:
Chicken looks really promising since I have been looking for something
that can wrap C++ apis and let me play around with them in a decent
language like scheme.
In the course of trying it out by interfacing to SDL , I think I am
encountering a problem with C "union" types (SDL_Event is a union of all
the event types).
I have a small test case below that seems to demonstrate the problem
which only seems to occur when allocating unions and manifests as an
infinite loop. I assume that it is in the GC cycle, but I'm not sure.
Here are the commands I used:
swig -chicken crash.i
csc crash_wrap.c crash.scm crash_test.scm
in crash_test.scm, the first and second loops complete, but the third
drops into a 100% cpu tailspin and never seems to recover. I tried this
with the chicken 1.0 release and the 1.9 development version.
I'd really appreciate any pointers anyone can give me with this!
Hi!
Thanks for the code. I was able to reproduce the problem pretty quickly.
The reason for the loop are calls to the interrupt-checking routine, that the
SWIG wrapper inserts. This routine (C_check_for_interrupt) is *not*
reentrant, since it saves the current limit for the allocation area
and sets it to an artificial value, that is guaranteed to trigger the
garbage-collector at the next check. In your test-code, you create
a very tight sequence of calls to crash:new-combo and crash:delete-combo.
Now, when the timer interrupt is signalled (for multithreading), the
interrupt-check in crash_wrap_new_combo saves the old limit and resets the
limit, then immediately afterwards (without a stack-check),
crash_wrap_delete_combo does the same (and also saves the old limit, which
was invalidated by C_check_for_interrupt' before) and...
Now GC and interrupt-handling go on forever.
I propose to remove the interrupt-checks in Source/Modules/chicken.cxx
in the SWIG code, those checks really should only done at the Scheme-side,
here we always make sure the stack-check happens right after the interrupt-
check.
A diff is attached.
cheers,
felix
cd ~/tmp/SWIG-1.3.18/Source/Modules/
diff -c /home/felix/tmp/SWIG-1.3.18/Source/Modules/chicken.cxx\~
/home/felix/tmp/SWIG-1.3.18/Source/Modules/chicken.cxx
*** /home/felix/tmp/SWIG-1.3.18/Source/Modules/chicken.cxx~ Sun Mar 23
21:43:20 2003
--- /home/felix/tmp/SWIG-1.3.18/Source/Modules/chicken.cxx Fri May 16
10:24:52 2003
***************
*** 528,535 ****
}
// Check for interrupts
! Printv (f->code, "C_check_for_interrupt;\n",
! "C_trace(\"",scmname,"\");\n", NIL);
Printv(f->def,
#ifndef BINDING
--- 528,534 ----
}
// Check for interrupts
! Printv (f->code, "C_trace(\"",scmname,"\");\n", NIL);
Printv(f->def,
#ifndef BINDING
***************
*** 952,959 ****
namify(proc_name);
// Check for interrupts
! Printv (f->code, "C_check_for_interrupt;\n",
! "C_trace(\"",scmname,"\");\n", NIL);
closargs = NewString("");
closwrapargs = NewString("");
--- 951,957 ----
namify(proc_name);
// Check for interrupts
! Printv (f->code, "C_trace(\"",scmname,"\");\n", NIL);
closargs = NewString("");
closwrapargs = NewString("");
***************
*** 1224,1231 ****
namify(proc_name);
// Check for interrupts
! Printv (f->code, "C_check_for_interrupt;\n",
! "C_trace(\"",scmname,"\");\n", NIL);
if (1 || (SwigType_type(t) != T_USER) || (isPointer(t))) {
--- 1222,1228 ----
namify(proc_name);
// Check for interrupts
! Printv (f->code, "C_trace(\"",scmname,"\");\n", NIL);
if (1 || (SwigType_type(t) != T_USER) || (isPointer(t))) {
Diff finished at Fri May 16 10:29:40