chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-users] chicken interupt handling


From: Jörg F . Wittenberger
Subject: Re: [Chicken-users] chicken interupt handling
Date: 05 Sep 2011 14:26:32 +0200

Hi,

I'm afraid the problem as such is gone.
At least I've got some fresh hope.

The code with the flag mentioned in my message is already gone for me again.
For one thing I've been able to convince myself that C_raise_interrupt
is correctly called in the global_signal_handler before the signal handler
is restored.  Only different types of signals could hurt.
But even that appears not to be the case.

But not being allowed to allocate memory in the signal handler was still
too much of a road block for me.

Looking into the details I don't fully understand the rationale why the signal handler is run at the begin of GC. (Which in turn is only my hypothesis why I can't allocate memory.) IMHO the still could easily be deferred until GC is done. I'm currently running from a modification, which runs signal handler just before the scheduler switches to the slot 1 of the current thread.

This seems to solve the problem.

However, since the original signal handler is basically untouched, since
it appears to be required that way for the sake of finalizers and scheduling
itself.  What I did is: count the signals in the global_signal_handler
(one counter per signal) and run the Scheme level handler later.
This should translate (I hope) into reduced overhead.  But once again I'm
unsure.

For this I removed the overwrite on ##sys#interrupt-hook from the posix
unit and introduced a ##sys#async-interrupt-hook - which then is called
from ##sys#schedule (at a better position than given in my recent posting).

Now for the diff: I'll have to prepare that. Since I updated to the new git (see my posting about that one apparently having a broken types.db or respective evaluation code) and found the problem I had the past days as an "unrelated" bug in other code, which has only been triggered because the system is now more responsive -- my build directory is a mess. Also I intent to do some more testing (other machines/architectures/environments).

I'll post the "final" suggestion when it's ready.

Ah: one more question: should there be an 1:1 correspondence between
signals received and signal handler invoked?  Since signals might be lost
at the current state of affairs when interrupts are disabled, it might
not hurt if we run the signal handler just once.  Alternatively we cold
add an optional argument to set-signal-handler specifying one way or the
other.  Which version should I code?

Thanks

/Jerry

On Sep 5 2011, Felix wrote:

I wonder if there is a bug in the runtime.c concerning interrupt
handling.

But I don't understand the code enough.

C_raise_interrupt will do
C_regparm void C_fcall C_raise_interrupt(int reason)
{
 if(C_interrupts_enabled) {
   saved_stack_limit = C_stack_limit;

#if C_STACK_GROWS_DOWNWARD
   C_stack_limit = C_stack_pointer + 1000;
#else
   C_stack_limit = C_stack_pointer - 1000;
#endif

   interrupt_reason = reason;
   interrupt_time = C_cpu_milliseconds();
 }
}

But there's already my first suspect: C_cpu_milliseconds boild down to
a system call, which AFAIK could dispatch the next signal already.

Yes, that may be a problem.


But things *seem* to get even worse: If I read the source right, then
C_context_switch must be used to complete the handle_interrupt.
Correct?
And this too will (seems to) change global state wrt. stack pointers.

Still, even with repeated interrupts, the stack-pointer should still
be beyond the limit, so that a GC is triggered in any case.

After having played with several variations of signal delivery, all
ending up in a tight loop sooner or later, I got the idea to add
one more variable (puh): a flag being set to true at the bottom of
C_context_switch (right before the trampoline call
and set to 0 before the global_signal_handler calls C_raise_interrupt.
Also C_raise_interrupt is only called if the flag was at 1, thus
at most once per C_context_switch.

I see - but the signals coming in while this flag is zero will be
ignored, right?


che




reply via email to

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