lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



On 10 Oct 2006, at 11:32, Mike Pall wrote:

Hi,

David Jones wrote:
I don't see how lua_sethook is safe when used in two different threads.

It's safe for the intended purpose. It's a timeout. You just want
the hook to be called as soon as possible. It doesn't matter
whether it's called before the next bytecode or the one after it.

L->hook and L->base are modified in dependent ways, for example, and
no attempt is made to synchronise the updates.  What if one is using
an architecture with relaxed memory order?

[L->base ist not modified. Maybe you mean L->basehookcount.]

I meant L->hookmask actually (!). Sorry about the unintended misdirection.


Any intermediate state caused by reordering of updates to the
memory fields in question is still safe. And only the final state
will cause a call to the hook. The code has been written with
great care (luaV_execute, traceexec, luaD_callhook).

This assumes that updates to each of hookmask and hook will take place atomically. There's no guarantee of that. On some architectures an update of hook may consist of two writes (to two halves of a 64-bit quantity say) and a re-ordered write to hookmask may appear in between them.

I can see that the code has been written with great care, but that doesn't make it correct.


It's basically an 'AND' function. You can flip the inputs (here:
individual memory words) from off to on in any order. It triggers
only when all changes have percolated.

"if (hook)" is actually an OR function. If _any_ of the constituent memory elements (bits, bytes, words) that comprise the memory occupied by "hook" are non-zero then it passes the test. That's bad.


I'm pretty sure that lua_sethook isn't safe when used in a signal
handler either.

It's the same native thread, so memory ordering is not an issue.
Calling the hook setter asynchronously is safe. The worst case is
that the caller is interrupted during the 1st phase of the hook
check. This either means the check succeeds (with all fields set)
or fails (and succeeds the next time). No problem here either.

No, it's worse when L->hook is not atomically updatable.

drj