|
Boost : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2001-11-17 10:18:06
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'; }
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk