On 04.10.2006, at 20:00, Stephen Deasey wrote:

On 10/4/06, Zoran Vasiljevic <[EMAIL PROTECTED]> wrote:

On 04.10.2006, at 18:44, Stephen Deasey wrote:


OK. I can accept that. Still, you put this into frequently
called procedure and there you go (literals are freed AFAIK,
when procedure scope is exited): again you have global locking.


I'm not sure what you're saying here. What is freed, and when?


The literal object "themutex" is gone after procedure exits
AFAIK. This MIGHT need to be double-checked though as I'm
not 100% sure if the literals get garbage collected at that
point OR at interp teardown.


If that were true then my scheme would be useless. But I don't think
it is. I added a log line to GetArgs in nsd/tclthread.c:

        if (Ns_TclGetOpaqueFromObj(objv[2], type, &addr) != TCL_OK
&& Ns_TclGetAddrFromObj(interp, objv[2], type, &addr) ! = TCL_OK) {

            Ns_Log(Warning, "tclthread.c:GetArgs: objv[2] not an
address object. Looking up in hash table...");

            Tcl_ResetResult(interp);
            Ns_MasterLock();
            ...


i.e. if the 'name' of the thread primitive given to the command does
not already contain a pointer to the underlying object, and it can not
be converted to one by deserialising a pointer address, then take the
global lock and look the name up in the hash table. Log this case.


    % proc lockunlock args {ns_mutex lock m; ns_mutex unlock m}
    % lockunlock
[04/Oct/2006:18:39:25][8985.3086293920][- thread-1208673376-] Warning:
        tclthread.c:GetArgs: objv[2] not an address object. Looking up
in hash table...
    % lockunlock
    % lockunlock



Hmhmhmhmhm.... look what I get after doing this change in tclthread.c
(exactly the same spot):


        if (Ns_TclGetOpaqueFromObj(objv[2], type, &addr) != TCL_OK
&& Ns_TclGetAddrFromObj(interp, objv[2], type, &addr) != TCL_OK) {
Ns_Log(2, "MISS THE OBJ CACHE : %p", objv[2]);
            Tcl_ResetResult(interp);
            Ns_MasterLock();


I do following from the nscp line:

server1:nscp 9> proc lu count {ns_log notice LOCK.$count; ns_mutex lock m; ns_mutex unlock m; ns_log notice UNLOCK.$count}
server1:nscp 11> lu 1
server1:nscp 12> lu 2
server1:nscp 13> lu 3

and this is what comes in the log:

[04/Oct/2006:20:25:22][3026.41967104][-nscp:3-] Notice: LOCK.1
[04/Oct/2006:20:25:22][3026.41967104][-nscp:3-] Error: MISS THE OBJ CACHE : 0x2f4ff8 [04/Oct/2006:20:25:22][3026.41967104][-nscp:3-] Error: MISS THE OBJ CACHE : 0x2f4ff8
[04/Oct/2006:20:25:22][3026.41967104][-nscp:3-] Notice: UNLOCK.1
[04/Oct/2006:20:25:24][3026.41967104][-nscp:3-] Notice: LOCK.2
[04/Oct/2006:20:25:24][3026.41967104][-nscp:3-] Error: MISS THE OBJ CACHE : 0x2f4ff8 [04/Oct/2006:20:25:24][3026.41967104][-nscp:3-] Error: MISS THE OBJ CACHE : 0x2f4ff8
[04/Oct/2006:20:25:24][3026.41967104][-nscp:3-] Notice: UNLOCK.2
[04/Oct/2006:20:25:27][3026.41967104][-nscp:3-] Notice: LOCK.3
[04/Oct/2006:20:25:27][3026.41967104][-nscp:3-] Error: MISS THE OBJ CACHE : 0x2f4ff8 [04/Oct/2006:20:25:27][3026.41967104][-nscp:3-] Error: MISS THE OBJ CACHE : 0x2f4ff8
[04/Oct/2006:20:25:27][3026.41967104][-nscp:3-] Notice: UNLOCK.3

So, what now?




The first time the proc is run it is compiled and the name is indeed
looked up in the hash of mutex names. And that is of course 'slow'
because there's a lock around the hash table.

But that is the *only* time this happens. On the second and third
attempt, no locking or look up!

What's interesting from the above is that there is only a single log
line, but there are two literal "m" objects.  Apparently Tcl is doing
some optimising behind the scenes...


I  believe quite opposit is happening. The literal "m" gets lost
and so its saved address.



Right. But it won't shimmer away, because it is a literal name and you
have no need to manipulate it in any way that would cause it to
shimmer, such as putting it in an nsv array.

Now, I'm not sure what you're getting at with the "junklock" business.
If you mean the user could have a typo in their code and an extra lock
will be created behind their back, well, that's the nature of Tcl.
Same goes for variables, right?

Although you could define ns_mutex create to take a name and force
people to use this in their initialisation code, and then in calls to
lock and unlock you wouldn't create on demand, you'd just do the look
up (first time only!), and throw an error if the name doesn't exist.

But maybe I'm missing your point here...

Yes. You miss the point. The "junkmutex" is  just yet another
name. No real "junk" was ment here.



OTOH, when I say

   set mutexhandle [ns_mutex create]

I can do whatever I want with mutexhandle, it will always point to
that damn mutex. I need not do some other lookup in addition.
I can put it into nsv, transfer it over network back to myself...


It's not that you *can* put it into an nsv array, it's that you *have*
to, because how else are you going to communicate the serialised
pointer which is a mutex handle?

No way. I have to put it there. You need not necessarily
put the mutex name there as it is "known". This is true.


And you *have* to do it because what good is a mutex without more than
one thread?

Correct.


And if you have more than one thread you have more than one interp,
each with it's own global namesapce. So how do you refer to a single
mutex from within each interp?

Using the handle I put in the nsv, how else?



Thats what I mean by removing the handle from users. If you
do that you need to do more, introduce more locks etc.
Nothing is for free...


It is in fact more or less free. Compiling the Tcl source to byte code
incurs a lock around the mutex hash table. It is a compile time
expense. At run time there is no locking.

Hmhmhm... not really and not always. First we have to understand
why do I get those misses of the cache...


nsv arrays *also* incur locking. Plus you have the effort of having to
cache the mutex in a thread local variable, or else you incur the nsv
locking cost each time.

Right. But finer grade locking, not the global lock.
Instead, the nsv bucket is locked.


So I think this is in fact a case of a free lunch!

There is no such thing as free lunch. This is not a
theorem, this is an axiom.


As far as I can see, the only thing that will make this not true, is
some real-world, non-contrived case where the mutex name has to
shimmer.

See above...




Reply via email to