Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2007-03-22 20:33:06


Anthony Williams wrote:
> "Peter Dimov" <pdimov_at_[hidden]> writes:
>
>> I don't see call_once in jss_thread.zip, by the way; maybe you
>> forgot to put it into the archive?
>
> Oops. Thanks for spotting that. I've added it to the archive, and
> updated it to take multiple arguments in passing.

Some comments on that:

    template<typename Function>
    void call_once(once_flag& flag,Function f)
    {
        // Try for a quick win: if the proceedure has already been called
        // just skip through:
        long const function_complete_flag_value=0xc15730e2;

        if(::jss::detail::interlocked_read(&flag)!=function_complete_flag_value)
        {
            char mutex_name[::jss::detail::once_mutex_name_length];
            void* const
mutex_handle(::jss::detail::create_once_mutex(mutex_name,&flag));
            BOOST_ASSERT(mutex_handle);
            detail::win32::handle_holder const closer(mutex_handle);
            detail::win32_mutex_scoped_lock const lock(mutex_handle);

            if(::jss::detail::interlocked_read(&flag)!=function_complete_flag_value)
            {
                f();
                JSS_INTERLOCKED_EXCHANGE(&flag,function_complete_flag_value);
            }
        }
    }

The first load needs to be a load_acquire; the second can be ordinary since
it's done under a lock. The store needs to be store_release.

An interlocked_read is stronger ('ordered') and more expensive than needed
on a hardware level, but is 'relaxed' on a compiler level under MSVC 7.1
(the optimizer moves code around it). It's 'ordered' for the compiler as
well under 8.0; the intrinsics have been changed to be compiler barriers as
well. InterlockedExchange is similar.

A load_acquire can be implemented as a volatile read under 8.0, and a
volatile read followed by _ReadWriteBarrier under 7.1.


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