Boost logo

Boost :

From: williamkempf_at_[hidden]
Date: 2001-05-23 08:38:12


--- In boost_at_y..., Beman Dawes <bdawes_at_a...> wrote:
> At 05:52 PM 5/22/2001, williamkempf_at_h... wrote:
>
> >--- In boost_at_y..., Beman Dawes <bdawes_at_a...> wrote:
> >> The whole thing with atomic_t might be a red herring. It may
well
> >be that
> >> thread_safe_int_least32_t needs a full set of integer
operations.
> >So even
> >> if sizeof(int)==32, it can't just be a typedef for atomic_t.
> >
> >I just realized what you're saying here. I don't think there's
any
> >way to natively give a full set of integer operations to a type
with
> >out using a mutex.
>
> That's what I mean about atomic_t being a red herring. Forget
about
> it. There is nothing wrong with a mutex.

No, but there is something wrong with a mutex being used at this
granularity.

> Think about needs for counters of various totals to be reported by
several
> worker threads. Each thread would keep its own local totals (so
they could
> be updated efficiently without locking), but then just before
closing down
> would update the shared thread_safe_int_least32_t program totals.
No
> particular efficiency issue there, just safety.

That's simple addition, not a full range of integral operations, so
it's not much of an example of the need for a full
thread_safe_int_least32_t. This particular example would best be
served by "traditional" synchronization, i.e. you'd roll the
synchronization yourself. Why? Well, it's just to simple of an
example to be worth addressing in a library. For instance, it's
quite possible that there will be multiple such totals that need to
be updated and it would be better to use a single mutex for all of
them then to use a mutex per total as would be done by a library
solution.

> Now of course there could be an application mutex, but why bother?
It just
> opens up the possibility of misuse. A thread_safe_int_least32_t
would wrap
> the functionality up in a nice safe package that would be very hard
to
> misuse. That's what C++ classes are all about.

The reason to bother is to attain the optimal granularity of lock
(and an "application mutex" might not fit that bill either). A
threading library can't predict what level of granularity is optimal
since it's going to depend on the application, so such a type just
isn't appropriate.

Beyond that, there's a severe problem with a
thread_safe_int_least32_t that behaves as an int. The level of
granularity of such a lock can actually lead to errors in usage. For
example:

thread_safe_int_least32_t i = 10;
i = (i + 2) / 2;

The above expression should be executed "atomically" (as in no other
thread can change the value of 'i' while the expression is being
evaluated) but it is not. The internal mutex is only locked during
the call to a single operation, so it's possible for another thread
to interrupt and change the value of 'i' in between the '+' and
the '/'. It can even interrupt before the assignment! This is why
atomic_t has very specific functions that can be called such as inc()
and dec() and doesn't have overloaded operators such as '++' and '--'.

Bill Kempf


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