
Howard Hinnant wrote:
On Jul 7, 2004, at 9:26 AM, Michael Glassford wrote:
However, I don't see any way to avoid re-trying after the write-lock is obtained when promotion fails, and I don't see a way to prevent promotion from failing except for the suggested latent-read-lock / upgradeable-read-lock. I agree that such a lock is a good idea, but it does have the drawback of serializing all upgradeable read locks, which could be quite undesirable in some circumstances.
I've been giving the fail-able read promotion more thought...
The purpose of using read/write locks is presumably to allow concurrent reads. In such a design, concurrent reads are probably expected as the norm, else the cheaper and simpler scoped_lock is likely to be more appropriate. Given that concurrent reads are likely to be a normal occurrence, it follows that a failed read_lock promotion would also be a normal occurrence.
It would be a normal occurrence, but not necessarily because of concurrent reads. It would be easy for promotion from read-lock to write-lock to a) prevent any new read or write locks, b) wait until all current read-locks are released, and then c) obtain the write lock. The only time a promotion request needs to fail is when multiple threads request promotion simultaneously; all but one must fail and relinquish its read lock to prevent deadlock. Other than that, I agree with everything you've said. (Actually, re-reading what you've said below, I think maybe that's actually what you meant anyway).
In the event of a failed read_lock promotion, the typical strategy is to accept that you have to block for write access, and to reread (or recompute) whatever you obtained under the read lock.
Given that the expected norm is fail-block-reread, is there any advantage to this approach? That is, in a design where you expect multiple concurrent read promotions, they have to be serialized no matter what.
True. The only advantage I can see is in cases where you have many readers that have to read in order to see if they need write access, and only few of them ever actually need it. The many checks can happen simultaneously, and the time saved by the concurrency outweighs the cost of the few re-reads. Having said that, I'm not at all tied to that type of scheme. I've thought all along that lock demotion is more important than lock promotion (at least for my typical uses of a read/write lock).
In a design where you expect multiple concurrent read promotions to be rare the upgradable_read_lock, or even the far simpler scoped_lock (in the case concurrent reads are rare) should not incur a performance hit.
The big motivation that I see for the upgradable_read_lock is the scenario linked to by Alexander yesterday:
On Jul 6, 2004, at 5:02 AM, Alexander Terekhov wrote:
Read this thread:
http://groups.google.com/groups?threadm=ijnd7a.3pb.ln%40tux.localdomain (Subject: upgradeable lock)
If you have multiple long read/compute then write threads, there is no other logic that solves the problem other than serialization, no matter how it is coded.
The paragraph that David Butenhof wrote in response to the fail-able read promotion design (which Alexander also quoted here) summed up (and cemented) my thoughts as well.
All this makes sense to me. Again, I like the upgradeable lock agree that the that it's cleaner and easier to use. Mike