Boost logo

Boost :

From: äÍÉÔÒÉÊ ÷ØÀËÏ× (dvyukov_at_[hidden])
Date: 2007-04-17 13:49:28


Is sp_counted_base and atomic_count thread-safe?

There code like this (sketchy version):

class shared_count
{
public:
    shared_count()
        : count_(1)
    {}

    void inc()
    {
        InterlockedIncrement(&count_);
    }

    long dec()
    {
        return InterlockedDecrement(&count_);
    }

private:
    long volatile count_;
};

Code like this can be found in
detail/sp_counted_base_gcc_ia64.hpp
detail/atomic_count_gcc.hpp
etc.

I want to point to next moment: there is no memory barrier before/after
initial store to variable count_

Let's consider example:
thread1 creates instance of shared_count and uses some lock-free method to
pass pointer to the instance to thread2
notice: thread1 issues _no_ memory barriers
thread2 executes inc() and dec() methods
if memory under the instance resides in the cache of processor executing
thread2 - then thread2 still can see garbage in variable count_

code:

shared_count volatile* sc;

void thread1()
{
    //...
    sc = new shared_count();
    //...
}

void thread2()
{
    //...
    while (!sc) Sleep(1);
    sc->inc();
    if (!sc->dec()) delete sc;
    //...
}

int main()
{
    //...
    start_thread(&thread1);
    start_thread(&thread2);
    //...
}

Can anyone make clear this moment.
On x86 this is certainly not an issue, but on machines with more relaxed
memory model (ia64, sparc or power), in my opinion, this can be an issue...
but I don't sure...
Or here is an example of data dependency - and all machines (except alpha)
will handle this situation correctly?

Dmitriy V'jukov


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