Request for interest in the new Synchro library

Hi, I would like to know if the Boost community is interested in the Synchro library. Of course there is a lot of work to do, but I think that there is enough material to start a discussion on the approach. I'd appreciate it if people could take a look, test it on their compiler and give me some feedback. The library is available at Boost Sandbox: https://svn.boost.org/svn/boost/sandbox/synchro and Boost Vault: http://www.boostpro.com/vault/index.php?action=downloadfile&filename=synchro.zip&directory=Concurrent%20Programming& that iIncludes every thing on the Sandbox + Html documentation Some examples use Boost.Interthreads also (available on the vault and the sandbox). This library is a compilation of what I have found in the literature not yet present in Boost. My main concern has been to boostify all these ideas in a coherent way. Next follows an overview of the library features: Boost.Synchro provides: * A uniform usage of Boost.Thread and Boost.Interprocess synchronization mechanisms based on lockables(mutexes) concepts and locker(guards) concepts. o lockables traits and lock generators, o lock adapters of the Boost.Thread and Boost.Interprocess lockable models, o locker adapters of the Boost.Thread and Boost.Interprocess lockers models, o complete them with the corresponding models for single-threaded programs: null_mutex and null_condition classes, o locking families, o semaphore, o condition_lockable lock which put together a lock and its associated conditions. * A coherent exception based timed lock approach, * A rich palette of lockers as o strict_locker, nested_strict_locker, o condition_locker, o reverse_locker, nested_reverse_locker, o locking_ptr, on_dereference_locking_ptr, o externally_locked, * A polymorphic lockable hierarchy. * High-level abstractions for handling more complicated synchronization problems, including o monitor for guaranteeing exclusive access to an object, and o a so-called rendezvous mechanism for handling direct communication between objects concurrent_components via ports using an accept-synchronize protocol based on the design of the concurrency library in the Beta language. On going work * array_locker and tuple_locker locker containers. * A complement to the already present in Boost.Thread lock, try_lock free functions: o lock_until, lock_for, try_lock_until, try_lock_for Best regrads, Vicente Juan Botet Escribá

vicente.botet wrote:
Hi,
I would like to know if the Boost community is interested in the Synchro library. Of course there is a lot of work to do, but I think that there is enough material to start a discussion on the approach.
I'd appreciate it if people could take a look, test it on their compiler and give me some feedback.
The library is available at Boost Sandbox: https://svn.boost.org/svn/boost/sandbox/synchro and Boost Vault: http://www.boostpro.com/vault/index.php?action=downloadfile&filename=synchro.zip&directory=Concurrent%20Programming& that iIncludes every thing on the Sandbox + Html documentation Some examples use Boost.Interthreads also (available on the vault and the sandbox).
This library is a compilation of what I have found in the literature not yet present in Boost. My main concern has been to boostify all these ideas in a coherent way. Next follows an overview of the library features:
Boost.Synchro provides:
* A uniform usage of Boost.Thread and Boost.Interprocess synchronization mechanisms based on lockables(mutexes) concepts and locker(guards) concepts. o lockables traits and lock generators, o lock adapters of the Boost.Thread and Boost.Interprocess lockable models, o locker adapters of the Boost.Thread and Boost.Interprocess lockers models, o complete them with the corresponding models for single-threaded programs: null_mutex and null_condition classes, o locking families, o semaphore, o condition_lockable lock which put together a lock and its associated conditions. * A coherent exception based timed lock approach, * A rich palette of lockers as o strict_locker, nested_strict_locker, o condition_locker, o reverse_locker, nested_reverse_locker, o locking_ptr, on_dereference_locking_ptr, o externally_locked, * A polymorphic lockable hierarchy. * High-level abstractions for handling more complicated synchronization problems, including o monitor for guaranteeing exclusive access to an object, and o a so-called rendezvous mechanism for handling direct communication between objects concurrent_components via ports using an accept-synchronize protocol based on the design of the concurrency library in the Beta language.
On going work * array_locker and tuple_locker locker containers. * A complement to the already present in Boost.Thread lock, try_lock free functions: o lock_until, lock_for, try_lock_until, try_lock_for
Best regrads, Vicente Juan Botet Escribá
Hi Vicente, I am interested in a binary semaphore, which is a semaphore with a count 0 or 1 only. No matter how many times it was posted the count doesn't exceed 1. boost.interprocess doc mentions that the semaphore from boost.interprocess can be binary if you initialize it with 1. However, if you post that semaphore twice the count increases twice as well. What type of semaphore are you planning to have in your library? BR, Dmitry

