Boost logo

Boost :

From: William E. Kempf (williamkempf_at_[hidden])
Date: 2002-08-08 09:35:19


----- Original Message -----
From: "Andrew J Bromage" <ajb_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Wednesday, August 07, 2002 6:54 PM
Subject: Re: [boost] Enhanced call_once()

> G'day all.
> > Your "once" object is dynamically initialized. It is pretty much the
same as
> > a boost::mutex; there is no reason for it to be more efficient than a
mutex.
>
> The same argument could be made against lightweight mutexes, or atomic
> counters.

I think I get what you mean, though I think you made some poor choices in
comparison here. "Lightweight" mutexes are an optimization, as are atomic
counters. Your "once" object, as pointed out, won't provide any
optimisations. The abstraction might still be appealing, which I think was
your point here, but it still misses the point that it's dynamically
initialized, which is not thread safe.

> On all platforms that I'm aware of, releasing a mutex lock costs at
> least one system call. On many platforms, even obtaining an
> uncontested lock costs a system call. This is a heavyweight
> solution for a lightweight problem: protecting a read of a single flag
> which is only going to be mutated once in its lifetime. I can see
> this causing problems in times of heavy concurrency.

Whoa. Careful there. There's a lot more to once routines then "protecting
a read of a single flag which is only going to be mutated once in its
lifetime". In fact, the flag is an implementation detail, *NOT* the
resource that's being synchronized. What's being synchronized is the call
to the routine, and the important thing is that any thread that attempts to
call this either actually calls the routine if it was the first, or blocks
until the routine has been called and returns. Multiple threads may have to
block if the "flag" isn't set and wait for the routine to finish. That's
one key part of what the DCL does, and why it fails is because memory
modified within this routine may not be visible to the other threads if
they've not acquired a lock (or performed other memory synchronization
calls).

On some platforms it is possible to optimize once routines so that they
perform faster than a mutex solution, so I'm not going to remove the concept
entirely. But the key here is that we still require static initialization
for this to work.

Bill Kempf


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