Boost logo

Boost :

Subject: Re: [boost] Request for interest in the new Synchro library
From: Dmitry Goncharov (dgoncharov_at_[hidden])
Date: 2009-02-26 04:40:14


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




Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk