Re: [Chicken-users] difference between ##sys#error and posix-error?
Hi Alan! * Alan Post alanp...@sunflowerriver.org [110929 05:51]: Looking at posixunix.scm, I find that some error messages are produced with ##sys#error, and others with posix-error. What distinguishes these two routines? Why would I use one but not the other? (define posix-error (let ([strerror (foreign-lambda c-string strerror int)] [string-append string-append] ) (lambda (type loc msg . args) (let ([rn (##sys#update-errno)]) (apply ##sys#signal-hook type loc (string-append msg - (strerror rn)) args) ) ) ) ) (define ##sys#posix-error posix-error) whereas ##sys#error just calles the À##sys#signal-hook (define (##sys#error . args) (if (pair? args) (apply ##sys#signal-hook #:error args) (##sys#signal-hook #:error #f))) So the former is a specialised convenience procedure that will add a textual presentation of errno for you, whereas the latter is the more general variant that hands your args to the ##sys#signal-hook. Does this make sense for you? Kind regards, Christian -- Who can (make) the muddy water (clear)? Let it be still, and it will gradually become clear. Who can secure the condition of rest? Let movement go on, and the condition of rest will gradually arise. -- Lao Tse. ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] EINTR with self-pipe signal trampoline
On Sep 29 2011, Alan Post wrote: Below is a test case for a problem I'm seeing in some multi-process code I'm writing. I'm getting the error: Error: (file-read) cannot read from file - Interrupted system call There are two ways to fix that: either make the posix unit thread safe (recall my recent message how to avoid process-wait having a bad effect). The other one is working around the problem. That's what I'm doing based on some code Felix supplied ages ago. It wraps the file descriptors into custom ports those are properly restarted on EINTR. However I'd be rather interested to learn what exactly the problem is you observe. Recently (maybe 4.7.3 or .4) I'm seeing missbehavior from formerly well working code. I can't say that's chickens fault but neither I can say it's not. Here is the code. Please excuse that uses process-wait-for-pid and process-test-pid to avoid blocking for the childs termination. You might replace them with process-wait whereby process-test-pid should never block. (define process-io-ports (let ([make-input-port make-input-port] [make-output-port make-output-port] [make-string make-string] [substring substring] [file-close-fd! (foreign-lambda* int ((int fd)) return(close(fd));)] ) (lambda (pid fdr fdw) (##sys#file-nonblocking! fdw) (##sys#file-nonblocking! fdr) ; should not be required (let* ([buf (make-string buffer-size)] ;; [data (vector #f #f #f)] [buflen 0] [bufindex 0] [iclosed #f] [oclosed #f] [in (make-input-port (let-location ((again bool #f)) (lambda () (when (fx= bufindex buflen) (let loop () (and (not iclosed) (let ([n ((foreign-lambda* int ((int fd) (scheme-pointer buf) (int s) ((c-pointer bool) again)) int r = read(fd, buf, s); *again=(r==-1)(errno == EAGAIN); return(r);) fdr buf buffer-size (location again))]) (cond (again (thread-wait-for-i/o! fdr #:input) (loop)) ((eq? -1 n) ;; (##sys#update-errno) ;; (##sys#signal-hook #:process-error 'process-io-read can not read from fd fdr strerror) (set! iclosed #t) #;(when (eq? -1 (file-close-fd! fdr)) (##sys#update-errno) (##sys#signal-hook #:process-error 'process-io-read can not close fd input port fdr) ) (file-close-fd! fdr)) (else ;; (print [rd: n ]) (set! buflen n) (set! bufindex 0))) ))) ) (if (or iclosed (fx= bufindex buflen)) (end-of-file) (let ([c (##core#inline C_subchar buf bufindex)]) (set! bufindex (fx+ bufindex 1)) c) ) )) (lambda () (when iclosed (##sys#signal-hook #:process-error input port is closed fdr)) #t ) (lambda () (unless iclosed (set! iclosed #t) (when (eq? -1 (file-close-fd! fdr)) (##sys#update-errno) (##sys#signal-hook #:process-error 'process-io-close can not close fd input port fdr) ) (if oclosed (receive (p f s) (process-wait-for-pid pid) s) (receive (p f s) (process-test-pid pid) (when (eqv? p pid) (set! oclosed #t) (when (eq? -1 (file-close-fd! fdw)) (##sys#update-errno) (##sys#signal-hook #:process-error 'process-io-close can not close fd output port fdw) ) s))) ) ) ) ] [out (let-location ((again bool #f)) (make-output-port (lambda (s) (define start-time (current-milliseconds)) (let loop ([len (##sys#size s)] [off 0]) (if oclosed (##sys#signal-hook
Re: [Chicken-users] difference between ##sys#error and posix-error?
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 08:36 AM, Christian Kellermann wrote: Hi Alan! * Alan Post alanp...@sunflowerriver.org [110929 05:51]: Looking at posixunix.scm, I find that some error messages are produced with ##sys#error, and others with posix-error. What distinguishes these two routines? Why would I use one but not the other? (define posix-error (let ([strerror (foreign-lambda c-string strerror int)] [string-append string-append] ) (lambda (type loc msg . args) (let ([rn (##sys#update-errno)]) (apply ##sys#signal-hook type loc (string-append msg - (strerror rn)) args) ) ) ) ) Ooof, is that correct? IIRC, strerror isn't thread safe. We may not be using POSIX threads, but might Chicken not schedule a new thread between strerror and string-append, which might itself call strerror and thus produce an invalid error message? I'm not sure at what points the scheduler is actually able to preempt. The solution, if that is a potential problem, is strerror_r, where you pass in your own string buffer. ABS - -- Alaric Snell-Pym http://www.snell-pym.org.uk/alaric/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk6EU0cACgkQRgz/WHNxCGoKwwCgh/PKkHikbGLulucz0Y9YwsvP HUEAniTO3Vq8zcCfYbbgghTcMm24khx7 =ZjGh -END PGP SIGNATURE- ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] difference between ##sys#error and posix-error?
* Alaric Snell-Pym ala...@snell-pym.org.uk [110929 13:18]: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 08:36 AM, Christian Kellermann wrote: Hi Alan! * Alan Post alanp...@sunflowerriver.org [110929 05:51]: Looking at posixunix.scm, I find that some error messages are produced with ##sys#error, and others with posix-error. What distinguishes these two routines? Why would I use one but not the other? (define posix-error (let ([strerror (foreign-lambda c-string strerror int)] [string-append string-append] ) (lambda (type loc msg . args) (let ([rn (##sys#update-errno)]) (apply ##sys#signal-hook type loc (string-append msg - (strerror rn)) args) ) ) ) ) Ooof, is that correct? IIRC, strerror isn't thread safe. We may not be using POSIX threads, but might Chicken not schedule a new thread between strerror and string-append, which might itself call strerror and thus produce an invalid error message? I'm not sure at what points the scheduler is actually able to preempt. The solution, if that is a potential problem, is strerror_r, where you pass in your own string buffer. posix unit declares disable-interrupts which does: Disable timer-interrupts checks in the compiled program. Threads can not be preempted in main- or library-units that contain this declaration. Does this help your understanding? Should be safe IMHO. Kind regards, Christian -- Who can (make) the muddy water (clear)? Let it be still, and it will gradually become clear. Who can secure the condition of rest? Let movement go on, and the condition of rest will gradually arise. -- Lao Tse. ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] two minor tweaks to runtime.c
On Sep 29 2011, Alan Post wrote: On Thu, Sep 29, 2011 at 12:09:19PM +0900, Alex Shinn wrote: On Thu, Sep 29, 2011 at 11:40 AM, Alan Post alanp...@sunflowerriver.org wrote: Will you show me this data for the current implementation? The first implementation doesn't need to justify itself, just be working. *nods* True. However I consider standard engineering practice, which does remove *complexity* from code and moreover offers the compiler much better chances to schedule independent code (where we had a conditional dependency before) worth a try without overkill. And frankly: I'm trying to get an application working. Improving chicken just happens along the way. In fact I feel kind of sorry that there is such a thread arose from a simple change. I don't not have benchmarks for a reason: they would cost me too much time to do right. Personally I don't believe too much in benchmarks anyway. I believe in fast execution and source code review. How should the community ever be able to improve over the current state of affairs, if each suggestion is upfront required to come with a benchmark, which is than probably first taken apart to show how flawed it is? Given how small the difference to the code is: wouldn't it be reasonable to just give it a try? I for one forgot to measure the time of first recompilation of chicken with those changes already in the compiler. But I was surprised. Or let me take the threading problem I solved ages ago. I did NOT want to get into that business. All I wanted was to have my prog run on chicken as it did on rscheme. Benchmarks said chicken is faster at that time. What a lie a benchmark can be! It was crawling slow. Tracked that down to the timeout queue. Fixed the complexity issue. Problem solved. Hm. So how would I device a benchmark case for that one? And why? It's obviously faster. Not with one or two threads. But those don't suffer either. /Jörg ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] difference between ##sys#error and posix-error?
On Sep 29 2011, Alaric Snell-Pym wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 08:36 AM, Christian Kellermann wrote: Hi Alan! * Alan Post alanp...@sunflowerriver.org [110929 05:51]: Looking at posixunix.scm, I find that some error messages are produced with ##sys#error, and others with posix-error. What distinguishes these two routines? Why would I use one but not the other? (define posix-error (let ([strerror (foreign-lambda c-string strerror int)] [string-append string-append] ) (lambda (type loc msg . args) (let ([rn (##sys#update-errno)]) (apply ##sys#signal-hook type loc (string-append msg - (strerror rn)) args) ) ) ) ) Ooof, is that correct? IIRC, strerror isn't thread safe. We may not be using POSIX threads, but might Chicken not schedule a new thread between strerror and string-append, which might itself call strerror and thus produce an invalid error message? I'm not sure at what points the scheduler is actually able to preempt. The core units are compiled without interrupt checking. There is no chicken thread switch coming in here. ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] two minor tweaks to runtime.c
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 12:38 PM, Jörg F. Wittenberger wrote: I don't not have benchmarks for a reason: they would cost me too much time to do right. Personally I don't believe too much in benchmarks anyway. I believe in fast execution and source code review. Ah, but how can you measure fast execution without a benchmark? How should the community ever be able to improve over the current state of affairs, if each suggestion is upfront required to come with a benchmark, which is than probably first taken apart to show how flawed it is? If the benchmark is flawed, it should be fixed. I am getting the impression you have encountered some terrible benchmarks! Given how small the difference to the code is: wouldn't it be reasonable to just give it a try? Yes. But trying out some code involves reviewing it, then testing it - both for correctness and, in this case, for a performance improvement; and (the evil case...) for not worsening performance elsewhere. Which needs a test suite and some benchmarks! Or let me take the threading problem I solved ages ago. I did NOT want to get into that business. All I wanted was to have my prog run on chicken as it did on rscheme. Benchmarks said chicken is faster at that time. What a lie a benchmark can be! It was crawling slow. Tracked that down to the timeout queue. Fixed the complexity issue. Problem solved. Hm. So how would I device a benchmark case for that one? If the supposed performance improvement can't be benchmarked, then it's pointless, as nobody will actually benefit from it. Any case where somebody can benefit from a performance improvement can be turned into a benchmark that consists of running the code that is sped up, and timing it. Benchmarks are like unit tests; they are snippets of code that perform some operation but, rather than testing correct responses, their emphasis is on testing resource usage. We could work on a system by iteratively hacking it then measuring performance by hand, but in doing so, we will only measure the kinds of performance we personally care about, and may well do things that reduce performance in other areas of the system. Decent benchmarks can be put into the test suite, so future performance tinkerers can see the consequences of their changes for previous uses. And just like unit tests, performance benchmarks should be chosen carefully for what they test. Unit tests are often easier to write, as they have clearly-defined (sometimes in specifications, sometimes in common sense) goals. Performance benchmarks are trickier. A system that aggressively caches everything read might perform very well on read latency and throughput, but terribly on memory consumption and latency of noticing changes to source data. So the best benchmarks are derived directly from applications, and include representative mixes of operations to test overall performance as well as low-level per-operation benchmarks! ABS - -- Alaric Snell-Pym http://www.snell-pym.org.uk/alaric/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk6EXlAACgkQRgz/WHNxCGq02ACcDTZBt8R4f3PU8Zu7vl63TjIP ShAAnjUl0K8Z3uCwpJMuVSb9bZ5uilcZ =mZsg -END PGP SIGNATURE- ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] difference between ##sys#error and posix-error?
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 12:41 PM, Jörg F. Wittenberger wrote: The core units are compiled without interrupt checking. There is no chicken thread switch coming in here. Oh, good. Stand down all units :-) ABS - -- Alaric Snell-Pym http://www.snell-pym.org.uk/alaric/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk6EYSoACgkQRgz/WHNxCGoxYACfT5bKZ1awtTTKZjGmWUu4/uKa Y2MAn29H5RxV3UcSSf6EVKaTxf2us/bI =sNUx -END PGP SIGNATURE- ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] EINTR with self-pipe signal trampoline
On Wed, Sep 28, 2011 at 05:29:46PM -0601, Alan Post wrote: Below is a test case for a problem I'm seeing in some multi-process code I'm writing. I'm getting the error: Error: (file-read) cannot read from file - Interrupted system call because a signal handler is going off while my main thread is in an iowait state. In C, I have always handled this by manually restarting a system call when EINTR is called. In my attached test case, I'm trying to use SA_RESTART in sigaction(2) for the same affect, and that isn't working for me. Does that actually work? I'm trying to determine which direction to head in to fix this problem, and I was surprised that SA_RESTART didn't work. Will one of you with access to a linux machine try running this code? Both in the version as seen here and also run uncommenting the two foreign-code lines. This code might have bugs that prevent it from running as intended--I'm not able to test past my EINTR problem. I'm now planning on patching file-read and file-write to restart on EINTR, unless someone has a better idea! Can I catch this exception at runtime? -Alan I investigated this further last night and can articulate better the problem. 1) The main thread sets a signal handler. 2) In then calls read(2) and blocks. 3) A signal arrives, which is handled by an internal signal handler. 4) read(2) returns -1 with errno set to EINTR. What I need to have happen here, is for the signal handling code to then be run, which will write(2) to the pipe. I then need the signal handler to be run (which happens on the main thread) At which point I *then* need to restart the read(2) call, which now will have pending data. I can't introduce a version of read(2) that restarts on EINTR: doing that causes the signal handler to never be run, so we pause forever in a deadlock. I don't understand enough about the scheduler to know when interrupts get handled. Can it happen while executing the scheme code in file-read? If signals get delivered at a reliable point, read can likely be restarted knowing the signal has been handled. If not, I'm left with needing to catch the error, somehow guarantee that the signal handler has been run, then call my code again (to re-enter read) When does the scheduler handle interrupts? -Alan -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] EINTR with self-pipe signal trampoline
On Thu, Sep 29, 2011 at 01:11:49PM +0200, Jörg F. Wittenberger wrote: On Sep 29 2011, Alan Post wrote: Below is a test case for a problem I'm seeing in some multi-process code I'm writing. I'm getting the error: Error: (file-read) cannot read from file - Interrupted system call There are two ways to fix that: either make the posix unit thread safe (recall my recent message how to avoid process-wait having a bad effect). The other one is working around the problem. That's what I'm doing based on some code Felix supplied ages ago. It wraps the file descriptors into custom ports those are properly restarted on EINTR. However I'd be rather interested to learn what exactly the problem is you observe. Recently (maybe 4.7.3 or .4) I'm seeing missbehavior from formerly well working code. I can't say that's chickens fault but neither I can say it's not. If I understand the part of the code below that wraps read/write, it can't be used as-is for my problem. Because chicken defers signals, a signal is delivered, deferred, then read/write return with EINTR. If I immediately restart these syscalls (all in the same C call), the deferred signal has not be delivered, and the code deadlocks, as read/write pauses--blocking the signal handler from ever being run. I need a way to deliver deferred signals after a syscall returns EINTR, before restarting that syscall. You may well not notice this in non-blocking code, as no data would be ready on the file descriptor and the code would continue running--eventually to deliver the deferred signal and unwedge everything. -Alan -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] two minor tweaks to runtime.c
On Sep 29 2011, Alaric Snell-Pym wrote: On 09/29/2011 12:38 PM, Jörg F. Wittenberger wrote: I don't not have benchmarks for a reason: they would cost me too much time to do right. Personally I don't believe too much in benchmarks anyway. I believe in fast execution and source code review. Ah, but how can you measure fast execution without a benchmark? Well, at the end of the day I run some complex applications. For instance I use httperf. I don't touch chicken, if I did not find a reason to do so. It complicates my work. Or let me take the threading problem I solved ages ago. I did NOT want to get into that business. All I wanted was to have my prog run on chicken as it did on rscheme. Benchmarks said chicken is faster at that time. What a lie a benchmark can be! It was crawling slow. Tracked that down to the timeout queue. Fixed the complexity issue. Problem solved. Hm. So how would I device a benchmark case for that one? If the supposed performance improvement can't be benchmarked, then it's pointless, Hey, I wrote crawling slow! That's worse than just a benchmark. If the same program needs seconds instead of a fraction, then I don't bother. I tracked the problem down, fixed a single thing and found a huge speed up. As expected. Case was closed for me: goal reached. At that time there was no point in perfomance measurements. Later I wrote that httperf run into my Makefile. At that time I recall for a fairly complex page 8-12 replies per second. Same page now around 24 per second. No single reason for that. Just accumulated, incremental steps. the system. Decent benchmarks can be put into the test suite, so future Sure. But since I'm working on a different front, I just don't have the capacity to invest into advertising here. If something works better for me than the current state of affairs, then I notify the list. Code review is due upon integration anyway. And those who do have benchmarks already are welcome to post their results. Reviews are welcome to challenge the code. derived directly from applications, and include representative mixes of operations to test overall performance as well as low-level per-operation benchmarks! OK, see above. My benchmark (httperf) fits perfectly. Except it is flawed: the code has evolved in that time too. (In fact it has grown: sqlite/pthread interaction was not included in the beginning.) So we are back at the capacity issue again: I have only so much live time. I'm not ready to spent it maintaining benchmarks in the hope that those will eventually convince someone to benefit from the work I did. You are free to convince yourself. Best Regards /Jörg ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] EINTR with self-pipe signal trampoline
Hi Jörg, On 29 Sep 2011 13:11:49 +0200 Jörg F. Wittenberger joerg.wittenber...@softeyes.net wrote: Recently (maybe 4.7.3 or .4) I'm seeing missbehavior from formerly well working code. I can't say that's chickens fault but neither I can say it's not. 4.7.3 has a bug that may affect your applications: https://bugs.call-cc.org/ticket/668 Best wishes. Mario -- http://parenteses.org/mario ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] two minor tweaks to runtime.c
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 01:44 PM, Jörg F. Wittenberger wrote: On Sep 29 2011, Alaric Snell-Pym wrote: On 09/29/2011 12:38 PM, Jörg F. Wittenberger wrote: I don't not have benchmarks for a reason: they would cost me too much time to do right. Personally I don't believe too much in benchmarks anyway. I believe in fast execution and source code review. Ah, but how can you measure fast execution without a benchmark? Well, at the end of the day I run some complex applications. For instance I use httperf. Then that, my good man, is your benchmark :-) Yes, it's complex to run a chicken-based app and then run httperf against that to get real-world performance figures. Ideally you'd be able to distill the essence of that a little into a simpler test that nonetheless had almost the same performance characteristics. And maybe make mistakes in the process - but that's the art of performance estimation. If the supposed performance improvement can't be benchmarked, then it's pointless, Hey, I wrote crawling slow! That's worse than just a benchmark. If the same program needs seconds instead of a fraction, then I don't bother. I tracked the problem down, fixed a single thing and found a huge speed up. As expected. Case was closed for me: goal reached. If you had some operation you could measure before and after to see that speed up, then that's a benchmark too! At that time there was no point in perfomance measurements. If you found a huge speed up, you were measuring performance, by definition :-) If something works better for me than the current state of affairs, then I notify the list. Code review is due upon integration anyway. And those who do have benchmarks already are welcome to post their results. Reviews are welcome to challenge the code. For sure. I, for one, think it's great that you're contributing performance patches. But they do need to be checked with actual benchmarks. It looks like you *have* been doing that, but claiming you haven't, due to a disagreement about the definition of benchmark ;-) Case in point: In the project I work on for a living, I have been working on a series of performance improvements lately. In profiling, I found that a critical system thread spent a large fraction of its time in a function that was trivially optimisable; it was doing an inter-process call back into the same process (don't ask why...), which was then queued amongst other incoming requests before being handled, and the handler then simply checked the existence of a certain file, and sent the results back... so I changed the function to check for the existence of the file itself, without the IPC back into the same process. Result? Performance roughly HALVED. This was a surprise, but not a great shock, as the performance of complex threaded software is famous for being unexpected. We didn't have time to properly investigate, but I believe the problem is that causing this operation to run faster causes the thread to spend more of its time doing other things (rather than blocking on the IPC), and is therefore holding certain locks for a greater percentage of the time, blocking out other, more useful, things that could be happening. But without a benchmark, I'd have thought that this change couldn't possibly have any other effect than to improve performance :-) So we are back at the capacity issue again: I have only so much live time. I'm not ready to spent it maintaining benchmarks in the hope that those will eventually convince someone to benefit from the work I did. You are free to convince yourself. That's fine; it's just that you were complaining you didn't want to do benchmarks, which I now think was purely a communications mistake. Your httperf results are benchmarks, too, if a little informal, but infinitely better than just making changes that through inspection should improve performance, which was my fear :-) /Jörg ABS - -- Alaric Snell-Pym http://www.snell-pym.org.uk/alaric/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk6EbhMACgkQRgz/WHNxCGoElgCgjWYuWJyhf/IxKng+UF5hqxGf OMsAn1O1Ly/kRojxwSCj2isdeGORF0lI =qCaS -END PGP SIGNATURE- ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] remove enable/disable interrupt flag
This patch removes the enable/disable interrupt flag from the scheduled. I can't see that this code is referenced. I'm not sure someone would just write this feature for fun, however. Is this code actually used? I'm preparing a larger patch for the signal handling code, so knowing whether this is used (and how) is important for getting my next set of patches correct. -Alan -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
On Thu, Sep 29, 2011 at 07:12:20AM -0600, Alan Post wrote: This patch removes the enable/disable interrupt flag from the scheduled. I can't see that this code is referenced. I'm not sure someone would just write this feature for fun, however. Is this code actually used? I'm preparing a larger patch for the signal handling code, so knowing whether this is used (and how) is important for getting my next set of patches correct. -Alan -- .i ma'a lo bradi cu penmi gi'e du Let's attach the patch, shall we? Reviewing this, I had to add a thunk to the C_fudge routine, case 14. It is not the least bit obvious what that routine does, or how case 14 gets called. What is that? It's the only part I don't consider straightforward, other than my already mentioned use of this feature I'm not seeing. diff --git a/chicken.h b/chicken.h index 8c6eff3..1739fb9 100644 --- a/chicken.h +++ b/chicken.h @@ -1527,8 +1527,6 @@ C_fctexport C_word C_fcall C_callback_wrapper(void *proc, int argc); C_fctexport void C_fcall C_callback_adjust_stack(C_word *base, int size); C_fctexport void CHICKEN_parse_command_line(int argc, char *argv[], C_word *heap, C_word *stack, C_word *symbols); C_fctexport void C_fcall C_toplevel_entry(C_char *name) C_regparm; -C_fctexport C_word C_fcall C_enable_interrupts(void) C_regparm; -C_fctexport C_word C_fcall C_disable_interrupts(void) C_regparm; C_fctexport void C_fcall C_paranoid_check_for_interrupt(void) C_regparm; C_fctexport void C_zap_strings(C_word str); C_fctexport void C_set_or_change_heap_size(C_word heap, int reintern); diff --git a/runtime.c b/runtime.c index c0c91bc..980f303 100644 --- a/runtime.c +++ b/runtime.c @@ -331,7 +331,6 @@ C_TLS int C_gui_mode = 0, C_abort_on_thread_exceptions, C_enable_repl, - C_interrupts_enabled, C_disable_overflow_check, #ifdef C_COLLECT_ALL_SYMBOLS C_enable_gcweak = 1, @@ -697,7 +696,6 @@ int CHICKEN_initialize(int heap, int stack, int symbols, void *toplevel) chicken_is_running = chicken_ran_once = 0; interrupt_reason = 0; last_interrupt_latency = 0; - C_interrupts_enabled = 1; C_initial_timer_interrupt_period = INITIAL_TIMER_INTERRUPT_PERIOD; C_timer_interrupt_counter = INITIAL_TIMER_INTERRUPT_PERIOD; memset(signal_mapping_table, 0, sizeof(int) * NSIG); @@ -2669,7 +2667,7 @@ C_regparm void C_fcall C_reclaim(void *trampoline, void *proc) /* assert(C_timer_interrupt_counter = 0); */ - if(interrupt_reason C_interrupts_enabled) + if(interrupt_reason) handle_interrupt(trampoline, proc); /* Note: the mode argument will always be GC_MINOR or GC_REALLOC. */ @@ -4102,8 +4100,9 @@ C_regparm C_word C_fcall C_fudge(C_word fudge_factor) case C_fix(13): /* debug mode */ return C_mk_bool(debug_mode); + /* XXX: Where is this called from, how do we deprecate it? */ case C_fix(14): /* interrupts enabled? */ -return C_mk_bool(C_interrupts_enabled); +return C_mk_bool(1); case C_fix(15): /* symbol-gc enabled? */ return C_mk_bool(C_enable_gcweak); @@ -4244,34 +4243,16 @@ C_regparm void C_fcall C_paranoid_check_for_interrupt(void) C_regparm void C_fcall C_raise_interrupt(int reason) { - if(C_interrupts_enabled) { -saved_stack_limit = C_stack_limit; + saved_stack_limit = C_stack_limit; #if C_STACK_GROWS_DOWNWARD -C_stack_limit = C_stack_pointer + 1000; + C_stack_limit = C_stack_pointer + 1000; #else -C_stack_limit = C_stack_pointer - 1000; + C_stack_limit = C_stack_pointer - 1000; #endif -interrupt_reason = reason; -interrupt_time = C_cpu_milliseconds(); - } -} - - -C_regparm C_word C_fcall C_enable_interrupts(void) -{ - C_timer_interrupt_counter = C_initial_timer_interrupt_period; - /* assert(C_timer_interrupt_counter 0); */ - C_interrupts_enabled = 1; - return C_SCHEME_UNDEFINED; -} - - -C_regparm C_word C_fcall C_disable_interrupts(void) -{ - C_interrupts_enabled = 0; - return C_SCHEME_UNDEFINED; + interrupt_reason = reason; + interrupt_time = C_cpu_milliseconds(); } -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] replace signal with sigaction
This patch replaces signal with sigaction for registering signals. sigaction is a newer API for signal processing that fixes some deficiencies of the original signal API. One fix can be seen in this patch: we don't have to reregister the signal handler after a signal is sent. That prevents a race condition whereby a signal is delivered, our signal handler is reset, and before we can reregister our signal handler, another signal is sent (which we then miss). I'm not sure even signal() behaves this way these days. It used to be one tested for sigaction in the same way you might test for other features. I'm not sure if chicken runs on a platform that doesn't have sigaction--do I need to add a feature test for this and preserve the existing capability on platforms without sigaction? -Alan diff --git a/chicken.h b/chicken.h index 1739fb9..4f5847a 100644 --- a/chicken.h +++ b/chicken.h @@ -859,7 +859,7 @@ DECL_C_PROC_p0 (128, 1,0,0,0,0,0,0,0) # define C_isatty isatty # define C_fileno fileno # define C_select select -# define C_signal signal +# define C_sigactionsigaction # define C_getrusagegetrusage # define C_tolower tolower # define C_toupper toupper diff --git a/runtime.c b/runtime.c index 980f303..eb64f92 100644 --- a/runtime.c +++ b/runtime.c @@ -982,7 +982,6 @@ void initialize_symbol_table(void) void global_signal_handler(int signum) { C_raise_interrupt(signal_mapping_table[ signum ]); - signal(signum, global_signal_handler); } @@ -4259,11 +4258,18 @@ C_regparm void C_fcall C_raise_interrupt(int reason) C_regparm C_word C_fcall C_establish_signal_handler(C_word signum, C_word reason) { int sig = C_unfix(signum); + struct sigaction new, old; - if(reason == C_SCHEME_FALSE) C_signal(sig, SIG_IGN); - else { + new.sa_flags = 0; + sigemptyset(new.sa_mask); + + if(reason == C_SCHEME_FALSE) { +new.sa_handler = SIG_IGN; +C_sigaction(sig, new, old); + } else { signal_mapping_table[ sig ] = C_unfix(reason); -C_signal(sig, global_signal_handler); +new.sa_handler = global_signal_handler; +C_sigaction(sig, new, old); } return C_SCHEME_UNDEFINED; -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] EINTR with self-pipe signal trampoline
On Sep 29 2011, Alan Post wrote: On Thu, Sep 29, 2011 at 01:11:49PM +0200, Jörg F. Wittenberger wrote: On Sep 29 2011, Alan Post wrote: Below is a test case for a problem I'm seeing in some multi-process code I'm writing. I'm getting the error: Error: (file-read) cannot read from file - Interrupted system call There are two ways to fix that: either make the posix unit thread safe (recall my recent message how to avoid process-wait having a bad effect). The other one is working around the problem. That's what I'm doing based on some code Felix supplied ages ago. It wraps the file descriptors into custom ports those are properly restarted on EINTR. However I'd be rather interested to learn what exactly the problem is you observe. Recently (maybe 4.7.3 or .4) I'm seeing missbehavior from formerly well working code. I can't say that's chickens fault but neither I can say it's not. If I understand the part of the code below that wraps read/write, it can't be used as-is for my problem. Because chicken defers signals, a signal is delivered, deferred, then read/write return with EINTR. Ah, I see! Good catch. If I immediately restart these syscalls (all in the same C call), the deferred signal has not be delivered, and the code deadlocks, as read/write pauses--blocking the signal handler from ever being run. I'm not yet sure, but this could shed some light at the problems I have. However I normally see signal handling working all day long in my code. Therefore I don't fully understand your issue yet. Signal handlers as they are in chicken might be problematic. I can't find the message, but I recall a reply these days, which informed me that it's true that chicken interrupt handlers are in fact in a restricted dialect of Scheme: they can not allocate memory. I started to read into it. I too, still don't understand all of the C_reclaim procedure. But it's obvious that the interrupt handler is invoked at the begin of the garbage collection. Wild guess: there is no memory available for allocation at that time. Attempt work around: defer the signal even more: until next schedule time. I'm not yet satisfied with that solution. (But at least it allows me to run arbitrary code in the signal handler.) (I intended so far to try whether it would be better to run it close to the finalizers; that is at the end of garbage collection. But that again is just an experiment TBD.) Given your situation I hope we can devise a better way. I'd need to understand your situation better. I need a way to deliver deferred signals after a syscall returns EINTR, before restarting that syscall. I see. I understand you need minimum latency - right? May I ask for more details. I need to understand where this latency requirement is important. You may well not notice this in non-blocking code, as no data would be ready on the file descriptor and the code would continue running--eventually to deliver the deferred signal and unwedge everything Sorry. I do not have so many chicken programs. As soon as something blocks too often, I'll noticed a heavy slow down so far. Under normal circumstances my prog uses 100-200 file descriptors connected to pipes to subprocesses (which do network i/o+ssl) and always on self-pipe. Plus a few open sockets. /Jörg ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] EINTR with self-pipe signal trampoline
On Thu, Sep 29, 2011 at 03:26:22PM +0200, Jörg F. Wittenberger wrote: Attempt work around: defer the signal even more: until next schedule time. I'm not yet satisfied with that solution. (But at least it allows me to run arbitrary code in the signal handler.) (I intended so far to try whether it would be better to run it close to the finalizers; that is at the end of garbage collection. But that again is just an experiment TBD.) Given your situation I hope we can devise a better way. I'd need to understand your situation better. I need a way to deliver deferred signals after a syscall returns EINTR, before restarting that syscall. I see. I understand you need minimum latency - right? May I ask for more details. I need to understand where this latency requirement is important. Let me try a demonstration showing just the main thread: (define (restart-read fd buf isize) ; call read(2), on the self-pipe, which blocks (let ((r (file-read fd buf isize))) (if (= -1 r) ; ah, a signal was delivered. In Chicken, the signal ; delivery to the prcoess causes this error, but the ; Scheme code signal handler might not have been ; delivered. In this case, it means that I haven't ; written a byte to the self-pipe yet. ; (if (= errno EINTR) ; restart the read. Normally, we would have written ; to our self-pipe already (as the signal is delivered ; the moment we return from our syscall.), but in ; Chicken, I'm not sure our deferred Scheme code has ; been called. When does that happen? If it hasn't ; happened yet, I'll block in this routine, and the ; deferred signal handler will never run. ; ; I need a way to guarantee that the deferred signal ; handler has already been run, before I call any other ; syscall. ; (restart-read fd buf isize)) ; something else went wrong, die. (io-error read Does that story make more sense? Chicken may already behave this way, I'm not sure how long it waits/when it delivers a deferred signal. The critically important thing is that it do so before making another syscall. -Alan -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
On Sep 29 2011, Alan Post wrote: This patch removes the enable/disable interrupt flag from the scheduled. I can't see that this code is referenced. I'm not sure someone would just write this feature for fun, however. Is this code actually used? Be careful! I found it to be win to actually reference and use that code. I do lot's of process-fork. The childs will soon be replaced by another program. Why should they spend time in garbage collection before the exec call? Futhermore it's dangerous to leave all threads enabled after a fork. I've seen cases when those subprocess managed to write to file descriptors used by the parent. That's one the the things on my list: find some better way to do the fork. So far I do (define-foreign-variable C_interrupts_enabled bool C_interrupts_enabled) (define (chicken-enable-interrupts!) (set! C_interrupts_enabled #t)) (define chicken-disable-interrupts! (foreign-lambda void C_disable_interrupts)) (let ((pid (begin (chicken-disable-interrupts!) ((foreign-lambda int fork)) )) (if (not (= pid 0)) (chicken-enable-interrupts!)) ... ) I'm preparing a larger patch for the signal handling code, so knowing whether this is used (and how) is important for getting my next set of patches correct. -Alan ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
On Thu, Sep 29, 2011 at 03:43:16PM +0200, Jörg F. Wittenberger wrote: On Sep 29 2011, Alan Post wrote: This patch removes the enable/disable interrupt flag from the scheduled. I can't see that this code is referenced. I'm not sure someone would just write this feature for fun, however. Is this code actually used? Be careful! I found it to be win to actually reference and use that code. I do lot's of process-fork. The childs will soon be replaced by another program. Why should they spend time in garbage collection before the exec call? Futhermore it's dangerous to leave all threads enabled after a fork. I've seen cases when those subprocess managed to write to file descriptors used by the parent. That's one the the things on my list: find some better way to do the fork. So far I do (define-foreign-variable C_interrupts_enabled bool C_interrupts_enabled) (define (chicken-enable-interrupts!) (set! C_interrupts_enabled #t)) (define chicken-disable-interrupts! (foreign-lambda void C_disable_interrupts)) (let ((pid (begin (chicken-disable-interrupts!) ((foreign-lambda int fork)) )) (if (not (= pid 0)) (chicken-enable-interrupts!)) ... ) I figured if someone was using this, it would be you! Thank you for this use case. I'll account for it now. I withdraw this patch--I do consider this code broken--including the test case above (it has a race condition where a signal might be delivered before the fork but after the disable interrupts), though this is not the only case in the signal handling code where this is true. I'll resubmit a new patch. -Alan -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] EINTR with self-pipe signal trampoline
On Thu, Sep 29, 2011 at 03:26:22PM +0200, Jörg F. Wittenberger wrote: Signal handlers as they are in chicken might be problematic. I can't find the message, but I recall a reply these days, which informed me that it's true that chicken interrupt handlers are in fact in a restricted dialect of Scheme: they can not allocate memory. I'm not sure how one would write a signal handler in chicken that doesn't allocate memory. It seems even relatively primitive signal handlers, like my example case, do so: (file-write output-pipe (string (integer-char signum I count that as two boxing operations, one that might not be doable on the stack (I don't know yet how Chicken Scheme allocates strings and therefor whether it does so on the stack. Then of course whatever memory is required to traverse the sexpr--I don't know how Chicken handles that yet either. The objects allocated could be done in advance, as you know what signal numbers you'll be receiving, but I've just assumed the deferral mechanism for signals is done in part to allow memory to be allocated inside them, because they're called in the main thread (or some rough equivalent). *C* signal handlers can't allocate memory, for sure--I'd consider it poor form to do something in a Chicken signal handler that isn't adviseable from a C signal handler, but the runtime environment makes that boundary fuzzy, for me. I started to read into it. I too, still don't understand all of the C_reclaim procedure. But it's obvious that the interrupt handler is invoked at the begin of the garbage collection. Wild guess: there is no memory available for allocation at that time. Given that a thread or a signal handler get their own stacks, and that Chicken uses the stack as a first-generation semispace/nursery, I'm not sure why conceptually one couldn't just execute the runtime inside a signal handler. There are things I'd forbid: no signals delivered during GC, no GC in the signal handler, c. It may well be nothing but hair all the way down, but architecturally I haven't imagined anything to prevent it. Attempt work around: defer the signal even more: until next schedule time. I'm not yet satisfied with that solution. (But at least it allows me to run arbitrary code in the signal handler.) (I intended so far to try whether it would be better to run it close to the finalizers; that is at the end of garbage collection. But that again is just an experiment TBD.) Interesting approach. In conversation with you, I have determined that what has to happen to preserve the execution model is that signals are delivered before a syscall is performed. It appears to me right now that any time at all between a return from a syscall and the next syscall are fine for signal delivery--that leaves a lot of room. .i ko .e mi ze'aca kelgu'a (let's keep hacking), -Alan -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] replace signal with sigaction
Alan Post scripsit: It used to be one tested for sigaction in the same way you might test for other features. I'm not sure if chicken runs on a platform that doesn't have sigaction--do I need to add a feature test for this and preserve the existing capability on platforms without sigaction? Win32 systems (not including Cygwin) have signal() but not sigaction(). The only signals on Win32 are SIGABRT, SIGFPE, and SIGSEGV. SIGILL and SIGTERM can be trapped, but they can only happen if you raise them yourself with raise(). SIGINT can also be trapped, but that's a bad idea, because the handler will be run on a separate Win32 thread. All of our other hosts implement sigaction(). -- But the next day there came no dawn,John Cowan and the Grey Company passed on into the co...@ccil.org darkness of the Storm of Mordor and werehttp://www.ccil.org/~cowan lost to mortal sight; but the Dead followed them. --The Passing of the Grey Company ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] replace signal with sigaction
On Thu, Sep 29, 2011 at 10:44:42AM -0400, John Cowan wrote: Alan Post scripsit: It used to be one tested for sigaction in the same way you might test for other features. I'm not sure if chicken runs on a platform that doesn't have sigaction--do I need to add a feature test for this and preserve the existing capability on platforms without sigaction? Win32 systems (not including Cygwin) have signal() but not sigaction(). The only signals on Win32 are SIGABRT, SIGFPE, and SIGSEGV. SIGILL and SIGTERM can be trapped, but they can only happen if you raise them yourself with raise(). SIGINT can also be trapped, but that's a bad idea, because the handler will be run on a separate Win32 thread. All of our other hosts implement sigaction(). I'm very happy you had this information to hand--I had not quite remembered how the signal() interface survived C ANSI-fication and you just laid it out for me. Does the ANSI C behavior specify that a signal must be re-registered after it is called? Is it more reliable for me to follow the ANSI C standard or the w32 documentation on this interface? If w32, where do I find that? I will submit a new patch that includes a feature test so this code will work on w32. .i.ioki'edo mu'o mi'e .alyn. -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 02:43 PM, Jörg F. Wittenberger wrote: (define (chicken-enable-interrupts!) (set! C_interrupts_enabled #t)) (define chicken-disable-interrupts! (foreign-lambda void C_disable_interrupts)) (let ((pid (begin (chicken-disable-interrupts!) ((foreign-lambda int fork)) )) (if (not (= pid 0)) (chicken-enable-interrupts!)) ... ) To be honest, doing *anything* between fork and exec is pretty questionable. There's the big issue that threads might not be expecting to be randomly duplicated by actions in some other thread, and proceed to do something twice because of it (not a great issue if it's just touching RAM, but a great issue if it involves I/O or mutual exclusion mechanisms). Then there's the fact that you can't use vfork if you do anything other than go straight into an exec, so you need to pay the cost of duplicating the entire address space with CoW mappings (which turned out to be a critical performance factor in a fork-heavy workload here at work, recently!). Having said that, there are good uses of fork() other than as a vfork() then exec() pair; you just need to be VERY CAREFUL, and get whole-program cooperation. Eg, don't initialise some third-party library in the parent, then use it in the child; only take your own state across the fork, and audit it for the consequences. (Good uses of fork() I have seen include redis' technique of forking to get an atomic copy of the process memory to snapshot to disk while the parent continues to process updates, and software forking off its own daemon processes as a form of threading or to ensure isolation from the parent for security reasons! But all of these cases involve careful consideration of the transmission of state from parent to child.) POSIX says that fork needs to produce only a single surviving POSIX thread in the child. Perhaps Chicken fork needs to do the same with Chicken threads. Chicken fork - no food jokes! ABS - -- Alaric Snell-Pym http://www.snell-pym.org.uk/alaric/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk6EiHIACgkQRgz/WHNxCGr0zwCfUWMseuGomWLBL/jgQGHUtEPE RXkAn1C0eXxK1zfXgwfoCR4OFKstU7X2 =d9Ca -END PGP SIGNATURE- ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] difference between ##sys#error and posix-error?
Alaric Snell-Pym scripsit: Ooof, is that correct? IIRC, strerror isn't thread safe. We may not be using POSIX threads, but might Chicken not schedule a new thread between strerror and string-append, which might itself call strerror and thus produce an invalid error message? I'm not sure at what points the scheduler is actually able to preempt. The problem is actually worse than that: a call to a C library earlier in the program might have spawned[*] an OS thread that has itself called strerror, corrupting the internal buffer. Any program that allows the user to invoke arbitrary libraries must assume that it is running more than one OS thread. [*] I say spawned because OS threads are denizens of the uttermost depths of Hell. The solution, if that is a potential problem, is strerror_r, where you pass in your own string buffer. That is what must be done. -- Babies are born as a result of the John Cowan mating between men and women, and most http://www.ccil.org/~cowan men and women enjoy mating. co...@ccil.org --Isaac Asimov in Earth: Our Crowded Spaceship ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] EINTR with self-pipe signal trampoline
On Sep 29 2011, Alan Post wrote: On Thu, Sep 29, 2011 at 03:26:22PM +0200, Jörg F. Wittenberger wrote: Signal handlers as they are in chicken might be problematic. I can't find the message, but I recall a reply these days, which informed me that it's true that chicken interrupt handlers are in fact in a restricted dialect of Scheme: they can not allocate memory. I'm not sure how one would write a signal handler in chicken that doesn't allocate memory. It seems even relatively primitive signal handlers, like my example case, do so: Neither I am. That's why I have the problem with the signal handlers. I tried to do the textbook solution: just unlock a mutex in the signal handler. This would still not work for sure (though it does work for quite some time in practice, but that doesn't help in reality). (file-write output-pipe (string (integer-char signum I count that as two boxing operations, one that might not be doable So do I. In Chicken, all memory is initially allocated by moving the stack pointer to make room for the object. Upon minor gc those objects are moved from the initial position (called nursery in chicken slang) to the heap. That's why signal handlers have the problem, as I tried to explain in the last message: they are run just when space is tight. Moving them to the end of the gc (C_reclaim) *should* *probably* not hurt. Except that we *will* see a larger latency. However my attempts to do so are not yet good enough. Given that a thread or a signal handler get their own stacks, and that Chicken uses the stack as a first-generation semispace/nursery, I'm not sure why conceptually one couldn't just execute the runtime inside a signal handler. I'm afraid I'm not prepared to answer here. Attempt work around: defer the signal even more: until next schedule time. I'm not yet satisfied with that solution. (But at least it allows me to run arbitrary code in the signal handler.) (I intended so far to try whether it would be better to run it close to the finalizers; that is at the end of garbage collection. But that again is just an experiment TBD.) Interesting approach. In conversation with you, I have determined that what has to happen to preserve the execution model is that signals are delivered before a syscall is performed. It appears to me right now that any time at all between a return from a syscall and the next syscall are fine for signal delivery--that leaves a lot of room. That might be the weakness of my attempt work around! Thanks for the hint. I'll try that next. (As soon as I'm done testing your signaction patch, which just finished to compile.) ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] replace signal with sigaction
On Sep 29 2011, John Cowan wrote: Alan Post scripsit: It used to be one tested for sigaction in the same way you might test for other features. I'm not sure if chicken runs on a platform that doesn't have sigaction--do I need to add a feature test for this and preserve the existing capability on platforms without sigaction? Win32 systems (not including Cygwin) have signal() but not sigaction(). The only signals on Win32 are SIGABRT, SIGFPE, and SIGSEGV. SIGILL and SIGTERM can be trapped, but they can only happen if you raise them yourself with raise(). SIGINT can also be trapped, but that's a bad idea, because the handler will be run on a separate Win32 thread. Too bad. I forgot. It's been quite a while that I considered Win32. Could we live with a conditional compilation here? (I'm *not* sure. It complicates thing quite a lot. Let alone readability of the source.) ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
On Sep 29 2011, Alaric Snell-Pym wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 02:43 PM, Jörg F. Wittenberger wrote: (define (chicken-enable-interrupts!) (set! C_interrupts_enabled #t)) (define chicken-disable-interrupts! (foreign-lambda void C_disable_interrupts)) (let ((pid (begin (chicken-disable-interrupts!) ((foreign-lambda int fork)) )) (if (not (= pid 0)) (chicken-enable-interrupts!)) ... ) ... POSIX says that fork needs to produce only a single surviving POSIX thread in the child. Perhaps Chicken fork needs to do the same with Chicken threads. Alaric, that's exactly the effect and reason why I'm using this disable-interrupts/enable-interrupts around fork: to make sure there is only this one Chicken-threads running in the child. With interrupts disabled there is no scheduling in chicken. (At least not until you run into a thread-yield! anyway.) And therefore I'd really recommend to keep it in the runtime. ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 04:25 PM, Jörg F. Wittenberger wrote: POSIX says that fork needs to produce only a single surviving POSIX thread in the child. Perhaps Chicken fork needs to do the same with Chicken threads. Alaric, that's exactly the effect and reason why I'm using this disable-interrupts/enable-interrupts around fork: to make sure there is only this one Chicken-threads running in the child. With interrupts disabled there is no scheduling in chicken. (At least not until you run into a thread-yield! anyway.) And therefore I'd really recommend to keep it in the runtime. I think a better mechanism would be a way to abort all threads but the current one, triggered after the fork in the child, with no interrupts until the thread murder is complete. If you just go off and exec after the fork it'd be better to uninterruptably vfork-then-exec, but we have procedures to do that already! Aborting all threads but the one that asked for the fork also gives one the opportunity to inform them of this fact, should any of them leave useful data structures in incosistent states with locks held. There's something to be said for requesting permission to fork from all threads before doing so, so they can make sure they finish any operations on shared state in the parent, but that'll be complex, and a potential performance bottleneck, so probably not worth it! ABS - -- Alaric Snell-Pym http://www.snell-pym.org.uk/alaric/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk6EkCcACgkQRgz/WHNxCGoBNwCfS5syjjCVWFiyjcP0S6z/BFoB s6MAnjE+v+0Tf32+9bQ+X6wd6UgEA+pA =fjVS -END PGP SIGNATURE- ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] replace signal with sigaction
Here an interesting finding: On Sep 29 2011, Alan Post wrote: This patch replaces signal with sigaction for registering signals. sigaction is a newer API for signal processing that fixes some deficiencies of the original signal API. One fix can be seen in this patch: we don't have to reregister the signal handler after a signal is sent. That prevents a race condition whereby a signal is delivered, our signal handler is reset, and before we can reregister our signal handler, another signal is sent (which we then miss). Since I'm quite old school I've been used to the meaning of signals to be almost reliable. Except under arbitrary complex usage restrictions. Hence I rarely ever tried to count signals, but use them as a hint, which operation would be in order. This might have been not enough! Turn out that with your patch applied something changed: I had one usage case, which almost sure (say ~50%+-25%) would run into that eat-all-memory condition. I tried too often, I fail to reproduce the condition. However at this time I can't convince myself that this is not a false positive. :-/ ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
On Thu, Sep 29, 2011 at 04:35:04PM +0100, Alaric Snell-Pym wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 04:25 PM, Jörg F. Wittenberger wrote: POSIX says that fork needs to produce only a single surviving POSIX thread in the child. Perhaps Chicken fork needs to do the same with Chicken threads. Alaric, that's exactly the effect and reason why I'm using this disable-interrupts/enable-interrupts around fork: to make sure there is only this one Chicken-threads running in the child. With interrupts disabled there is no scheduling in chicken. (At least not until you run into a thread-yield! anyway.) And therefore I'd really recommend to keep it in the runtime. I think a better mechanism would be a way to abort all threads but the current one, triggered after the fork in the child, with no interrupts until the thread murder is complete. If you just go off and exec after the fork it'd be better to uninterruptably vfork-then-exec, but we have procedures to do that already! Aborting all threads but the one that asked for the fork also gives one the opportunity to inform them of this fact, should any of them leave useful data structures in incosistent states with locks held. There's something to be said for requesting permission to fork from all threads before doing so, so they can make sure they finish any operations on shared state in the parent, but that'll be complex, and a potential performance bottleneck, so probably not worth it! ABS In posix threads, this is what pthread_atfork() is for--to clean up resources in the process of joining threads across a fork. The way Chicken is currently implemented, any signal that arrives during this time is discarded, which also makes me unhappy with this situation. A lot of blood and tears were spilled over signal handling on Unix to get to reliable signal delivery. I don't think Chicken should implement unreliable signal delivery on top of a reliable mechanism. It seems that the thread-like nature of signal handling and the thread-like nature of threading have been intermixed in the scheduler, and this particular feature is at cross-purposes. -Alan -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] two minor tweaks to runtime.c
Alaric Snell-Pym scripsit: If the supposed performance improvement can't be benchmarked, then it's pointless, as nobody will actually benefit from it. Any case where somebody can benefit from a performance improvement can be turned into a benchmark that consists of running the code that is sped up, and timing it. Benchmarks are like unit tests; they are snippets of code that perform some operation but, rather than testing correct responses, their emphasis is on testing resource usage. Your clarification down-thread that a benchmark can be of any size makes this comparison rather otiose. Nobody is going to have a benchmark suite that includes tests like these: With patch #1234, application 'foo' runs in an acceptable 18 hours rather than an intolerable 25 hours. (Obviously the improvement has to be nonlinear.) With patch #2345, vectors larger than 2^40 elements show O(1) reference behavior rather than not. With patch #3456, systems running more than 25 million green threads are able to make forward progress rather than thrashing. And yet, tested in the necessary environment, these patches may be sound and even necessary. -- [W]hen I wrote it I was more than a little John Cowan febrile with foodpoisoning from an antique carrot co...@ccil.org that I foolishly ate out of an illjudged faith http://ccil.org/~cowan in the benignancy of vegetables. --And Rosta ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] replace signal with sigaction
On Thu, Sep 29, 2011 at 05:45:46PM +0200, Jörg F. Wittenberger wrote: Here an interesting finding: On Sep 29 2011, Alan Post wrote: This patch replaces signal with sigaction for registering signals. sigaction is a newer API for signal processing that fixes some deficiencies of the original signal API. One fix can be seen in this patch: we don't have to reregister the signal handler after a signal is sent. That prevents a race condition whereby a signal is delivered, our signal handler is reset, and before we can reregister our signal handler, another signal is sent (which we then miss). Since I'm quite old school I've been used to the meaning of signals to be almost reliable. Except under arbitrary complex usage restrictions. Hence I rarely ever tried to count signals, but use them as a hint, which operation would be in order. This might have been not enough! Turn out that with your patch applied something changed: I had one usage case, which almost sure (say ~50%+-25%) would run into that eat-all-memory condition. I tried too often, I fail to reproduce the condition. However at this time I can't convince myself that this is not a false positive. :-/ Even with my patch, there is still a bug in the chicken signal handler: void global_signal_handler(int signum) { C_raise_interrupt(signal_mapping_table[ signum ]); } This signal handler will notify the main thread that signal X has been raised, but it doesn't keep track of how often that happens. By the time we get around to handling this signal, it could have been raised more than once, and we only fire our signal handler once regardless of how many signals were delivered between the original interrupt and executing the deferred handler. If you're doing anything at all that is reasonably interrupt heavy, you're going to be seeing this behavior. The quick test would be to fork a few hundred children (that all immediately exit) all at once and count the number of times SIGCHLD is raised. I haven't written this test yet, it's my next test case to follow my EINTR test--though I suspect you'll get fewer SIGCHLD interrupts than you had spawned children. I also suspect there is a condition here where the signal handler flags the interrupt to be raised, but we're already servicing the deferred signal, and it goes ahead and resets the signal_mapping_table before the signal currently being raised is handled by deferral. If you're coping with unreliable delivery from the above method, maybe you're seeing this case instead, which would be a different class of behavior. Rather than 1 or more deferred signals being delivered for N signals raised, you might well see 0 under this condition--If this can happen at all. I'm assuming it can, looking at the code, but haven't verified yet. -Alan -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 04:47 PM, Alan Post wrote: The way Chicken is currently implemented, any signal that arrives during this time is discarded, which also makes me unhappy with this situation. A lot of blood and tears were spilled over signal handling on Unix to get to reliable signal delivery. I don't think Chicken should implement unreliable signal delivery on top of a reliable mechanism. I quite agree. It seems that the thread-like nature of signal handling and the thread-like nature of threading have been intermixed in the scheduler, and this particular feature is at cross-purposes. So it seems... Signals should always end up being handled somewhere, unlessly explicitly set to be ignored; in that case, ignoring it IS handling it, but not otherwise. IIRC, signals are handled by setting a flag and poking the stack limit then returning. A GC is then invoked as soon as the interrupted thread tries to allocate memory, due to the poked stack limit, but the GC checks for the signal flag and goes off to do the signal if it has to. I presume that invoking the Chicken runtime inside the C-level signal handler is unsafe on account of Chicken wanting to call non-signal-safe C functions. I presume that allocating memory in a Chicken-level signal handler is risky as you might have actually been at or near the stack limit when the signal happened. I have not looked at the mechanism in code - just heard hearsay about it - - so please take this suggestion with a pinch of salt: 1) Have a (signal-safe) data structure containing pending signals. This might just be a bitmask, or if we want to be flash, a queue of generic pending software interrupts if there's uses for it other than signals. 2) C-level signal handlers poke an entry into the structure indicating the need to invoke a Chicken signal handler, and poke the stack limit [all of the above is basically what I think we already have] 3) The GC, invoked due to the stack limit being breached, checks for pending signals. If there are any, it resets the stack limit to what it was originally, then modifies the currently active continuation to a newly-allocated one that invokes a system procedure which executes all pending signals, then continues to the previous continuation; and returns. The normal stack limit needs to be set so that there will always, in the worst case, be enough space to allocate that extra continuation frame. If the system WAS at the edge of the stack when the signal(s) came in, it would then still be able to allocate the special continuation; execution of it would then almost instantly trigger a perfectly ordinary GC, and execution would continue as usual, executing the pending signal handler(s) then continuing with user code as before. That would give you low latency, unless the GC really needed to happen, in which case... well... it needs to happen before the handler can run. It would run signal handlers in the context of the currently executing thread when they happened, so to all intents and purposes it would be normal Chicken code, and the current thread would just temporarily dart off into signal handlers when required; I'm not sure what dynamic environment (in the parameters/current-output-port) they should be in; neither do I know how they are implemented in Chicken! Perhaps they should encapsulate a copy of the dynamic environment in place when the signal handler was registered, as the most hygienic option... -Alan ABS - -- Alaric Snell-Pym http://www.snell-pym.org.uk/alaric/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk6El54ACgkQRgz/WHNxCGpebACfdxF+Fqb3OiEVJHoAaww3U23f inkAnRCPDl2dZhWrrdBODaBC8+rCDdHY =VjKl -END PGP SIGNATURE- ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] two minor tweaks to runtime.c
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 04:51 PM, John Cowan wrote: Alaric Snell-Pym scripsit: If the supposed performance improvement can't be benchmarked, then it's pointless, as nobody will actually benefit from it. Any case where somebody can benefit from a performance improvement can be turned into a benchmark that consists of running the code that is sped up, and timing it. Benchmarks are like unit tests; they are snippets of code that perform some operation but, rather than testing correct responses, their emphasis is on testing resource usage. Your clarification down-thread that a benchmark can be of any size makes this comparison rather otiose. Nobody is going to have a benchmark suite that includes tests like these: With patch #1234, application 'foo' runs in an acceptable 18 hours rather than an intolerable 25 hours. (Obviously the improvement has to be nonlinear.) Actually, where I work we do! The full test suite takes all weekend - on a cluster of fairly beefy hardware, running different bits in parallel. But there's a hierarchy of tests and benchmarks. The correctness tests we run on our laptops before committing code to the trunk take fifteen minutes, and we run benchmarks in the five-minute range for quickly checking the results of changes. The full suite runs only once a week... ABS - -- Alaric Snell-Pym http://www.snell-pym.org.uk/alaric/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk6EmFQACgkQRgz/WHNxCGp2IwCfcofES+0R2BLmTBZ18wStt5Yf /zUAn3Z0NYBhWzWrDodOF6+gPi3441k5 =DVDu -END PGP SIGNATURE- ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
On Thu, Sep 29, 2011 at 05:06:54PM +0100, Alaric Snell-Pym wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 04:47 PM, Alan Post wrote: It seems that the thread-like nature of signal handling and the thread-like nature of threading have been intermixed in the scheduler, and this particular feature is at cross-purposes. So it seems... Signals should always end up being handled somewhere, unlessly explicitly set to be ignored; in that case, ignoring it IS handling it, but not otherwise. I'll add too that signals have an API-level mechanism for ignoring them, which we should probably use. And yes. IIRC, signals are handled by setting a flag and poking the stack limit then returning. A GC is then invoked as soon as the interrupted thread tries to allocate memory, due to the poked stack limit, but the GC checks for the signal flag and goes off to do the signal if it has to. I presume that invoking the Chicken runtime inside the C-level signal handler is unsafe on account of Chicken wanting to call non-signal-safe C functions. It would be something of a minor miracle were this not true. I think it is technically achievable, though I say that with zero understanding of the actual effort involved. It's more my ideal case worth banging my head against a few times than something I think we can do in practice. I presume that allocating memory in a Chicken-level signal handler is risky as you might have actually been at or near the stack limit when the signal happened. I have not looked at the mechanism in code - just heard hearsay about it - - so please take this suggestion with a pinch of salt: 1) Have a (signal-safe) data structure containing pending signals. This might just be a bitmask, or if we want to be flash, a queue of generic pending software interrupts if there's uses for it other than signals. 2) C-level signal handlers poke an entry into the structure indicating the need to invoke a Chicken signal handler, and poke the stack limit [all of the above is basically what I think we already have] 3) The GC, invoked due to the stack limit being breached, checks for pending signals. If there are any, it resets the stack limit to what it was originally, then modifies the currently active continuation to a newly-allocated one that invokes a system procedure which executes all pending signals, then continues to the previous continuation; and returns. The normal stack limit needs to be set so that there will always, in the worst case, be enough space to allocate that extra continuation frame. If the system WAS at the edge of the stack when the signal(s) came in, it would then still be able to allocate the special continuation; execution of it would then almost instantly trigger a perfectly ordinary GC, and execution would continue as usual, executing the pending signal handler(s) then continuing with user code as before. The Minix source code is illustrative on this point. I think a program being near the stack limit when a signal arrives is the only time in that operating system that a process will be killed without the normal mechanims the kernel goes through--It just tosses the thing out. I've never looked at how this behaves on *BSD or Linux, but I imagine there is a similar condition (or as you outline above, a reserve available). So this comes up even in C, which at least on Minux is not a handleable condition. We effectively can't handle it if our GC makes a syscall--I imagine that we minimally call sbrk() (or whatever the kids call it these days) in the event of a full, post-GC heap. That may well be a terminal case in this rabbit hole, mirroring the terminal case in the C code. That would give you low latency, unless the GC really needed to happen, in which case... well... it needs to happen before the handler can run. It would run signal handlers in the context of the currently executing thread when they happened, so to all intents and purposes it would be normal Chicken code, and the current thread would just temporarily dart off into signal handlers when required; I'm not sure what dynamic environment (in the parameters/current-output-port) they should be in; neither do I know how they are implemented in Chicken! Perhaps they should encapsulate a copy of the dynamic environment in place when the signal handler was registered, as the most hygienic option... I pretty much rely on my registered signal handler being in the dynamic environment it was declared in. The EINTR test case uses this to get hold of a file descriptor created in the main thread. I'll add that we might of course get a signal while performing GC, a case that needs to be accounted for. And that we also *must* handle deferred signals before making another syscall, whether that syscall happened from user code or whether we're making a syscall in service to the need of the runtime. I think is a fantastic outline of what
Re: [Chicken-users] remove enable/disable interrupt flag
On Sep 29 2011, Alaric Snell-Pym wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 09/29/2011 04:25 PM, Jörg F. Wittenberger wrote: POSIX says that fork needs to produce only a single surviving POSIX thread in the child. Perhaps Chicken fork needs to do the same with Chicken threads. Alaric, that's exactly the effect and reason why I'm using this disable-interrupts/enable-interrupts around fork: to make sure there is only this one Chicken-threads running in the child. With interrupts disabled there is no scheduling in chicken. (At least not until you run into a thread-yield! anyway.) And therefore I'd really recommend to keep it in the runtime. I think a better mechanism would be a way to abort all threads but the current one, triggered after the fork in the child, with no interrupts until the thread murder is complete. True. Though I view doing this as a higher level, complete solution. And it depends on the ability to disable interrupts. Given that we can, we are free to choose an option: A) Forget about all other chicken threads and just exec the code. This is the vfork-then-exec case. Chances are that this is, what the doctor ordered in most cases. (As it is in mine.) B) Kill the threads and re-enable chicken's scheduler (aka enable-initerupts). (B) might need some more considerations. I'm not sure how this could be mapped to srfi-18. I'll abstain from guess work here. If you just go off and exec after the fork it'd be better to uninterruptably vfork-then-exec, but we have procedures to do that already! Aborting all threads but the one that asked for the fork also gives one the opportunity to inform them of this fact, should any of them leave useful data structures in incosistent states with locks held. There's something to be said for requesting permission to fork from all threads before doing so, so they can make sure they finish any operations on shared state in the parent, but that'll be complex, and a potential performance bottleneck, so probably not worth it! ABS - -- Alaric Snell-Pym http://www.snell-pym.org.uk/alaric/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk6EkCcACgkQRgz/WHNxCGoBNwCfS5syjjCVWFiyjcP0S6z/BFoB s6MAnjE+v+0Tf32+9bQ+X6wd6UgEA+pA =fjVS -END PGP SIGNATURE ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
On Sep 29 2011, Alan Post wrote: The way Chicken is currently implemented, any signal that arrives during this time is discarded, which also makes me unhappy with this Wait, I'm confused. During which time signals are really discarded? As far as I read the source, the signal will be recorded, not discarded. Now this could run into the situation, that there would be several signals (to be) recorded until they are handled. This is exactly the situation my changes to the signal handler as initially proposed recently would handle. At least for MAX_INT many signals (which, when pending, should bring your machine down in any case). situation. A lot of blood and tears were spilled over signal handling on Unix to get to reliable signal delivery. I don't think Chicken should implement unreliable signal delivery on top of a reliable mechanism. That's what I've been asking lately: should we call the signal handler once for every signal, or might it be better to change the signal handlers signature to receive the number of times the signal has seen since the signal handler was called last time. NB: the former would be easy to implement on top of the latter. The latter could be quite some overhead for no good reason. Maybe the latter should be the default which can be changed by the user. My current code however does the opposite: it deliberately calls the handler once per invocation using the old API. Thereby possibly ignoring signals (it discards and resets the counter. (I had not yet the time to write the code for the maybe-case and change the API) Since my code does not count the signals, it works well under this condition. ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] EINTR with self-pipe signal trampoline
On Sep 29 2011, Alan Post wrote: Let me try a demonstration showing just the main thread: (define (restart-read fd buf isize) ; call read(2), on the self-pipe, which blocks (let ((r (file-read fd buf isize))) (if (= -1 r) ; ah, a signal was delivered. In Chicken, the signal ; delivery to the prcoess causes this error, but the ; Scheme code signal handler might not have been ; delivered. In this case, it means that I haven't ; written a byte to the self-pipe yet. ; (if (= errno EINTR) ; restart the read. Normally, we would have written ; to our self-pipe already (as the signal is delivered ; the moment we return from our syscall.), but in ; Chicken, I'm not sure our deferred Scheme code has ; been called. When does that happen? If it hasn't ; happened yet, I'll block in this routine, and the ; deferred signal handler will never run. ; ; I need a way to guarantee that the deferred signal ; handler has already been run, before I call any other ; syscall. ; (restart-read fd buf isize)) ; something else went wrong, die. (io-error read Does that story make more sense? Chicken may already behave this way, I'm not sure how long it waits/when it delivers a deferred signal. The critically important thing is that it do so before making another syscall. Yes. That looks quite like the code in the process-io-ports as I posted before. (let-location ((again bool #f)) (lambda () (when (fx= bufindex buflen) (let loop () (and (not iclosed) (let ([n ((foreign-lambda* int ((int fd) (scheme-pointer buf) (int s) ((c-pointer bool) again)) int r = read(fd, buf, s); *again=(r==-1)(errno == EAGAIN); return(r);) fdr buf buffer-size (location again))]) (cond (again (thread-wait-for-i/o! fdr #:input) (loop)) Here the thread is scheduled to wait again if EAGAIN has been in errno. But you are right: the EINTR call is not handled. That's a bug for sure. I need to fix it. /Jörg ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
On Thu, Sep 29, 2011 at 06:56:03PM +0200, Jörg F. Wittenberger wrote: On Sep 29 2011, Alan Post wrote: The way Chicken is currently implemented, any signal that arrives during this time is discarded, which also makes me unhappy with this Wait, I'm confused. During which time signals are really discarded? As far as I read the source, the signal will be recorded, not discarded. If a signal is called when C_interrupts_enabled is false, the signal handler turns into a no-op. global_signal_handler calls C_raise_interrupt, but C_raise_interrupt does nothing if C_interrupts_enabled is false, the entire routine is contained in that if statement. My reading of that is that a signal being delivered when C_interrupts_enabled is false wil cause that signal to be discarded. Yes? -Alan -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] replace signal with sigaction
On Thu, Sep 29, 2011 at 02:15:29PM -0400, John Cowan wrote: Alan Post scripsit: Does the ANSI C behavior specify that a signal must be re-registered after it is called? Is it more reliable for me to follow the ANSI C standard or the w32 documentation on this interface? If w32, where do I find that? The Woe32 documentation is silent about such fine points: the interface probably dates back to Windows 3 or even MS-DOS. For future reference, it's at http://msdn.microsoft.com/en-us/library/634ca0c2.aspx . Before the specified function is executed, the value of func is set to SIG_DFL. The next interrupt signal is treated as described for SIG_DFL, unless an intervening call to signal specifies otherwise. This feature lets you reset signals in the called function. That's good enough (well not really *good*, but *enough*) to know how to implement signal handling on missing-sigaction platforms. Thank you, -Alan -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] replace signal with sigaction
Alan Post scripsit: That's good enough (well not really *good*, but *enough*) to know how to implement signal handling on missing-sigaction platforms. You're right. Note also, however: For floating-point exceptions, the value of func is not reset upon receiving the signal. -- John Cowan co...@ccil.org http://www.ccil.org/~cowan Thor Heyerdahl recounts his attempt to prove Rudyard Kipling's theory that the mongoose first came to India on a raft from Polynesia. --blurb for Rikki-Kon-Tiki-Tavi ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
On Sep 29 2011, Alan Post wrote: On Thu, Sep 29, 2011 at 06:56:03PM +0200, Jörg F. Wittenberger wrote: On Sep 29 2011, Alan Post wrote: The way Chicken is currently implemented, any signal that arrives during this time is discarded, which also makes me unhappy with this Wait, I'm confused. During which time signals are really discarded? As far as I read the source, the signal will be recorded, not discarded. If a signal is called when C_interrupts_enabled is false, the signal handler turns into a no-op. global_signal_handler calls C_raise_interrupt, but C_raise_interrupt does nothing if C_interrupts_enabled is false, the entire routine is contained in that if statement. My reading of that is that a signal being delivered when C_interrupts_enabled is false wil cause that signal to be discarded. Yes? Yes. That's what I've been talking about in the next paragraph. With the changes I made (did I post them, did not I?) this problem is gone. Hence my question how to clean up the API. Default to possibly useless re-calling the handler (while it assumes possibly having missed a signal and hence re-check everything)? Provide a modified API which covers both cases? ... ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
On Thu, Sep 29, 2011 at 08:35:41PM +0200, Jörg F. Wittenberger wrote: On Sep 29 2011, Alan Post wrote: If a signal is called when C_interrupts_enabled is false, the signal handler turns into a no-op. global_signal_handler calls C_raise_interrupt, but C_raise_interrupt does nothing if C_interrupts_enabled is false, the entire routine is contained in that if statement. My reading of that is that a signal being delivered when C_interrupts_enabled is false wil cause that signal to be discarded. Yes? Yes. That's what I've been talking about in the next paragraph. With the changes I made (did I post them, did not I?) this problem is gone. Hence my question how to clean up the API. Default to possibly useless re-calling the handler (while it assumes possibly having missed a signal and hence re-check everything)? Provide a modified API which covers both cases? ... It may have been posted before I was really attending to this conversation. I can't find it in my archive. Would you mind sending it to me again? -Alan -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] EINTR with self-pipe signal trampoline
On Sep 29 2011, Jörg F. Wittenberger wrote: On Sep 29 2011, Alan Post wrote: Let me try a demonstration showing just the main thread: (define (restart-read fd buf isize) ; call read(2), on the self-pipe, which blocks (let ((r (file-read fd buf isize))) (if (= -1 r) ; ah, a signal was delivered. In Chicken, the signal ; delivery to the prcoess causes this error, but the ; Scheme code signal handler might not have been ; delivered. In this case, it means that I haven't ; written a byte to the self-pipe yet. ; (if (= errno EINTR) ; restart the read. Normally, we would have written ; to our self-pipe already (as the signal is delivered ; the moment we return from our syscall.), but in ; Chicken, I'm not sure our deferred Scheme code has ; been called. When does that happen? If it hasn't ; happened yet, I'll block in this routine, and the ; deferred signal handler will never run. ; ; I need a way to guarantee that the deferred signal ; handler has already been run, before I call any other ; syscall. ; (restart-read fd buf isize)) ; something else went wrong, die. (io-error read Does that story make more sense? Chicken may already behave this way, I'm not sure how long it waits/when it delivers a deferred signal. The critically important thing is that it do so before making another syscall. Yes. That looks quite like the code in the process-io-ports as I posted before. (let-location ((again bool #f)) (lambda () (when (fx= bufindex buflen) (let loop () (and (not iclosed) (let ([n ((foreign-lambda* int ((int fd) (scheme-pointer buf) (int s) ((c-pointer bool) again)) int r = read(fd, buf, s); *again=(r==-1)(errno == EAGAIN); return(r);) fdr buf buffer-size (location again))]) (cond (again (thread-wait-for-i/o! fdr #:input) (loop)) Try fixing the problem by replacing *again=(r==-1)(errno == EAGAIN); with *again=(r==-1)((errno == EAGAIN) || (errno == EINTR)); And do so again in the output case. So far I'm in a bogus situation: a) I applied that sigaction-patch. Since I've not seen the problem, which has eaten my nerves for about a week. b) still I've seen those kinda rare events, where I had some indication of i/o-threads dying in unexpected way with no good clean up. But those indications where wild guess work as you do, when you just have no clue how to force the case to happen. c) Those lost-in-io cases did not show up... within an all too short time to take the observation as serious. But still long enough to inform you of my personal feeling that there might be a connection. Alan, I'd give Felix' code a shot with the EINTR case fixed. Looks kinda good from my bogus poit of view. ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag -- SORRY
On Sep 29 2011, Jörg F. Wittenberger wrote: Wait, I'm confused. Obviously I am. I've been talking nonsense. Sorry for the confusion. Finalizers and signal handlers are run with the same restrictions on allocating memory. (My confusion came from the idea in the back of my head, that I might eventually remove the handle_interrupt at the begin of C_reclaim completely if I could prove that running finalizers where I run signal handlers right now would be a safe thing to do.) Right now I'm running signal handlers from the scheduler as soon as the yielding thread is where it belongs (ready queue or garbage). That would be after the context switch. But as I'm preparing this message I noticed that there's another badly handles case in my code (EINTR translated into a thread-yield if I'm correct). However I need to remind you that I'm currently working from kinda wild guess work. I'm reading the code and docs I found so far. (Giving priority to the way I understand the current code.) And there is one more case where I might need some help. A bad one in fact. The whole s* works quite well with many threads. However somehow I'm missing the spot where I can hook into the execution right *after* gc. With threads: in ##sys#schedule in scheduler.scm without threads I'm unsure. As I read the source it should arrive in ##sys#schedule too, but this time in library.scm. However: there I called the signal handler too. So far I have *not* made sure that it is not called. But trying to stop chicken compiling itself by pressing C-c will be ignored. I know: this could have been a different reason. ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] valgrind
I'm still asking myself why I can't run chicken program under valgrind. Since there's a lot going on at this time I'm about to forget. Hence here an update for those who care and the archive. I've traced the call coming from irregex.c down to valgrind complaining as soon as *all-chars* value is accessed. (I did not yet come around to prepare a test case where I'd only cons up a random list (or a list of char's - wild guess) and see if I can sync valgrind's output enough to verify that it will complain on code which is supposed to work at all counts.) (The back of my head now might be about to forget that a less expensive implementations of charset and their merges might be obvious; even in R5RS Scheme. Right now they are a pretty nice test case to see how much a few instructions shaved from the cons operation would speed up the program initialization over all.) Furthermore I'd know that chicken might to weird things to the stack. Maybe valgrind was just a bad choice. Wild guess again. But as far as I understand valgrind so far (which is close to nothing at all), it would instrument then executable code only. Given that I see access to uninitialized memory resulting from stack allocation - I wonder: maybe valgrind is right? Now, at this time it my memory consumption issue does not appear. Real work is pressing. I'll not find the time to dig deeper into these things any time soon. Except if I'm wrong about the does not appear. /Jerry ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] valgrind
On Thu, Sep 29, 2011 at 09:38:44PM +0200, Jörg F. Wittenberger wrote: I'm still asking myself why I can't run chicken program under valgrind. Since there's a lot going on at this time I'm about to forget. Hence here an update for those who care and the archive. I've traced the call coming from irregex.c down to valgrind complaining as soon as *all-chars* value is accessed. (I did not yet come around to prepare a test case where I'd only cons up a random list (or a list of char's - wild guess) and see if I can sync valgrind's output enough to verify that it will complain on code which is supposed to work at all counts.) (The back of my head now might be about to forget that a less expensive implementations of charset and their merges might be obvious; even in R5RS Scheme. Right now they are a pretty nice test case to see how much a few instructions shaved from the cons operation would speed up the program initialization over all.) Furthermore I'd know that chicken might to weird things to the stack. Maybe valgrind was just a bad choice. Wild guess again. But as far as I understand valgrind so far (which is close to nothing at all), it would instrument then executable code only. Given that I see access to uninitialized memory resulting from stack allocation - I wonder: maybe valgrind is right? Now, at this time it my memory consumption issue does not appear. Real work is pressing. I'll not find the time to dig deeper into these things any time soon. Except if I'm wrong about the does not appear. /Jerry Since it seems as good a day as any for wild-ass speculation, what about this scenario: We allocate an object, set the tag pointer, but don't fill out all of the memory yet. We're yet to need it. Oops! The gc gets called, and that object has to move. So we memcpy it to it's new home and tuck it into bed. Wouldn't valgrind complain that we just memcpy'd uninitialized memory, even though in this case it is a completely safe operation? -Alan -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] valgrind
On Sep 29 2011, Alan Post wrote: Since it seems as good a day as any for wild-ass speculation, what about this scenario: We allocate an object, set the tag pointer, but don't fill out all of the memory yet. We're yet to need it. Oops! The gc gets called, and that object has to move. So we memcpy it to it's new home and tuck it into bed. Wouldn't valgrind complain that we just memcpy'd uninitialized memory, even though in this case it is a completely safe operation? Maybe. Maybe Felix could shed some light. I can't. However as far as I read it, this should not happen. The pattern is to allocate some space on the stack, fill stuff in, eventually jump to the continuation. GC will only happen during the jump, not within the time between allocation and assignment of initial values. (Beware: It's my reading of source!) ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
On Sep 29 2011, Alan Post wrote: Hence my question how to clean up the API. Default to possibly useless re-calling the handler (while it assumes possibly having missed a signal and hence re-check everything)? Provide a modified API which covers both cases? ... It may have been posted before I was really attending to this conversation. I can't find it in my archive. Would you mind sending it to me again? Not at all. Given the doubt whether or not this conversation pertains to the before mentioned issue https://bugs.call-cc.org/ticket/668 I'm not sure: should we take this conversation private for a while or not. The situation is: right now I'm running from a modified chicken. Changes have been made to a) the signal handling b) the finalizer_list and list constructors as posted recently c) the scheduler and srfi-18 (ages ago) d) for historic reasons: the time representation (see below for an excuse) At least for (d) there is no reason for you to swallow that one. (c) might fix a bug - risky enough if your code relies on it -- or it may introduce one my code relies on. The note to take to the chicken community: it's a nice feature in a way, that chicken needs only on .h and on .c file plus your code. But this features now shows it's downside: it's hard to merge independent changes. It's hard to track the common ground. However (c) does have some overlap with (a) - which would be what you are interested in to begin with. We will not be able to reconcile without manual intervention. Worse: (a) and (d) do overlap in runtime.c and chicken.c (for what the excuse is worth)... Alan, what would be the best? Several postings on the list detailing the changes (good for documentation; needs manual integration always; thereby forcing code review)? A full diff from current git to my current state of affairs (watch out for excuses below!)? /Jörg PS: The Excuse Since I've only recently reached the state of affairs that I can expose the Chicken-compiled version of Askemos to the net without keeping an eye on the firewall, I did so far not even dare to change the time representation for a reason unrelated to Chicken. So far the only Scheme for which there was a working implementation of Askemos/BALL was RScheme. Therefore the network ran all public nodes on RScheme. Now the DHT is updated in byzantine agreement, whereby a current time (which is not the current-time from Chicken) is going to be part of the checksum the agreement in being run on. One of the closest-to-worst cases which could hit me would be, if due to some hypothetical rounding error representing the same time value for the checksum would occasionally result in a different representation under RScheme and Chicken. (Which in turn would make the update fail. If all that byzantine agreement relates stuff does not make any sense to you: take the idea of http://code.google.com/p/upright/ - you find an API where you plug in you application code (one single step that is). Now forget upright and java. Plug in a single step of a Scheme interpreter. You've got it?) I did not dare to even try floats. Too floating this ground. ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
On Thu, Sep 29, 2011 at 10:20:28PM +0200, Jörg F. Wittenberger wrote: On Sep 29 2011, Alan Post wrote: Hence my question how to clean up the API. Default to possibly useless re-calling the handler (while it assumes possibly having missed a signal and hence re-check everything)? Provide a modified API which covers both cases? ... It may have been posted before I was really attending to this conversation. I can't find it in my archive. Would you mind sending it to me again? Not at all. Given the doubt whether or not this conversation pertains to the before mentioned issue https://bugs.call-cc.org/ticket/668 I'm not sure: should we take this conversation private for a while or not. The situation is: right now I'm running from a modified chicken. Changes have been made to a) the signal handling b) the finalizer_list and list constructors as posted recently c) the scheduler and srfi-18 (ages ago) d) for historic reasons: the time representation (see below for an excuse) At least for (d) there is no reason for you to swallow that one. (c) might fix a bug - risky enough if your code relies on it -- or it may introduce one my code relies on. The note to take to the chicken community: it's a nice feature in a way, that chicken needs only on .h and on .c file plus your code. But this features now shows it's downside: it's hard to merge independent changes. It's hard to track the common ground. However (c) does have some overlap with (a) - which would be what you are interested in to begin with. We will not be able to reconcile without manual intervention. Worse: (a) and (d) do overlap in runtime.c and chicken.c (for what the excuse is worth)... Alan, what would be the best? Several postings on the list detailing the changes (good for documentation; needs manual integration always; thereby forcing code review)? A full diff from current git to my current state of affairs (watch out for excuses below!)? /Jörg Fun! I'd rather look at an isolated a), even if it doesn't compile, than try to digest the rest of this too. If you can just send me the parts of your tree that pertain to a), even if that patch does not result in code that compiles, that would help me the most. It's ok if, for instance, I get a patch that leads off into b, c, or d and you just fail to include that. Will you do this? I am curious to see your signal handling patch. -Alan -- .i ma'a lo bradi cu penmi gi'e du ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] remove enable/disable interrupt flag
On Sep 29 2011, Alan Post wrote: On Thu, Sep 29, 2011 at 10:20:28PM +0200, Jörg F. Wittenberger wrote: On Sep 29 2011, Alan Post wrote: Hence my question how to clean up the API. Default to possibly useless re-calling the handler (while it assumes possibly having missed a signal and hence re-check everything)? Provide a modified API which covers both cases? ... It may have been posted before I was really attending to this conversation. I can't find it in my archive. Would you mind sending it to me again? Not at all. Given the doubt whether or not this conversation pertains to the before mentioned issue https://bugs.call-cc.org/ticket/668 I'm not sure: should we take this conversation private for a while or not. The situation is: right now I'm running from a modified chicken. Changes have been made to a) the signal handling b) the finalizer_list and list constructors as posted recently c) the scheduler and srfi-18 (ages ago) d) for historic reasons: the time representation (see below for an excuse) At least for (d) there is no reason for you to swallow that one. (c) might fix a bug - risky enough if your code relies on it -- or it may introduce one my code relies on. The note to take to the chicken community: it's a nice feature in a way, that chicken needs only on .h and on .c file plus your code. But this features now shows it's downside: it's hard to merge independent changes. It's hard to track the common ground. However (c) does have some overlap with (a) - which would be what you are interested in to begin with. We will not be able to reconcile without manual intervention. Worse: (a) and (d) do overlap in runtime.c and chicken.c (for what the excuse is worth)... Alan, what would be the best? Several postings on the list detailing the changes (good for documentation; needs manual integration always; thereby forcing code review)? A full diff from current git to my current state of affairs (watch out for excuses below!)? /Jörg Fun! I'd rather look at an isolated a), even if it doesn't compile, than try to digest the rest of this too. If you can just send me the parts of your tree that pertain to a), even if that patch does not result in code that compiles, that would help me the most. It's ok if, for instance, I get a patch that leads off into b, c, or d and you just fail to include that. Will you do this? I am curious to see your signal handling patch. -Alan I'll do so. But I have to call this a day for today. Some sad news: it looks as if things are much better now on Linux/AMD64 but the Sheeva Plug seems to still loose on i/o. I even got the feeling that it might loose more than before. (Which could be a hint for the days to come.) ___ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] replace signal with sigaction
On Thu, Sep 29, 2011 at 07:25:31AM -0600, Alan Post wrote: This patch replaces signal with sigaction for registering signals. sigaction is a newer API for signal processing that fixes some deficiencies of the original signal API. One fix can be seen in this patch: we don't have to reregister the signal handler after a signal is sent. That prevents a race condition whereby a signal is delivered, our signal handler is reset, and before we can reregister our signal handler, another signal is sent (which we then miss). I'm not sure even signal() behaves this way these days. It used to be one tested for sigaction in the same way you might test for other features. I'm not sure if chicken runs on a platform that doesn't have sigaction--do I need to add a feature test for this and preserve the existing capability on platforms without sigaction? -Alan I have ammended this patch to include a HAVE_SIGACTION define, to preserve the existing functionality on w32 systems. diff --git a/Makefile.bsd b/Makefile.bsd index 5eab203..98e44fd 100644 --- a/Makefile.bsd +++ b/Makefile.bsd @@ -83,6 +83,7 @@ chicken-config.h: chicken-defaults.h echo #define HAVE_LONG_LONG 1 $@ echo #define HAVE_MEMMOVE 1 $@ echo #define HAVE_MEMORY_H 1 $@ + echo #define HAVE_SIGACTION 1 $@ echo #define HAVE_STDINT_H 1 $@ echo #define HAVE_STDLIB_H 1 $@ echo #define HAVE_STRERROR 1 $@ diff --git a/Makefile.cygwin b/Makefile.cygwin index f56bc29..cee6e74 100644 --- a/Makefile.cygwin +++ b/Makefile.cygwin @@ -95,6 +95,7 @@ chicken-config.h: chicken-defaults.h echo #define HAVE_LONG_LONG 1 $@ echo #define HAVE_MEMMOVE 1 $@ echo #define HAVE_MEMORY_H 1 $@ + echo #define HAVE_SIGACTION 1 $@ echo #define HAVE_STDINT_H 1 $@ echo #define HAVE_STDLIB_H 1 $@ echo #define HAVE_STRERROR 1 $@ diff --git a/Makefile.haiku b/Makefile.haiku index 1f86bc3..54634a2 100644 --- a/Makefile.haiku +++ b/Makefile.haiku @@ -71,6 +71,7 @@ chicken-config.h: chicken-defaults.h echo #define HAVE_LONG_LONG 1 $@ echo #define HAVE_MEMMOVE 1 $@ echo #define HAVE_MEMORY_H 1 $@ + echo #define HAVE_SIGACTION 1 $@ echo #define HAVE_STDINT_H 1 $@ echo #define HAVE_STDLIB_H 1 $@ echo #define HAVE_STRERROR 1 $@ diff --git a/Makefile.linux b/Makefile.linux index c713b45..6e5116a 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -72,6 +72,7 @@ chicken-config.h: chicken-defaults.h echo #define HAVE_LONG_LONG 1 $@ echo #define HAVE_MEMMOVE 1 $@ echo #define HAVE_MEMORY_H 1 $@ + echo #define HAVE_SIGACTION 1 $@ echo #define HAVE_STDINT_H 1 $@ echo #define HAVE_STDLIB_H 1 $@ echo #define HAVE_STRERROR 1 $@ diff --git a/Makefile.macosx b/Makefile.macosx index b4a44d9..da612a4 100644 --- a/Makefile.macosx +++ b/Makefile.macosx @@ -96,6 +96,7 @@ chicken-config.h: chicken-defaults.h echo #define HAVE_LONG_LONG 1 $@ echo #define HAVE_MEMMOVE 1 $@ echo #define HAVE_MEMORY_H 1 $@ + echo #define HAVE_SIGACTION 1 $@ echo #define HAVE_STDINT_H 1 $@ echo #define HAVE_STDLIB_H 1 $@ echo #define HAVE_STRERROR 1 $@ diff --git a/Makefile.solaris b/Makefile.solaris index f2d4dee..84dc433 100644 --- a/Makefile.solaris +++ b/Makefile.solaris @@ -102,6 +102,7 @@ chicken-config.h: chicken-defaults.h echo #define HAVE_LONG_LONG 1 $@ echo #define HAVE_MEMMOVE 1 $@ echo #define HAVE_MEMORY_H 1 $@ + echo #define HAVE_SIGACTION 1 $@ echo #define HAVE_STDINT_H 1 $@ echo #define HAVE_STDLIB_H 1 $@ echo #define HAVE_STRERROR 1 $@ diff --git a/chicken.h b/chicken.h index 1739fb9..a154fbe 100644 --- a/chicken.h +++ b/chicken.h @@ -859,7 +859,11 @@ DECL_C_PROC_p0 (128, 1,0,0,0,0,0,0,0) # define C_isatty isatty # define C_fileno fileno # define C_select select +# if defined(HAVE_SIGACTION) +# define C_sigactionsigaction +# else # define C_signal signal +# endif # define C_getrusagegetrusage # define C_tolower tolower # define C_toupper toupper diff --git a/runtime.c b/runtime.c index 980f303..68e3c90 100644 --- a/runtime.c +++ b/runtime.c @@ -982,7 +982,9 @@ void initialize_symbol_table(void) void global_signal_handler(int signum) { C_raise_interrupt(signal_mapping_table[ signum ]); +#if !defined(HAVE_SIGACTION) signal(signum, global_signal_handler); +#endif } @@ -4259,11 +4261,28 @@ C_regparm void C_fcall C_raise_interrupt(int reason) C_regparm C_word C_fcall C_establish_signal_handler(C_word signum, C_word reason) { int sig = C_unfix(signum); +#if defined(HAVE_SIGACTION) + struct sigaction new, old; - if(reason == C_SCHEME_FALSE) C_signal(sig, SIG_IGN); - else { + new.sa_flags = 0; +