
Jody Hagins wrote:
On Thu, 29 Dec 2005 20:57:38 +0200 "Peter Dimov" <pdimov@mmltd.net> wrote:
... this is not quite correct if you are on a platform where shared_ptr uses atomic operations; let's assume for the sake of argument that this is not the case. The alternative is obviously to supply another version of shared_ptr, one that isn't MT-safe. Interoperability issues aside, this would be OK for most people as long as their ST shared pointers never cross threads, but it won't solve the problem that you describe unless ALL libraries that use shared_ptr ALSO supply two variants of their classes or APIs.
Right. ACE uses sunchromization policies, which solves the payment problem, but it does mean that other classes either need to specify their use, or also allow the synch policy in their interface.
Right, and this can be a problem if shared_ptr is used only as an implementation detail; implementation details shouldn't affect the interface.
This is a maintenance problem that most people would rather avoid; it is not a coincidence that compiler vendors are moving away from ST/MT libraries and towards a single MT-safe library. The resources that are freed by dropping the ST variant are used to improve the performance of the MT library to a competitive level.
I can certainly understand that. However, MT-safe is different than what I'm talking about. Some stuff is MT-safe without synchronization primitives.
shared_ptr on x86/PPC, for example.
For this library, it even goes beyond that, I'm afraid. The demuxer::run() method always acquires/releases a mutex for each operation.
... and this is a problem because..?
Because every time through the loop, you pay for the synchronization, when it is not needed. The only reason for its existence is so that multiple threads can call demuxer::run() at the same time. Aside from implementation questions brought up earlier about calling os demux hooks from multiple threads, this is extremely undesirable in the more common case where a single thread calls run().
Maybe I'm not being very clear, or maybe you don't think it is bad to uselessly call to synchronization primitives.
Specific undesirable effects (such as reduced performance) can be bad. Synchronization, by itself, is not. It's merely a way (not the only way) to implement the documented thread safety guarantee of ::run. (One example of a specific undesirable effect that springs to mind is the possibility of deadlock if a callback invokes ::run.)
From a cursory look at epoll_reactor, I'd think that the costs of the lock are negligible for the ST case (barring a pathologically inefficient mutex implementation) since the critical regions are fairly expensive.