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 --------