/* * PROGRAM: Client/Server Common Code * MODULE: fb_atomic.h * DESCRIPTION: Atomic counters * * The contents of this file are subject to the Initial * Developer's Public License Version 1.0 (the "License"); * you may not use this file except in compliance with the * License. You may obtain a copy of the License at * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. * * Software distributed under the License is distributed AS IS, * WITHOUT WARRANTY OF ANY KIND, either express or implied. * See the License for the specific language governing rights * and limitations under the License. * * The Original Code was created by Nickolay Samofatov * for the Firebird Open Source RDBMS project. * * Copyright (c) 2004 Nickolay Samofatov * and all contributors signed below. * * All Rights Reserved. * Contributor(s): ______________________________________. * * * $Id: fb_atomic.h,v 1.4 2004-06-30 01:26:06 skidder Exp $ * */ #ifndef CLASSES_FB_ATOMIC_H #define CLASSES_FB_ATOMIC_H #if defined(WIN_NT) #include namespace Firebird { // Win95 is not supported unless compiled conditionally and // redirected to generic version below class AtomicCounter { public: typedef LONG counter_type; AtomicCounter(counter_type val = 0) : counter(val) {} ~AtomicCounter() {} counter_type exchangeAdd(counter_type val) { return InterlockedExchangeAdd(&counter, val); } counter_type operator +=(counter_type val) { return exchangeAdd(val) + val; } counter_type operator -=(counter_type val) { return exchangeAdd(-val) - val; } counter_type operator ++() { return InterlockedIncrement(&counter); } counter_type operator --() { return InterlockedDecrement(&counter); } counter_type value() const { return counter; } private: # if (defined(_MSC_VER) && (_MSC_VER <= 1200)) || defined(MINGW) counter_type counter; # else volatile counter_type counter; # endif }; } // namespace Firebird #elif defined(__GNUC__) && (defined(i386) || defined(I386) || defined(_M_IX86) || defined(AMD64)) // Assembler version for x86 and AMD64. Note it uses xaddl thus it requires i486 class AtomicCounter { public: typedef int counter_type; AtomicCounter(counter_type value = 0) : counter(value) {} ~AtomicCounter() {} counter_type exchangeAdd(counter_type value) { register counter_type result; __asm __volatile ( "lock; xaddl %0, %1" : "=r" (result), "=m" (counter) : "0" (value), "m" (counter)); return result; } counter_type operator +=(counter_type value) { return exchangeAdd(value) + value; } counter_type operator -=(counter_type value) { return exchangeAdd(-value) - value; } counter_type operator ++() { return exchangeAdd(1) + 1; } counter_type operator --() { return exchangeAdd(-1) - 1; } counter_type value() const { return counter; } private: volatile counter_type counter; }; #else # include "../common/classes/locks.h" namespace Firebird { // Highly inefficient, but safe and portable implementation class AtomicCounter { public: typedef int counter_type; AtomicCounter(counter_type value = 0) : counter(value) {} ~AtomicCounter() {} counter_type exchangeAdd(counter_type value) { lock.enter(); counter_type temp = counter; counter += value; lock.leave(); return temp; } counter_type operator +=(counter_type value) { lock.enter(); counter_type temp = counter += value; lock.leave(); return temp; } counter_type operator -=(counter_type value) { lock.enter(); counter_type temp = counter -= value; lock.leave(); return temp; } counter_type operator ++() { lock.enter(); counter_type temp = counter++; lock.leave(); return temp; } counter_type operator --() { lock.enter(); counter_type temp = counter--; lock.leave(); return temp; } counter_type value() const { return counter; } private: volatile counter_type counter; Mutex lock; }; } // namespace Firebird #endif #endif // CLASSES_FB_ATOMIC_H