Make ++a, where a is an atomic_count, return the new value.

[SVN r52456]
This commit is contained in:
Peter Dimov
2009-04-17 20:24:01 +00:00
parent 0368a37fde
commit 4b4a62513f
7 changed files with 69 additions and 21 deletions

View File

@ -31,13 +31,12 @@
// ++a; // ++a;
// //
// Effects: Atomically increments the value of a // Effects: Atomically increments the value of a
// Returns: nothing // Returns: (long) the new value of a
// //
// --a; // --a;
// //
// Effects: Atomically decrements the value of a // Effects: Atomically decrements the value of a
// Returns: (long) zero if the new value of a is zero, // Returns: (long) the new value of a
// unspecified non-zero value otherwise (usually the new value)
// //
// Important note: when --a returns zero, it must act as a // Important note: when --a returns zero, it must act as a
// read memory barrier (RMB); i.e. the calling thread must // read memory barrier (RMB); i.e. the calling thread must

View File

@ -40,21 +40,21 @@ class atomic_count
{ {
public: public:
explicit atomic_count(long v) : value_(v) {} explicit atomic_count( long v ) : value_( v ) {}
void operator++() long operator++()
{ {
__atomic_add(&value_, 1); return __exchange_and_add( &value_, +1 ) + 1;
} }
long operator--() long operator--()
{ {
return __exchange_and_add(&value_, -1) - 1; return __exchange_and_add( &value_, -1 ) - 1;
} }
operator long() const operator long() const
{ {
return __exchange_and_add(&value_, 0); return __exchange_and_add( &value_, 0 );
} }
private: private:

View File

@ -25,16 +25,9 @@ public:
explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {} explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {}
void operator++() long operator++()
{ {
__asm__ return atomic_exchange_and_add( &value_, +1 ) + 1;
(
"lock\n\t"
"incl %0":
"+m"( value_ ): // output (%0)
: // inputs
"cc" // clobbers
);
} }
long operator--() long operator--()

View File

@ -62,10 +62,10 @@ public:
pthread_mutex_destroy(&mutex_); pthread_mutex_destroy(&mutex_);
} }
void operator++() long operator++()
{ {
scoped_lock lock(mutex_); scoped_lock lock(mutex_);
++value_; return ++value_;
} }
long operator--() long operator--()

View File

@ -31,9 +31,9 @@ public:
explicit atomic_count( long v ) : value_( v ) {} explicit atomic_count( long v ) : value_( v ) {}
void operator++() long operator++()
{ {
__sync_add_and_fetch( &value_, 1 ); return __sync_add_and_fetch( &value_, 1 );
} }
long operator--() long operator--()

View File

@ -58,5 +58,6 @@ import testing ;
[ run sp_recursive_assign2_rv_test.cpp ] [ run sp_recursive_assign2_rv_test.cpp ]
[ run esft_constructor_test.cpp ] [ run esft_constructor_test.cpp ]
[ compile-fail auto_ptr_lv_fail.cpp ] [ compile-fail auto_ptr_lv_fail.cpp ]
[ run atomic_count_test2.cpp ]
; ;
} }

View File

@ -0,0 +1,55 @@
//
// atomic_count_test2.cpp
//
// Copyright 2009 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/detail/atomic_count.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
boost::detail::atomic_count n( 4 );
BOOST_TEST( n == 4 );
BOOST_TEST( ++n == 5 );
BOOST_TEST( ++n == 6 );
BOOST_TEST( n == 6 );
BOOST_TEST( --n == 5 );
BOOST_TEST( --n == 4 );
BOOST_TEST( n == 4 );
boost::detail::atomic_count m( 0 );
BOOST_TEST( m == 0 );
BOOST_TEST( ++m == 1 );
BOOST_TEST( ++m == 2 );
BOOST_TEST( m == 2 );
BOOST_TEST( --m == 1 );
BOOST_TEST( --m == 0 );
BOOST_TEST( m == 0 );
BOOST_TEST( --m == -1 );
BOOST_TEST( --m == -2 );
BOOST_TEST( m == -2 );
BOOST_TEST( ++m == -1 );
BOOST_TEST( ++m == 0 );
BOOST_TEST( m == 0 );
return boost::report_errors();
}