Re: Does perl really need to use sigsetjmp? (18%performancehit)

2001-01-22 Thread Alan Burlison

Uri Guttman wrote:

 my scheme allows the user to do that. they just create a regular thread
 and request all their signal events in that thread. but my design also
 allows different threads to handle different signals (and multiple
 threads to handle the same one).

Hmm.  So how will you know the difference betwen a signal being
delivered once and handled twice and the same signal arriving twice?  I
can see that multiple threads all handling the same signal could be very
confusing.

 my main point there is that faking async i/o and sync signal delivery is
 much easier than faking threads. so we code all the internals to an
 event loop api and fake it underneath as needed on various
 platforms. much more on this soon.

As Jarkko would say:

Yes, yes yes.

:-)

Alan Burlison



Re: Does perl really need to use sigsetjmp? (18% performancehit)

2001-01-21 Thread Alan Burlison

Dan Sugalski wrote:

 *) If, and *only* if, a variable is marked as shared, then its vtable
 function pointer is replaced with a threadsafe version. (Or, rather, a
 pointer to the 'use in case of threads' table--strictly speaking it doesn't
 have to do any locking, but that would be pretty stupid) Multiple threads
 can access the shared data (the thread that shared it and any threads it
 spawns). We do no user-level locking, and if the low-level locking that the
 vtable functions do to ensure we don't core dump is really expensive, well,
 too darned bad)

Hmm.  Might be easier to say that shared variables are visible to all
threads.  I'm not sure that a parent/child relationship makes much sense
between threads, and your proposal kinda implies that sort of
relationship.

 *) We *will* yank out any promises of what threads signals (or any async
 event) fire off in. I really, *really* want to toss the promise of being
 able to die from within a signal handler that catches a real signal, but I
 don't know that Larry will go for that. (Expecting sane shutdown when you
 essentially puke from within an interrupt handler's always struck me as a
 semi-odd thing, though I understand the utility) to some extent

If perl signal handlers are dispatched from the main loop at specified
cancellation-safe points then calling die from a perl-level signal
handler should be doable.  The underlying C level handler will just have
to be careful not to do anything that isn't async signal safe.  If perl
gets a proper event loop, aren't signals just another event?

As for continuing the current pretence that you can write a 'real'
signal handler in perl - well, even Larry can't make it so merely by
wishing it so.

 * We may put in a mechanism to direct an interrupt at a particular thread
 (and probably will have to to preserve the 'die from a signal handler'
 stuff, but that'll only work for perl-generated events and non-fatal
 synchronous signals (of which there are very few))

What about automatically having a dedicated signal handling thread for
any program that is user-level threaded?  

 I don't know what Larry will want from a language perspective, but this is
 what he'll get from the core engine. I think this is the smallest safe set
 of things we can do, and I'm reasonably sure that everything else anyone
 might want can be layered on top, albeit slowly in some cases.

A very sound strategy IMHO.

Alan Burlison



Re: Does perl really need to use sigsetjmp? (18% performancehit)

2001-01-21 Thread Dan Sugalski

At 10:00 PM 1/21/01 +, Alan Burlison wrote:
Dan Sugalski wrote:

  *) If, and *only* if, a variable is marked as shared, then its vtable
  function pointer is replaced with a threadsafe version. (Or, rather, a
  pointer to the 'use in case of threads' table--strictly speaking it doesn't
  have to do any locking, but that would be pretty stupid) Multiple threads
  can access the shared data (the thread that shared it and any threads it
  spawns). We do no user-level locking, and if the low-level locking that the
  vtable functions do to ensure we don't core dump is really expensive, well,
  too darned bad)

Hmm.  Might be easier to say that shared variables are visible to all
threads.  I'm not sure that a parent/child relationship makes much sense
between threads, and your proposal kinda implies that sort of
relationship.

Well, since we're tossing refcounting for GC, I was thinking of 
implementing a sort of memory list for things referred to outside the 
current interpreter. (Generally extension code and other thread) I was 
figuring that we'd inherit from that, so putting variables on the shared 
list would mean they'd be looked at only when we cloned off an interpreter. 
That's the lazy way, though, so propagating shared variables out to the 
world's not a huge deal. A SMOP, and a cost we won't pay all that often.

  *) We *will* yank out any promises of what threads signals (or any async
  event) fire off in. I really, *really* want to toss the promise of being
  able to die from within a signal handler that catches a real signal, but I
  don't know that Larry will go for that. (Expecting sane shutdown when you
  essentially puke from within an interrupt handler's always struck me as a
  semi-odd thing, though I understand the utility) to some extent

If perl signal handlers are dispatched from the main loop at specified
cancellation-safe points then calling die from a perl-level signal
handler should be doable.  The underlying C level handler will just have
to be careful not to do anything that isn't async signal safe.  If perl
gets a proper event loop, aren't signals just another event?

Yup, though rather simplistic ones.

The issue of 'which thread' comes in with signals. We can tell with real 
async events, since they'll have thread ownership tags on them if we care, 
but we can't do that with signals, and then we have the issue of "which 
thread" to deal with?

