Re: RFCs for thread models

2000-09-11 Thread Dan Sugalski

At 11:59 AM 9/10/00 -0700, Benjamin Stuhl wrote:
--- Chaim Frenkel [EMAIL PROTECTED] wrote:
  Now where
sub recursive() { my $a :shared; ; return
  recursive() }
  would put $a or even which $a is meant, is left as an
  excersize
  for someone brighter than me.

%P6-E-MEANINGLESS, "my $a : shared" is a meaningless
construct.

That, as they say, turns out not to be the case. :)

   #! perl -w
   my $first_arg : shared = shift;
   sub foo {
 print $first_arg, "\n";
   }
   new Thread \foo;

No reason that code shouldn't work right...

Dan

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




Re: RFCs for thread models

2000-09-11 Thread Nick Ing-Simmons

Steven W McDougall [EMAIL PROTECTED] writes:
1. All threads execute the same op tree

Consider an op, like

   fetch(b)

If you actually compile a Perl program, like

   $a = $b
   
and then look at the op tree, you won't find the symbol "$b", or "b"
anywhere in it. 

But it isn't very far away (at least for lexicals) ;-)

The fetch() op does not have the name of the variable
$b; rather, it holds a pointer to the value for $b.

It holds and index into the scratch-pad. Subs have scratch-pads 
which are cloned as needed during recursion etc. 


If each thread is to have its own value for $b, then the fetch() op
can't hold a pointer to *the* value. 

Each thread's view of the sub has its own scratch-pad - value is at same 
index in each.

-- 
Nick Ing-Simmons




Re: RFCs for thread models

2000-09-10 Thread Dan Sugalski

At 10:26 PM 9/9/00 -0400, Steven W McDougall wrote:
RFC 178 proposes a shared data model for Perl6 threads. In a shared
data model
- globals are shared unless localized
- file-scoped lexicals are shared unless the thread recompiles the
   file
- block scoped lexicals may be shared by
   - passing a reference to them
   - closures
   - declaring one subroutine within the scope of another

In short, lots of stuff is shared, and just about everything can be
shared.

I snipped out the rest here, since it's just generally wrong. (Subs don't 
need copying, and the optree doesn't currently hold pointers to 
lexicals--if it did recursion wouldn't work)

The current "share everything" model perl 5 uses is too expensive. Far too 
much is shared, and it means that for safety you have to lock and unlock 
everything. Bleah. That costs too much, and you're spending it in the wrong 
places.

The alternate perl 5 model (the one IThreads uses) actually clones off the 
data when a new thread is created. This also can be too darned expensive in 
many cases, since you really only want to access a limited set of data. 
(Though if you're careful about when a thread gets created you can dodge a 
bunch of this)

Both methods have their advantages. And both have their unneeded costs. 
There are even times when they both suck--what happens, for example, if you 
want to fire off a thread in a sub that accesses *no* package variables or 
external lexical state? It's self-contained, but you pay either way.

What would be best is if we instead tried going with Plan B. I'd write this 
up as a formal RFC, but I'm strapped for time, so here's the overview.

Creating a new thread takes two extra sets of flags. They're the same for 
lexical and package variables. These flags can be one of:

*) SHARE_ALL. This marks all the whatevers as shared. Perl flags the data 
elements as shared, and every access to everything costs. No data copying's 
done. Icky, but OK.

*) SHARE_EXPLICIT. When a new thread is created, all the variables marked 
as :shared are shared. All the rest are cloned into the new interpreter

*) SHARE_NOCOPY. When a new thread is created, all the variables marked as 
:shared are shared. All the rest are *gone*. Poof. You get an empty symbol 
table, and no lexical variables are visible. (We may need to provide empty 
variables, since there's no autoviv functionality that'll cover us here) 
Maybe files are shared across threads, but that's it.

When a non-shared variable is put into a shared variable, it becomes 
shared. So if you have this:

   my $foo;
   my @bar : shared;
   push @bar, \$foo;

then $foo becomes shared. Yes, we do walk references and do propagage 
sharedness through containers, so sticking a ref in a shared container 
might get you a pause. Tough noogies, you asked for it. :) (We could warn 
with -w on this)

What the default is would be up in the air. Personally, I like 
share_nocopy, but others might prefer other things.

Dan

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




Re: RFCs for thread models

2000-09-10 Thread Benjamin Stuhl

--- Chaim Frenkel [EMAIL PROTECTED] wrote:
  "SWM" == Steven W McDougall [EMAIL PROTECTED]
 writes:
 
 SWM If you actually compile a Perl program, like
 
 SWM  $a = $b
   
 SWM and then look at the op tree, you won't find the
 symbol "$b", or "b"
 SWM anywhere in it. The fetch() op does not have the
 name of the variable
 SWM $b; rather, it holds a pointer to the value for $b.
 
 Where did you get this idea from? P5 currently does many
 lookups for
 names. All globals. Lexicals live elsewhere.

