From: Stephen D. <sd...@gm...> - 2005-12-07 11:12:16
|
Ns_ConnRunRequest in op.c does something like: Ns_MutexLock(&ulock); reqPtr =3D Ns_UrlSpecificGet(server, method, url, id); ... Ns_MutexUnlock(&ulock); Ns_UrlSpecificGet in urlspace.c does something like: MkSeq(&seq, server, method, url); Ns_MutexLock(&lock); data =3D JunctionFind(&urlspace, seq, id, 0); Ns_MutexUnlock(&lock); i.e. there's double locking going on. The second lock, in the urlspace code, is under contention by all callers of urlspace (requests, url2file, etc.), and many of these are very common operations. Users of urlspace need to call Ns_UrlSpecificAlloc() in their initialisation code to get a magic ID. This ID partitions the data of each subsystem. But the ID is stored within the 'Trie' and so needs to be protected by the global lock. What if instead the ID was used as in Thread Local Storage? There's an array of slots, where each slot contains a separate Trie, and the ID is an index into this array. Because ID's are allocated at start up and aren't destroyed there need be no locking at run time to locate the appropriate Trie for the caller. The urlspace locking can now be removed because the callers locking perfectly protects the Trie from concurrent access. It would also allow the caller to run lock-free in the case where all urlspace entries are created at start up and only read at run time. Does this make sense? |