05/01/04 04:34:15, Luke Palmer <[EMAIL PROTECTED]> wrote:

 LP> I think you're saying that each thread gets its own register set and
 LP> register stacks (the call chain is somewhat hidden within the register
 LP> stacks).  Dan has been saying we'll do this all along.
 .
That has been my interpretation, but there are others that appear to be
contradicting that view.

 LP> But you're also saying that a particular PMC can only be loaded into one
 LP> register at a time, in any thread.  So if thread A has a string in its
 LP> P17, then if thread B tries to load that string into its, say, P22, it
 LP> will block until thread A releases it.  Is this correct?
 .
Yes!

 LP> This is a novel idea.  It reduces lock acquisition/release from every
 LP> opcode to only the C<set> opcodes.  That's a win.
 .
That is the intent.

 LP> Sadly, it greatly increases the chances of deadlocks.  Take this
 LP> example:
.
    my ($somestr, $otherstr);
    sub A {
        $somestr .= "foo";
        $otherstr .= "bar";
    }
    sub B {
        $otherstr .= "foo";
        $somestr .= "bar";
    }
    Thread->new(\&A);
    Thread->new(\&B);
.
 LP> This is a fairly trivial example, and it should work smoothly if we're
 LP> automatically locking for the user.

 LP> But consider your scheme:  A loads $somestr into its P17, and performs
 LP> the concatenation.   B loads $otherstr into its P17, and performs the
 LP> concatenation.  A tries to load $otherstr into its P18, but blocks
 LP> because it's in B's P17.  B then tries to load $somestr into its P18,
 LP> but blocks because it's in A's P17.  Deadlock.

 LP> Did I accurately portray your scheme?  If not, could you explain what
 LP> yours does in terms of this example?
.
Where your description falls down is considering each sub as an opcode.
I *think* that each statement within the sub is an opcode.

Therefore the sequence of opcodes in A (simplified) is:

    A sets the in-use flag on $somestr when it loads it into P17.
    If the inuse flag was set, it aquires the mutex.
    A executes the CONCAT opcode against $somestr. 
        Constant 'foo' as operand.
    Releases the mutex.
    A then clears the in-use flag for $somestr.

    A then set the in-use flag for $otherstr.
    If the inuse flag was set, it aquires the mutex.
    A executes CONCAT opcode against P18.
        Constant 'bar' as operand.
    Releases the mutex.
    A then clears the in-use flag for $otherstr.

And the sequence of opcodes in B (simplified) is:

    B sets the in-use flag on $otherstr when it loads it into P17.
    If the inuse flag was set, it aquires the mutex.
    B executes the CONCAT opcode for against $otherstr.
        Constant 'foo' as operand.
    Releases the mutex.
    B then clears the in-use flag for $otherstr.

    B then set the in-use flag for $somestr.
    If the inuse flag was set, it aquires the mutex.
    B executes CONCAT opcode against P18.
        Constant 'bar; as operand.
    Releases the mutex.
    B then clears the in-use flag for $somestr.

The deadlock doesn't occur (if I'm right) because however you overlap
those two sequences, only one of the two in-use flags is set at any
given time. Blocking only occurs if the two threads are attempting 
simultaneous operatons on the same PMC. When this occurs, the second
thread blocks until the first completes it's operation, when it 
immediately releases the lock and clears the in-use flag.

Ie. (In this example) Only one in-use flag (per thread) will be set 
at any given time, so possibility for deadlock cannot arise.

If the situation requires a single opcode to manipulate two PMCs, then
other threads will be prevented from accessing either of those PMCs
until the single opcode on the first thread clears both in-use flags.

It may be possible to set up a scenario where, loops of dual PMC, single
opcodes could deadlock. I haven't convinced myself of this one way or the
other. But notionally, opcodes with dual PMC operands should be fairly
rare if at all. Mostly, perl-level statements which involve multiple PMCs
will resolve down to sequences of opcodes that involve a single PMC and
intermediate results from previous opcodes held in non-PMC registers.

NOTE: That last paragraph is *highly* speculative on my part. It's how 
I think it should work. Not how it does or should. 


 LP> Luke

Does it work? If it does, can it be implemented, cross-platform, within
the Dan's constraints? I do not know the answer to this. I'm trying to
work that out now. I would have preferred to have had categorical answers
before bringing it here, but time ran out and my knowledge of Parrot and
other platforms lets me down.

Cheers, Nigel.



-------- End of forwarded message --------



Reply via email to