All the synchronous signals I know of are fatal, and all the async ones 
won't tell us which thread. And, of course, there are the ones that may or 
may not be async (like SIGPIPE) for more fun. So while we *could* die from 
a signal handler, none of the ones we can catch can be associated with a 
thread. This isn't the case for non-signal signals like the die and warn 
handlers, but they're not strictly speaking signal handlers.

As for continuing the current pretence that you can write a 'real'
signal handler in perl - well, even Larry can't make it so merely by
wishing it so.

  * We may put in a mechanism to direct an interrupt at a particular thread
  (and probably will have to to preserve the 'die from a signal handler'
  stuff, but that'll only work for perl-generated events and non-fatal
  synchronous signals (of which there are very few))

What about automatically having a dedicated signal handling thread for
any program that is user-level threaded?

I'm torn between doing that and not, since firing up a second OS-level 
thread can add some overhead that we might not need with the "set a flag 
and check on op boundary" setup. I know that VMS won't kick over to the 
slower fully threadsafe version of its runtime libraries until you actually 
start a second thread, and I thought Solaris did something similar.


Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk




Re: Does perl really need to use sigsetjmp? (18%performancehit)

2001-01-21 Thread Alan Burlison

Dan Sugalski wrote:

 I'm torn between doing that and not, since firing up a second OS-level
 thread can add some overhead that we might not need with the "set a flag
 and check on op boundary" setup. I know that VMS won't kick over to the
 slower fully threadsafe version of its runtime libraries until you actually
 start a second thread, and I thought Solaris did something similar.

It's linking to libthread that makes it use the thread-safe versions of
stuff:

$ cat z.c
int main () { abort(); }

$ cc -o z z.c; ./z; pstack core
Abort(coredump)
core 'core' of 193353:  ./z
 ff3194d0 _kill(ff336000, 0, ff3385a8, 5, 229bc, ff29b784) + 8
 0001061c main (1, ffbef8ac, ffbef8b4, 20800, 0, 0) + 4
 000105f0 _start   (0, 0, 0, 0, 0, 0) + b8

$ cc -o z z.c -mt; ./z; pstack core
Abort(coredump)
core 'core' of 193574:  ./z
-  lwp# 1 / thread# 1  
 ff369494 __sigprocmask (ff36bdb8, 0, 0, 20860, ff37e000, 0) + 8
 ff35da38 _sigon   (20860, ff3859a0, 6, ffbef6f4, 20860, 1) + d0
 ff360abc _thrp_kill (0, 1, 6, ff37e000, 1, ff33a480) + f8
 ff2ca840 raise(6, 0, 0, , ff33a3ec, ) + 40
 ff2b4c04 abort(ff336000, 0, ff3385a8, 5, 100d4, 0) + 100
 00010624 main (1, ffbef8ac, ffbef8b4, 20800, 0, 0) + 4
 000105f8 _start   (0, 0, 0, 0, 0, 0) + b8
-  lwp# 2 / thread# 2  
 ff318690 _signotifywait (ff37e000, 145, 0, 0, 0, 0) + 8
 ff361930 thr_yield (0, 0, 0, 0, 0, 0) + 8c
-  lwp# 3  
 ff316234 _door_return (3, ff37f6d8, ff37f6f0, 3, ff37e000, 1) + 10
 ff35a1cc _lwp_start (ff245d70, 0, 6000, ffbef19c, 0, 0) + 18
 ff361930 thr_yield (0, 0, 0, 0, 0, 0) + 8c
--  thread# 3  
 ff35d6e4 _reap_wait (ff382a50, 20bf8, 0, ff37e000, 0, 0) + 38
 ff35d43c _reaper  (ff37ee80, ff3847b0, ff382a50, ff37ee58, 1, fe40)
+ 38
 ff36b4a0 _thread_start (0, 0, 0, 0, 0, 0) + 40

Alan Burlison



Re: Does perl really need to use sigsetjmp? (18%performancehit)

2001-01-21 Thread Dan Sugalski

At 11:04 PM 1/21/01 +, Alan Burlison wrote:
Dan Sugalski wrote:

  I'm torn between doing that and not, since firing up a second OS-level
  thread can add some overhead that we might not need with the "set a flag
  and check on op boundary" setup. I know that VMS won't kick over to the
  slower fully threadsafe version of its runtime libraries until you actually
  start a second thread, and I thought Solaris did something similar.

It's linking to libthread that makes it use the thread-safe versions of
stuff:

Ah, different than what I expected. ISTR some systems (possibly just the 
Digital ones) do some odd things with the libraries, basically having the 
whole runtime library being vectored, and firing off a thread changed the 
vectors from the non-threaded to the threaded version. Makes writing 
thread-agnostic code easier, since you can do locking if you need to but 
don't necessarily have to slow down the entire RTL system. (No need for 
malloc to lock, for example, in single-threaded code, since there's nothing 
that could require them be taken as you're, well, single threaded)

I could be talking out my hat, though, as it's been a while and my memory's 
an interesting thing. ("reliable" is not an appropriate adjective for it... :)

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk