Re: [Chicken-users] difference between ##sys#error and posix-error?

2011-09-29 Thread Christian Kellermann
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

2011-09-29 Thread Jörg F . Wittenberger

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?

2011-09-29 Thread Alaric Snell-Pym
-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?

2011-09-29 Thread Christian Kellermann
* 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

2011-09-29 Thread Jörg F . Wittenberger

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?

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Alaric Snell-Pym
-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?

2011-09-29 Thread Alaric Snell-Pym
-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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Mario Domenech Goulart
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

2011-09-29 Thread Alaric Snell-Pym
-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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread John Cowan
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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Alaric Snell-Pym
-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?

2011-09-29 Thread John Cowan
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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Alaric Snell-Pym
-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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread John Cowan
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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Alaric Snell-Pym
-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

2011-09-29 Thread Alaric Snell-Pym
-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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread John Cowan
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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Alan Post
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

2011-09-29 Thread Jörg F . Wittenberger

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

2011-09-29 Thread Alan Post
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;
+