// -*- C++ -*- // $Id: Atomic_Op.i,v 1.1.1.2.2.1 2002/01/09 20:40:46 michel_j Exp $ template ACE_INLINE TYPE ACE_Atomic_Op::operator++ (void) { // ACE_TRACE ("ACE_Atomic_Op::operator++"); ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_); return ++this->value_; } template ACE_INLINE TYPE ACE_Atomic_Op::operator+= (const TYPE &i) { // ACE_TRACE ("ACE_Atomic_Op::operator+="); ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_); return this->value_ += i; } template ACE_INLINE TYPE ACE_Atomic_Op::operator-- (void) { // ACE_TRACE ("ACE_Atomic_Op::operator--"); ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_); return --this->value_; } template ACE_INLINE TYPE ACE_Atomic_Op::operator-= (const TYPE &i) { // ACE_TRACE ("ACE_Atomic_Op::operator-="); ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_); return this->value_ -= i; } template ACE_INLINE ACE_Atomic_Op::ACE_Atomic_Op (const ACE_Atomic_Op &rhs) { // ACE_TRACE ("ACE_Atomic_Op::ACE_Atomic_Op"); *this = rhs; // Invoke the assignment operator. } template ACE_INLINE TYPE ACE_Atomic_Op::operator++ (int) { // ACE_TRACE ("ACE_Atomic_Op::operator++"); ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_); return this->value_++; } template ACE_INLINE TYPE ACE_Atomic_Op::operator-- (int) { // ACE_TRACE ("ACE_Atomic_Op::operator--"); ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, this->value_); return this->value_--; } template ACE_INLINE int ACE_Atomic_Op::operator== (const TYPE &i) const { // ACE_TRACE ("ACE_Atomic_Op::operator=="); ACE_GUARD_RETURN (ACE_LOCK, ace_mon, (ACE_LOCK &) this->mutex_, -1); return this->value_ == i; } template ACE_INLINE int ACE_Atomic_Op::operator!= (const TYPE &i) const { // ACE_TRACE ("ACE_Atomic_Op::operator!="); return !(*this == i); } template ACE_INLINE int ACE_Atomic_Op::operator>= (const TYPE &i) const { // ACE_TRACE ("ACE_Atomic_Op::operator>="); ACE_GUARD_RETURN (ACE_LOCK, ace_mon, (ACE_LOCK &) this->mutex_, -1); return this->value_ >= i; } template ACE_INLINE int ACE_Atomic_Op::operator> (const TYPE &rhs) const { // ACE_TRACE ("ACE_Atomic_Op::operator>"); ACE_GUARD_RETURN (ACE_LOCK, ace_mon, (ACE_LOCK &) this->mutex_, -1); return this->value_ > rhs; } template ACE_INLINE int ACE_Atomic_Op::operator<= (const TYPE &rhs) const { // ACE_TRACE ("ACE_Atomic_Op::operator<="); ACE_GUARD_RETURN (ACE_LOCK, ace_mon, (ACE_LOCK &) this->mutex_, -1); return this->value_ <= rhs; } template ACE_INLINE int ACE_Atomic_Op::operator< (const TYPE &rhs) const { // ACE_TRACE ("ACE_Atomic_Op::operator<"); ACE_GUARD_RETURN (ACE_LOCK, ace_mon, (ACE_LOCK &) this->mutex_, -1); return this->value_ < rhs; } template ACE_INLINE void ACE_Atomic_Op::operator= (const ACE_Atomic_Op &rhs) { // ACE_TRACE ("ACE_Atomic_Op::operator="); if (&rhs == this) return; // Avoid deadlock... ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_); // This will call ACE_Atomic_Op::TYPE(), which will ensure the value // of is acquired atomically. this->value_ = rhs.value (); } template ACE_INLINE TYPE ACE_Atomic_Op::value (void) const { // ACE_TRACE ("ACE_Atomic_Op::value"); ACE_GUARD_RETURN (ACE_LOCK, ace_mon, (ACE_LOCK &) this->mutex_, this->value_); return this->value_; } template ACE_INLINE TYPE & ACE_Atomic_Op::value_i (void) { // Explicitly return (by reference). This gives the user // full, unrestricted access to the underlying value. This method // will usually be used in conjunction with explicit access to the // lock. Use with care ;-) return this->value_; } template ACE_INLINE void ACE_Atomic_Op::operator= (const TYPE &i) { // ACE_TRACE ("ACE_Atomic_Op::operator="); ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_); this->value_ = i; } // These specializations have been added to ACE_Atomic_Op to make the // implementation faster on Win32 that has OS support for doing this // quickly through methods like InterlockedIncrement and // InterlockedDecrement // Note : All of these special interlocked functions can fail if the // value being locked is not aligned on a 32 bit boundary. // Note : If InterlockedExchangeAdd is unavailable then it isn't possible // to implement +=, -=, i++, or i--. Therefore it's pointless to // specialize anything because it won't be thread-safe. #if defined (ACE_HAS_INTERLOCKED_EXCHANGEADD) // FUZZ: disable check_for_inline // implements ++long ACE_TEMPLATE_SPECIALIZATION inline long ACE_Atomic_Op::operator++ (void) { return ::InterlockedIncrement (&this->value_); } // --long ACE_TEMPLATE_SPECIALIZATION inline long ACE_Atomic_Op::operator-- (void) { return ::InterlockedDecrement (&this->value_); } // If it has ExchangeAdd then it also has CompareExchange // implements long++ ACE_TEMPLATE_SPECIALIZATION inline long ACE_Atomic_Op::operator++ (int) { // InterlockedExchangeAdd returns the original value_. return ::InterlockedExchangeAdd (&this->value_, 1); } // long-- ACE_TEMPLATE_SPECIALIZATION inline long ACE_Atomic_Op::operator-- (int) { // InterlockedExchangeAdd returns the original value_. return ::InterlockedExchangeAdd (&this->value_, -1); } ACE_TEMPLATE_SPECIALIZATION inline long ACE_Atomic_Op::operator+= (const long& i) { // InterlockedExchangeAdd returns the original value_. return i + ::InterlockedExchangeAdd (&this->value_, i); } ACE_TEMPLATE_SPECIALIZATION inline long ACE_Atomic_Op::operator-= (const long& i) { // InterlockedExchangeAdd returns the original value_. return i + ::InterlockedExchangeAdd (&this->value_, -i); } ACE_TEMPLATE_SPECIALIZATION inline void ACE_Atomic_Op::operator= (const long& i) { // Note : This is already an atomic operation. You only need InterlockedExchange // if you want to atomically assign and compare to the old value. But an assignment // operator is interested in the new value so ... this->value_ = i; } ACE_TEMPLATE_SPECIALIZATION inline void ACE_Atomic_Op::operator= (const ACE_Atomic_Op& rhs) { // Note : This is already an atomic operation. You only need InterlockedExchange // if you want to atomically assign and compare to the old value. But an assignment // operator is interested in the new value so ... this->value_ = rhs.value(); } ACE_TEMPLATE_SPECIALIZATION inline int ACE_Atomic_Op::operator== (const long& rhs) const { return this->value_ == rhs; } ACE_TEMPLATE_SPECIALIZATION inline int ACE_Atomic_Op::operator!= (const long& rhs) const { return this->value_ != rhs; } ACE_TEMPLATE_SPECIALIZATION inline int ACE_Atomic_Op::operator>= (const long& rhs) const { return this->value_ >= rhs; } ACE_TEMPLATE_SPECIALIZATION inline int ACE_Atomic_Op::operator> (const long& rhs) const { return this->value_ > rhs; } ACE_TEMPLATE_SPECIALIZATION inline int ACE_Atomic_Op::operator<= (const long& rhs) const { return this->value_ <= rhs; } ACE_TEMPLATE_SPECIALIZATION inline int ACE_Atomic_Op::operator< (const long& rhs) const { return this->value_ < rhs; } ACE_TEMPLATE_SPECIALIZATION inline long ACE_Atomic_Op::value (void) const { return this->value_; } #endif /* ACE_HAS_INTERLOCKED_EXCHANGEADD */