Boost logo

Boost :

From: Mac Murrett (mmurrett_at_[hidden])
Date: 2001-11-18 00:03:31


So long as there is already a dependency upon some kind of Boost threading
library (BOOST_HAS_THREADS), why not use Boost.Threads? Doing this would
give us a poor-man's version for any platform (using similar logic to that
of the POSIX implementation), which we could then specialize for other
platforms as is advantageous (e.g., your Windows implementation or a Mac OS
implementation using AddAtomic).

Also, should the implementation of this not be part of Boost.Threads? It
would seem to me that implementing this would be part of porting
Boost.Threads to a new platform, and so it belongs there.

Mac.

On 11/17/01 10:18 AM, "Peter Dimov" <pdimov_at_[hidden]> wrote:

> In order to make shared_ptr thread safe (w.r.t. reference counting) we need
> an atomic_counter type, with the following operations defined:
>
> atomic_counter a(n); // n is the initial value, convertible to 'long'
> ++a; // atomic increment, returns the new value (by value, type 'long')
> --a; // atomic decrement, returns the new value (by value, type 'long')
> a; // convertible to long, atomic read (to support use_count() and unique())
>
> See below for a proposed implementation.
>
> Comments are welcome.
>
> --
> Peter Dimov
> Multi Media Ltd.
>
> // boost/detail/atomic_counter.hpp
>
> #ifndef BOOST_DETAIL_ATOMIC_COUNTER_HPP_INCLUDED
> #define BOOST_DETAIL_ATOMIC_COUNTER_HPP_INCLUDED
>
> #if _MSC_VER+0 >= 1020
> #pragma once
> #endif
>
> #include <boost/config.hpp>
>
> namespace boost
> {
>
> namespace detail
> {
>
> #ifndef BOOST_HAS_THREADS
>
> typedef long atomic_counter;
>
> #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
>
> namespace win32
> {
> extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement(long
> *);
> extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement(long
> *);
> }
>
> class atomic_counter
> {
> public:
>
> explicit atomic_counter(long v): value_(v)
> {
> }
>
> long operator++()
> {
> return win32::InterlockedIncrement(&value_);
> }
>
> long operator--()
> {
> return win32::InterlockedDecrement(&value_);
> }
>
> operator long() const
> {
> return value_;
> }
>
> private:
>
> long value_;
> };
>
> #elif defined(BOOST_HAS_PTHREADS)
>
> } // namespace detail
>
> } // namespace boost
>
> #include <pthread.h>
>
> namespace boost
> {
>
> namespace detail
> {
>
> class atomic_counter
> {
> private:
>
> class scoped_lock
> {
> public:
>
> scoped_lock(pthread_mutex_t & m): m_(m)
> {
> pthread_mutex_lock(&m_);
> }
>
> ~scoped_lock()
> {
> pthread_mutex_unlock(&m_);
> }
>
> private:
>
> pthread_mutex_t & m_;
> };
>
> public:
>
> explicit atomic_counter(long v): value_(v)
> {
> pthread_mutex_init(&mutex_, 0);
> }
>
> ~atomic_counter()
> {
> pthread_mutex_destroy(&mutex_);
> }
>
> long operator++()
> {
> scoped_lock lock(mutex_);
> return ++value_;
> }
>
> long operator--()
> {
> scoped_lock lock(mutex_);
> return --value_;
> }
>
> operator long() const
> {
> scoped_lock lock(mutex_);
> return value_;
> }
>
> private:
>
> mutable pthread_mutex_t mutex_;
> long value_;
> };
>
> #endif
>
> } // namespace detail
>
> } // namespace boost
>
> #endif // #ifndef BOOST_DETAIL_ATOMIC_COUNTER_HPP_INCLUDED
>
> // user code
>
> #include <iostream>
>
> int main()
> {
> boost::detail::atomic_counter a(1);
>
> std::cout << "++a: " << ++a << '\n';
> std::cout << "--a: " << --a << '\n';
> std::cout << "a == 1: " << (a == 1) << '\n';
> std::cout << "sizeof(boost::detail::atomic_counter): " <<
> sizeof(boost::detail::atomic_counter) << '\n';
> }
>
>
>
> Info: http://www.boost.org Unsubscribe:
> <mailto:boost-unsubscribe_at_[hidden]>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>


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