----- Original Message ----- From: "Dmitry Goncharov" <dgoncharov@unison.com> To: <boost@lists.boost.org> Sent: Tuesday, February 17, 2009 10:54 AM Subject: Re: [boost] Request for interest in the new Synchro library
Hi Vicente,
I am interested in a binary semaphore, which is a semaphore with a count 0 or 1 only. No matter how many times it was posted the count doesn't exceed 1. boost.interprocess doc mentions that the semaphore from boost.interprocess can be binary if you initialize it with 1. However, if you post that semaphore twice the count increases twice as well. What type of semaphore are you planning to have in your library?
Hi, currently Synchro provides the same semaphore as Boost.Interprocess (counting semaphores), except that it uses Threads resources on a inter-threads context, and Interprocess resources on a inter-process context. The library could provide binary semaphores (the difference is minimal). Could you talk us about your use case, and why a mutex cannot be used in your context? Let me know if you need other kind of semaphores. Best, Vicente

vicente.botet wrote:
What type of semaphore are you planning to have in your library?
Hi,
currently Synchro provides the same semaphore as Boost.Interprocess (counting semaphores), except that it uses Threads resources on a inter-threads context, and Interprocess resources on a inter-process context.
The library could provide binary semaphores (the difference is minimal).Could you talk us about your use case, and why a mutex cannot be used in your context?
I need to block a thread until either a timeout expires or some other thread wakes this one up. This is really what condition_variable::timed_wait() is for, right? Why can't condition_variable::timed_wait() be used? It can. It has a drawback, though. After the condvar was signaled it has to lock a mutex. This means there is an unbound timeout between the time condvar was signaled and the time condition_variable::timed_wait() returns. A binary_semaphore::timed_wait() can be used for the same purpose. The advantage is it doesn't have to lock a mutex. BR, Dmitry

Dmitry Goncharov wrote:
I need to block a thread until either a timeout expires or some other thread wakes this one up. This is really what condition_variable::timed_wait() is for, right? Why can't condition_variable::timed_wait() be used? It can. It has a drawback, though. After the condvar was signaled it has to lock a mutex. This means there is an unbound timeout between the time condvar was signaled and the time condition_variable::timed_wait() returns. Why is that any more unbounded than any other code that has to happen inside the gubbins of binary_semaphore?
After all, something, somewhere, has to wake up and then test to see whether it was timed out or woken up. Which implies a state variable, which implies a mutex to protect it, which implies you're not winning how you think you are.
A binary_semaphore::timed_wait() can be used for the same purpose. The advantage is it doesn't have to lock a mutex.
I think the advantage is that its actually a portable abstraction, in a way that a condition_variable isn't. James

