Merge lp://staging/~gpr/dcplusplus/sync into lp://staging/dcplusplus

Proposed by Gennady Proskurin
Status: Needs review
Proposed branch: lp://staging/~gpr/dcplusplus/sync
Merge into: lp://staging/dcplusplus
Diff against target: 408 lines (+171/-53)
10 files modified
dcpp/Atomic.h (+122/-0)
dcpp/BufferedSocket.cpp (+3/-3)
dcpp/BufferedSocket.h (+5/-1)
dcpp/Client.cpp (+6/-6)
dcpp/Client.h (+14/-6)
dcpp/CriticalSection.h (+7/-27)
dcpp/Pointer.h (+4/-4)
dcpp/Semaphore.h (+5/-2)
dcpp/ShareManager.cpp (+3/-3)
dcpp/ShareManager.h (+2/-1)
To merge this branch: bzr merge lp://staging/~gpr/dcplusplus/sync
Reviewer Review Type Date Requested Status
Jacek Sieka Needs Information
Review via email: mp+32912@code.staging.launchpad.net

Description of the change

+ includes all patches submitted in corresponding bug reports
+ Thread::safeDec/Inc/Exchange functions are replaced by more fine-grained/lightweight/portable implementations

To post a comment you must log in.
Revision history for this message
Jacek Sieka (arnetheduck) wrote :

I'm not quite sure I understand why one of the counters uses interprocess::detail and the other shared_ptr::detail - if we're relying on internals, I'd minimise their use.

Also, I do not understand the comment on weak vs strong ordering, could you elaborate please.

Regarding fastcriticalsection, it's a spin lock which is quite appropriate if the sections locked are (very) short (small risk of contention) as OS mutexes add a lot of overhead...

review: Needs Information
Revision history for this message
Gennady Proskurin (gpr) wrote :

About weak/strong ordering, much information is available in internet, for example:
http://en.wikipedia.org/wiki/Memory_ordering
http://en.wikipedia.org/wiki/Memory_barrier
http://msdn.microsoft.com/en-us/library/ms686355(VS.85).aspx

In short, "strong" ordering garantees that all threads in all processors see identical synchronized view of memory, because synchronization primitives (mutex in case of FastCriticalSection in Atomic<strong>) do all necessary memory barriers (synchronization of memory between all processors).

In "weak" ordering (which is used for thread-safe counters in my code), you cannot do any action, based on counter's value. For example, you cannot write code like "if (counter==0) do_some_multithread_action()" because only counter value is synchronized (during atomic access to it), and other memory content may be stale. This is suitable for accounting of some statistics for example.

For smart pointer counters, it is necessary to synchronize memory only in case when counter reaches zero, when destructor is called. This is exactly what shared_ptr counters do. So I used shared_ptr/atomic for intrusive_ptr refcount, which was designed exactly for this purpose - thread-safe refcounting in smart pointers.

But shared_ptr/atomic does not have assignment semantics, only construction. So for Atomic<weak> I used another atomic from boost - interprocess::detail. My Atomic template was designed to be general-purpose thread-safe counter, so it should have assignment.

Revision history for this message
Gennady Proskurin (gpr) wrote :

My motivation for writing all this patches (besides bug in using pthread_cond) was bad (coarse) locking for unix. It uses one static mutex in Thread class for almost all synchronization in the whole code.

While I agree that spinning is suitable for FastCriticalSection, it's not easy to implement it properly and effective. At first glance, current implementation may be subject to priority inversion, and therefore, deadlocks.

I'm not sure, what solution will be acceptable for both unix and windows. For intrusive_ptr, I'd just use boost shared_ptr/atomic (as in my patch). For critical sections, I think correctness is priority, and then optimization. And portability is also good.

Unmerged revisions

2216. By Gennady Proskurin

Change BufferedSocket::sockets to Atomic (strong variant).

2215. By Gennady Proskurin

Use Atomic<bool> for "refreshing" variable.

2214. By Gennady Proskurin

Implement Atomic template for atomic counters.

2213. By Gennady Proskurin

Portable FastCriticalSection implementation.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
The diff is not available at this time. You can reload the page or download it.

Subscribers

People subscribed via source and target branches

to status/vote changes: