Boost logo

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