----- Original Message ----- From: "Dmitry Goncharov" <dgoncharov@unison.com> To: <boost@lists.boost.org> Sent: Thursday, February 19, 2009 8:37 AM Subject: Re: [boost] Request for interest in the new Synchro library
vicente.botet wrote:
What type of semaphore are you planning to have in your library?
Hi,
currently Synchro provides the same semaphore as Boost.Interprocess (counting semaphores), except that it uses Threads resources on a inter-threads context, and Interprocess resources on a inter-process context.
The library could provide binary semaphores (the difference is minimal).Could you talk us about your use case, and why a mutex cannot be used in your context?
I need to block a thread until either a timeout expires or some other thread wakes this one up. This is really what condition_variable::timed_wait() is for, right? Why can't condition_variable::timed_wait() be used? It can. It has a drawback, though. After the condvar was signaled it has to lock a mutex. This means there is an unbound timeout between the time condvar was signaled and the time condition_variable::timed_wait() returns. A binary_semaphore::timed_wait() can be used for the same purpose. The advantage is it doesn't have to lock a mutex.
Hi, the binary_semaphore you describe must poll with test_and_set. I have no such implementation, but as far as a portable test_and_set is available this can be implemented in the library. Waiting for that what do you think of using a mutex as a binary_semaphore: template <typename ScopeTag=multi_threaded_tag> class basic_binary_semaphore { typedef synchronization_family<ScopeTag> Sync; typedef typename Sync::mutex_type lockable_type; lockable_type mtx_; public: BOOST_COPY_CONSTRUCTOR_DELETE(basic_binary_semaphore) /*< disable copy construction >*/ BOOST_COPY_ASSIGNEMENT_DELETE(basic_binary_semaphore) /*< disable copy asignement >*/ inline basic_binary_semaphore() { mtx_.unlock(); }; inline void post() { mtx_.unlock(); } inline void wait() { mtx.lock(); } inline bool try_wait() { return mtx.try_lock(); } inline bool try_wait_until(const system_time &abs_time) { return mtx.try_lock_until(); } template<typename TimeDuration> inline bool try_wait_for(const TimeDuration &rel_time) { return try_wait_until(get_system_time()+rel_time); } inline void wait_until(const system_time &abs_time) { if (!try_wait_until(abs_time)) throw timeout_exception(); } template<typename TimeDuration> inline void wait_for(const TimeDuration &rel_time) { if (!try_wait_until(rel_time)) throw timeout_exception(); } }; Vicente

vicente.botet wrote:
Hi,
the binary_semaphore you describe must poll with test_and_set. I have no such implementation, but as far as a portable test_and_set is available this can be implemented in the library.
Waiting for that what do you think of using a mutex as a binary_semaphore:
template <typename ScopeTag=multi_threaded_tag> class basic_binary_semaphore { typedef synchronization_family<ScopeTag> Sync; typedef typename Sync::mutex_type lockable_type; lockable_type mtx_; public: BOOST_COPY_CONSTRUCTOR_DELETE(basic_binary_semaphore) /*< disable copy construction >*/ BOOST_COPY_ASSIGNEMENT_DELETE(basic_binary_semaphore) /*< disable copy asignement >*/
inline basic_binary_semaphore() { mtx_.unlock(); };
inline void post() { mtx_.unlock(); }
inline void wait() { mtx.lock(); }
inline bool try_wait() { return mtx.try_lock(); }
inline bool try_wait_until(const system_time &abs_time) { return mtx.try_lock_until(); }
template<typename TimeDuration> inline bool try_wait_for(const TimeDuration &rel_time) { return try_wait_until(get_system_time()+rel_time); }
inline void wait_until(const system_time &abs_time) { if (!try_wait_until(abs_time)) throw timeout_exception(); }
template<typename TimeDuration> inline void wait_for(const TimeDuration &rel_time) { if (!try_wait_until(rel_time)) throw timeout_exception(); } };
Vicente
Hi, Unfortunately, the class above is not a semaphore since only the thread which locked the mutex can unlock it. A semaphore can be posted by any thread. What about the following adapter? #ifndef BOOST_BINSEM_HPP #define BOOST_BINSEM_HPP #include <boost/thread.hpp> namespace boost { template <typename Semaphore> class binary_semaphore { public: explicit binary_semaphore(int v) : m_sem(v) {} void wait() { m_sem.wait(); } void post() { // If cannot lock then some other thread is posting. // In this case just return. if (m_mutex.try_lock()) { try { // The result of try_wait() is not important. m_sem.try_wait(); m_sem.post(); } catch (...) { m_mutex.unlock(); throw; } m_mutex.unlock(); } } bool timed_wait(boost::posix_time::ptime const& t) { return m_sem.timed_wait(t); } bool try_wait() { return m_sem.try_wait(); } private: boost::mutex m_mutex; Semaphore m_sem; }; } #endif This adapter makes a binary semaphore out of a regular one. The post() method is not as efficient as it should be. On the other hand the adapter is very simple. There is also a test attached. BR, Dmitry

