|
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 doC_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
[Prev in Thread] | Current Thread | [Next in Thread] |