From: Zoran V. <zv...@ar...> - 2006-10-04 18:34:59
|
On 04.10.2006, at 20:00, Stephen Deasey wrote: > On 10/4/06, Zoran Vasiljevic <zv...@ar...> 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... |