----- Original Message ----- From: "Dmitry Goncharov" <dgoncharov@unison.com> To: <boost@lists.boost.org> Sent: Thursday, February 26, 2009 10:40 AM Subject: Re: [boost] Request for interest in the new Synchro library
vicente.botet wrote:
Hi,
the binary_semaphore you describe must poll with test_and_set. I have no such implementation, but as far as a portable test_and_set is available this can be implemented in the library.
Waiting for that what do you think of using a mutex as a binary_semaphore: Hi,
Unfortunately, the class above is not a semaphore since only the thread which locked the mutex can unlock it. A semaphore can be posted by any thread.
OOPS! Where I have my head!
What about the following adapter?
#ifndef BOOST_BINSEM_HPP #define BOOST_BINSEM_HPP
#include <boost/thread.hpp>
namespace boost { template <typename Semaphore> class binary_semaphore { public: explicit binary_semaphore(int v) : m_sem(v) {}
void wait() { m_sem.wait(); }
void post() { // If cannot lock then some other thread is posting. // In this case just return. if (m_mutex.try_lock()) { try { // The result of try_wait() is not important. m_sem.try_wait(); m_sem.post(); } catch (...) { m_mutex.unlock(); throw; } m_mutex.unlock(); } }
bool timed_wait(boost::posix_time::ptime const& t) { return m_sem.timed_wait(t); }
bool try_wait() { return m_sem.try_wait(); }
private: boost::mutex m_mutex; Semaphore m_sem; }; }
#endif
This adapter makes a binary semaphore out of a regular one. The post() method is not as efficient as it should be. On the other hand the adapter is very simple. There is also a test attached.
Thanks for the proposal. I have another alternative using inheritance that avoid adding a new mutex. template <typename ScopeTag=multi_threaded_tag> class basic_binary_semaphore: public basic_semaphore<ScopeTag> { public: BOOST_COPY_CONSTRUCTOR_DELETE(basic_binary_semaphore) /*< disable copy construction >*/ BOOST_COPY_ASSIGNEMENT_DELETE(basic_binary_semaphore) /*< disable copy asignement >*/ inline explict basic_binary_semaphore(int initialCount):basic_semaphore<ScopeTag>(initialCount>0?1:0) {}; inline void post() { scoped_lock lock(this->m_mut); if(this->m_count == 0){ this->m_cond.notify_one(); ++(this->m_count); } } }; typedef basic_binary_semaphore<> binary_semaphore; Attached the complete file. What do you think? Thanks, Vicente

vicente.botet wrote:
What about the following adapter?
#ifndef BOOST_BINSEM_HPP #define BOOST_BINSEM_HPP
#include <boost/thread.hpp>
namespace boost { template <typename Semaphore> class binary_semaphore { public: explicit binary_semaphore(int v) : m_sem(v) {}
void wait() { m_sem.wait(); }
void post() { // If cannot lock then some other thread is posting. // In this case just return. if (m_mutex.try_lock()) { try { // The result of try_wait() is not important. m_sem.try_wait(); m_sem.post(); } catch (...) { m_mutex.unlock(); throw; } m_mutex.unlock(); } }
bool timed_wait(boost::posix_time::ptime const& t) { return m_sem.timed_wait(t); }
bool try_wait() { return m_sem.try_wait(); }
private: boost::mutex m_mutex; Semaphore m_sem; }; }
#endif
This adapter makes a binary semaphore out of a regular one. The post() method is not as efficient as it should be. On the other hand the adapter is very simple. There is also a test attached.
Thanks for the proposal. I have another alternative using inheritance that avoid adding a new mutex.
template <typename ScopeTag=multi_threaded_tag> class basic_binary_semaphore: public basic_semaphore<ScopeTag> { public: BOOST_COPY_CONSTRUCTOR_DELETE(basic_binary_semaphore) /*< disable copy construction >*/ BOOST_COPY_ASSIGNEMENT_DELETE(basic_binary_semaphore) /*< disable copy asignement >*/
inline explict basic_binary_semaphore(int initialCount):basic_semaphore<ScopeTag>(initialCount>0?1:0) {};
inline void post() { scoped_lock lock(this->m_mut); if(this->m_count == 0){ this->m_cond.notify_one(); ++(this->m_count); } } }; typedef basic_binary_semaphore<> binary_semaphore;
Attached the complete file. What do you think?
Thanks, Vicente
Could not find basic_semaphore in boost. Is it one from your Synchro library? Locking a mutex inside post() is inefficient. If one thread has the mutex locked then there is no need to wait until the mutex is unlocked. Use try_lock() and return if cannot lock. In one of the previous posts i described why a binary_semaphore::timed_wait() was superior in my case than condition_variable::timed_wait(). Using a condition variable defeats the purpose of a binary_semaphore (at least in my usage scenario). BR, Dmitry

----- Original Message ----- From: "Dmitry Goncharov" <dgoncharov@unison.com> To: <boost@lists.boost.org> Sent: Wednesday, March 04, 2009 10:06 AM Subject: Re: [boost] Request for interest in the new Synchro library
vicente.botet wrote:
What about the following adapter?
#ifndef BOOST_BINSEM_HPP #define BOOST_BINSEM_HPP
#include <boost/thread.hpp>
namespace boost { template <typename Semaphore> class binary_semaphore { public: explicit binary_semaphore(int v) : m_sem(v) {}
void wait() { m_sem.wait(); }
void post() { // If cannot lock then some other thread is posting. // In this case just return. if (m_mutex.try_lock()) { try { // The result of try_wait() is not important. m_sem.try_wait(); m_sem.post(); } catch (...) { m_mutex.unlock(); throw; } m_mutex.unlock(); } }
bool timed_wait(boost::posix_time::ptime const& t) { return m_sem.timed_wait(t); }
bool try_wait() { return m_sem.try_wait(); }
private: boost::mutex m_mutex; Semaphore m_sem; }; }
#endif
This adapter makes a binary semaphore out of a regular one. The post() method is not as efficient as it should be. On the other hand the adapter is very simple. There is also a test attached.
Thanks for the proposal. I have another alternative using inheritance that avoid adding a new mutex.
template <typename ScopeTag=multi_threaded_tag> class basic_binary_semaphore: public basic_semaphore<ScopeTag> { public: BOOST_COPY_CONSTRUCTOR_DELETE(basic_binary_semaphore) /*< disable copy construction >*/ BOOST_COPY_ASSIGNEMENT_DELETE(basic_binary_semaphore) /*< disable copy asignement >*/
inline explict basic_binary_semaphore(int initialCount):basic_semaphore<ScopeTag>(initialCount>0?1:0) {};
inline void post() { scoped_lock lock(this->m_mut); if(this->m_count == 0){ this->m_cond.notify_one(); ++(this->m_count); } } }; typedef basic_binary_semaphore<> binary_semaphore;
Attached the complete file. What do you think?
Thanks, Vicente
Could not find basic_semaphore in boost. Is it one from your Synchro library?
Yes. And I use the fields of the base semaphore. I though that you has taken a look, but ... :(
Locking a mutex inside post() is inefficient. If one thread has the mutex locked then there is no need to wait until the mutex is unlocked. Use try_lock() and return if cannot lock.
I could a a try_post with this semantics. BUt what the user will do if fails? I'll re-post your implementation here
namespace boost { template <typename Semaphore> class binary_semaphore { public: explicit binary_semaphore(int v) : m_sem(v) {}
void wait() { m_sem.wait(); }
void post() { // If cannot lock then some other thread is posting. // In this case just return. if (m_mutex.try_lock()) { try { // The result of try_wait() is not important. m_sem.try_wait(); m_sem.post(); } catch (...) { m_mutex.unlock(); throw; } m_mutex.unlock(); } }
bool timed_wait(boost::posix_time::ptime const& t) { return m_sem.timed_wait(t); }
bool try_wait() { return m_sem.try_wait(); }
private: boost::mutex m_mutex; Semaphore m_sem; };
You implementation has some deficiencies. It add another mutex to the semaphore. My implementation do not add nothing more. Just controls that second posts are ignored as you have requested. Yours add some try_locks and at the end call m_sem.post(); which do the following in my implementation template <typename ScopeTag> inline void basic_semaphore<ScopeTag>::post() { scoped_lock lock(m_mut); if(m_count == 0){ m_cond.notify_one(); } ++m_count; } So you will lock in any case.
In one of the previous posts i described why a binary_semaphore::timed_wait() was superior in my case than condition_variable::timed_wait(). Using a condition variable defeats the purpose of a binary_semaphore (at least in my usage scenario).
Well all depends, on how the Semaphore::timed_wait is implemented.
bool timed_wait(boost::posix_time::ptime const& t) { return m_sem.timed_wait(t); }
In my case it inherits from the basic_semaphore<>::timed_wait. So in both cases yours::binary_semaphore<mine::basic_semaphore<multi_threaded_tag> > will even lock more than mine::basic_binary_semaphore<multi_threaded_tag> > Maybe your binary_semaphore class works better with Semaphore classes that do not use conditions. But do you have such a portable Semaphore class? If you have I'm interested also. Best, Vicente Vicente

You implementation has some deficiencies. It add another mutex to the semaphore. Yes. I dont like it. A good implementation should be as efficient as
My implementation do not add nothing more. Just controls that second posts are ignored as you have requested. They are not just ignored, since if some thread has a mutex locked other
vicente.botet wrote: posix's syscalls. Unfortunately, i can't figure out how to make one for unix. threads that invoke post() are blocked. try_lock() lets other threads keep running. In fact, sem.post() cannot block. Posting a semaphore is a non-blocking operation. It is even async-signal safe. If semphore::post() locks a mutex it is no longer non-blocking. IMO, synchro::basic_semaphore::post() should not lock a mutex as well. You could use a pipe to implement semaphore with non-blocking post(). Please, find a link to one implementation below.
In one of the previous posts i described why a binary_semaphore::timed_wait() was superior in my case than condition_variable::timed_wait(). Using a condition variable defeats the purpose of a binary_semaphore (at least in my usage scenario).
Well all depends, on how the Semaphore::timed_wait is implemented.
Exactly. It should be just a call to sem_timedwait() on posix. Other implementations are possible. Anyway, on posix any proper implementation of semaphore::timed_wait() should be more efficient than condition_variable::timed_wait(), because condition_variable::timed_wait() has to lock a mutex in order to return.
In my case it inherits from the basic_semaphore<>::timed_wait.
So in both cases
yours::binary_semaphore<mine::basic_semaphore<multi_threaded_tag> > will even lock more than
mine::basic_binary_semaphore<multi_threaded_tag> >
Maybe your binary_semaphore class works better with Semaphore classes that do not use conditions. But do you have such a portable Semaphore class
No, i dont. I just used semaphore from boost::interprocess, since it is the only currently available in boost. The posix implementation of boost interprocess semaphore uses sem_timedwait().
If you have I'm interested also.
You can find one unix implementation here http://www.kohala.com/start/unpv22e/unpv22e.tar.gz. This archive has an implementation of semaphore, not binary_semaphore. In order to make binary_semaphore the size of the pipe has to be restricted to 1 byte. It is possible to restrict the size of a pipe on windows. I dont know how to restrict the size of a pipe on unix (besides recompiling the kernel). BR, Dmitry

----- Original Message ----- From: "Dmitry Goncharov" <dgoncharov@unison.com> To: <boost@lists.boost.org> Sent: Wednesday, March 04, 2009 3:03 PM Subject: Re: [boost] Request for interest in the new Synchro library
You implementation has some deficiencies. It add another mutex to the semaphore. Yes. I dont like it. A good implementation should be as efficient as
vicente.botet wrote: posix's syscalls. Unfortunately, i can't figure out how to make one for unix.
My implementation do not add nothing more. Just controls that second posts are ignored as you have requested. They are not just ignored, since if some thread has a mutex locked other threads that invoke post() are blocked. try_lock() lets other threads keep running. In fact, sem.post() cannot block. Posting a semaphore is a non-blocking operation. It is even async-signal safe. If semphore::post() locks a mutex it is no longer non-blocking. IMO, synchro::basic_semaphore::post() should not lock a mutex as well. You could use a pipe to implement semaphore with non-blocking post(). Please, find a link to one implementation below.
In one of the previous posts i described why a binary_semaphore::timed_wait() was superior in my case than condition_variable::timed_wait(). Using a condition variable defeats the purpose of a binary_semaphore (at least in my usage scenario).
Well all depends, on how the Semaphore::timed_wait is implemented.
Exactly. It should be just a call to sem_timedwait() on posix. Other implementations are possible. Anyway, on posix any proper implementation of semaphore::timed_wait() should be more efficient than condition_variable::timed_wait(), because condition_variable::timed_wait() has to lock a mutex in order to return.
I can use the sem_ family functions where available. But we need a implementation on the other platforms.
In my case it inherits from the basic_semaphore<>::timed_wait.
So in both cases
yours::binary_semaphore<mine::basic_semaphore<multi_threaded_tag> > will even lock more than
mine::basic_binary_semaphore<multi_threaded_tag> >
Maybe your binary_semaphore class works better with Semaphore classes that do not use conditions. But do you have such a portable Semaphore class No, i dont. I just used semaphore from boost::interprocess, since it is the only currently available in boost. The posix implementation of boost interprocess semaphore uses sem_timedwait(). If you have I'm interested also.
I was not aware Boost.Interprocess do that already. I will have a look.
You can find one unix implementation here http://www.kohala.com/start/unpv22e/unpv22e.tar.gz. This archive has an implementation of semaphore, not binary_semaphore. In order to make binary_semaphore the size of the pipe has to be restricted to 1 byte. It is possible to restrict the size of a pipe on windows. I dont know how to restrict the size of a pipe on unix (besides recompiling the kernel).
Thanks for the link. Vicente

vicente.botet wrote:
Well all depends, on how the Semaphore::timed_wait is implemented.
Exactly. It should be just a call to sem_timedwait() on posix. Other implementations are possible. Anyway, on posix any proper implementation of semaphore::timed_wait() should be more efficient than condition_variable::timed_wait(), because condition_variable::timed_wait() has to lock a mutex in order to return.
I can use the sem_ family functions where available. That is, probably, the most correct solution.
But we need a implementation on the other platforms.
Other platforms should have some implementation of semaphore. On windows there's CreateSemaphore(), etc. For some platform which doesn't have semaphores it is possible to implement one using a pipe. BR, Dmitry
participants (3)
-
Dmitry Goncharov
-
James Mansion
-
vicente.botet