Globals whose names can be resolved at compile time are,
with the SV* is stuck in to o-op_sv.

 SWM If each thread is to have its own value for $b, then
 the fetch() op
 SWM can't hold a pointer to *the* value. Instead, it
 must hold a pointer
 SWM to a map that indexes from thread ID to the value of
 $b for that
 SWM thread. Thread IDs tend to be sparse, so the map
 can't be implemented
 SWM as an array. It will have to be a hash, or a
 B*-tree, or a balanced
 SWM B-tree, or the like.

Or, say a hash table by pointer value that only contains
thread-local-ified globals - the rest juat use the stored
pointer (So for only a few thread-local globals, there is
very little overhead). I.e.

OP* PERL_FASTCALL p6_pp_fetch (perl_thread *t)
{
SV *real_sv = ((SVOP*)PL_op)-op_sv, tsv;

if (tsv = p6_ptrtbl_fetch(t-t_localsvs, real_sv))
real_sv = tsv;
p6_extend_stack(t-t_stack, 1);
p6_push(t-t_stack, real_sv);
}

 Now where
   sub recursive() { my $a :shared; ; return
 recursive() }
 would put $a or even which $a is meant, is left as an
 excersize
 for someone brighter than me.

%P6-E-MEANINGLESS, "my $a : shared" is a meaningless
construct.

-- BKS


__
Do You Yahoo!?
Yahoo! Mail - Free email you can access from anywhere!
http://mail.yahoo.com/



Re: RFCs for thread models

2000-09-09 Thread Chaim Frenkel

 "SWM" == Steven W McDougall [EMAIL PROTECTED] writes:

SWM If you actually compile a Perl program, like

SWM$a = $b

SWM and then look at the op tree, you won't find the symbol "$b", or "b"
SWM anywhere in it. The fetch() op does not have the name of the variable
SWM $b; rather, it holds a pointer to the value for $b.

Where did you get this idea from? P5 currently does many lookups for
names. All globals. Lexicals live elsewhere.

SWM If each thread is to have its own value for $b, then the fetch() op
SWM can't hold a pointer to *the* value. Instead, it must hold a pointer
SWM to a map that indexes from thread ID to the value of $b for that
SWM thread. Thread IDs tend to be sparse, so the map can't be implemented
SWM as an array. It will have to be a hash, or a B*-tree, or a balanced
SWM B-tree, or the like.

You are imagining an implementation and then arguing against it.
What about a simple block of reserved data per'stack frame' and the
$b becomes an offset into that area? And then there are all the
other offset for variables that are in outer scopes.

Here is my current 'guess'.

A single pointer to the thread interpreters private data.
A thread stack (either machine or implemented)
A thread private area for evaled code op trees (and Damian specials :-)
A thread private file scope lexical area

The lexical variables would live on the stack in some frame, with outer
scope lexicals directly addressable (I don't recall all of the details
but this is standard compiler stuff, I think the dragon book covers
this in detail)

The shared variables (e.g. main::*) would live in the well protected
global area.

Now where
sub recursive() { my $a :shared; ; return recursive() }
would put $a or even which $a is meant, is left as an excersize
for someone brighter than me.

chaim
-- 
Chaim FrenkelNonlinear Knowledge, Inc.
[EMAIL PROTECTED]   +1-718-236-0183



Re: RFCs for thread models

2000-09-09 Thread Steven W McDougall

 SWM If you actually compile a Perl program, like
 
 SWM  $a = $b
   
 SWM and then look at the op tree, you won't find the symbol "$b", or "b"
 SWM anywhere in it. The fetch() op does not have the name of the variable
 SWM $b; rather, it holds a pointer to the value for $b.
 
 Where did you get this idea from? P5 currently does many lookups for
 names. All globals. Lexicals live elsewhere.

From perlmod.pod, Symbol Tables:

the following have the same effect, though the first is more
efficient because it does the symbol table lookups at compile
time:

local *main::foo= *main::bar;
local $main::{foo}  = $main::{bar};

Perhaps I misinterpreted it.


 You are imagining an implementation and then arguing against it.

Yes.


 Here is my current 'guess'.

[...]

 Now where
   sub recursive() { my $a :shared; ; return recursive() }
 would put $a or even which $a is meant, is left as an excersize

My point is that we can't work with guesses and exercises.
We need a specific, detailed proposal that we can discuss and
evaluate. I'm hoping that someone will submit an RFC for one.


- SWM