📄 atomicint.h
字号:
//%2006//////////////////////////////////////////////////////////////////////////// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation, The Open Group.// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; Symantec Corporation; The Open Group.//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to// deal in the Software without restriction, including without limitation the// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or// sell copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions:// // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.////==============================================================================////%/////////////////////////////////////////////////////////////////////////////#ifndef Pegasus_AtomicInt_h#define Pegasus_AtomicInt_h#include <Pegasus/Common/Config.h>//==============================================================================//// class AtomicIntTemplate<>////==============================================================================PEGASUS_NAMESPACE_BEGINtemplate<class ATOMIC_TYPE>class AtomicIntTemplate{public: // Constructor. AtomicIntTemplate(Uint32 n = 0); // Destructor. ~AtomicIntTemplate(); // Sets value. void set(Uint32 n); // Gets value. Uint32 get() const; // Increment. void inc(); // Decrement. void dec(); // Decrements and returns true if it is zero. bool decAndTestIfZero(); // Assignment. AtomicIntTemplate& operator=(Uint32 n) { set(n); return* this; } // Post-increment. void operator++(int) { inc(); } // Post-decrement. void operator--(int) { dec(); }private: // Note: These methods are intentionally hidden (and should not be called). // The implementation is much easier without having to implement these for // every platform. AtomicIntTemplate(const AtomicIntTemplate&); AtomicIntTemplate& operator=(const AtomicIntTemplate&); Boolean operator==(Uint32) const; void operator++(); void operator--(); typedef AtomicIntTemplate<ATOMIC_TYPE> This; ATOMIC_TYPE _rep;};PEGASUS_NAMESPACE_END//==============================================================================//// PEGASUS_PLATFORM_LINUX_IX86_GNU// PEGASUS_PLATFORM_DARWIN_IX86_GNU////==============================================================================#if defined(PEGASUS_PLATFORM_LINUX_IX86_GNU) || \ defined(PEGASUS_PLATFORM_DARWIN_IX86_GNU)# define PEGASUS_ATOMIC_INT_DEFINED// Note: this lock can be eliminated for single processor systems.# define PEGASUS_ATOMIC_LOCK "lock ; "PEGASUS_NAMESPACE_BEGINstruct AtomicType{ volatile int n;};PEGASUS_TEMPLATE_SPECIALIZATIONinline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n){ _rep.n = n;}PEGASUS_TEMPLATE_SPECIALIZATIONinline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate(){}PEGASUS_TEMPLATE_SPECIALIZATIONinline Uint32 AtomicIntTemplate<AtomicType>::get() const{ return _rep.n;}PEGASUS_TEMPLATE_SPECIALIZATIONinline void AtomicIntTemplate<AtomicType>::set(Uint32 n){ _rep.n = n;}PEGASUS_TEMPLATE_SPECIALIZATIONinline void AtomicIntTemplate<AtomicType>::inc(){ asm volatile( PEGASUS_ATOMIC_LOCK "incl %0" :"=m" (_rep.n) :"m" (_rep.n));}PEGASUS_TEMPLATE_SPECIALIZATIONinline void AtomicIntTemplate<AtomicType>::dec(){ asm volatile( PEGASUS_ATOMIC_LOCK "decl %0" :"=m" (_rep.n) :"m" (_rep.n));}PEGASUS_TEMPLATE_SPECIALIZATIONinline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero(){ unsigned char c; asm volatile( PEGASUS_ATOMIC_LOCK "decl %0; sete %1" :"=m" (_rep.n), "=qm" (c) :"m" (_rep.n) : "memory"); return c != 0;}typedef AtomicIntTemplate<AtomicType> AtomicInt;PEGASUS_NAMESPACE_END#endif /* PEGASUS_PLATFORM_LINUX_IX86_GNU *///==============================================================================//// PEGASUS_PLATFORM_LINUX_X86_64_GNU////==============================================================================#if defined(PEGASUS_PLATFORM_LINUX_X86_64_GNU)# define PEGASUS_ATOMIC_INT_DEFINED// Note: this lock can be eliminated for single processor systems.# define PEGASUS_ATOMIC_LOCK "lock ; "PEGASUS_NAMESPACE_BEGINstruct AtomicType{ volatile int n;};PEGASUS_TEMPLATE_SPECIALIZATIONinline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n){ _rep.n = n;}PEGASUS_TEMPLATE_SPECIALIZATIONinline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate(){}PEGASUS_TEMPLATE_SPECIALIZATIONinline Uint32 AtomicIntTemplate<AtomicType>::get() const{ return _rep.n;}PEGASUS_TEMPLATE_SPECIALIZATIONinline void AtomicIntTemplate<AtomicType>::set(Uint32 n){ _rep.n = n;}PEGASUS_TEMPLATE_SPECIALIZATIONinline void AtomicIntTemplate<AtomicType>::inc(){ asm volatile( PEGASUS_ATOMIC_LOCK "incl %0" :"=m" (_rep.n) :"m" (_rep.n));}PEGASUS_TEMPLATE_SPECIALIZATIONinline void AtomicIntTemplate<AtomicType>::dec(){ asm volatile( PEGASUS_ATOMIC_LOCK "decl %0" :"=m" (_rep.n) :"m" (_rep.n));}PEGASUS_TEMPLATE_SPECIALIZATIONinline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero(){ unsigned char c; asm volatile( PEGASUS_ATOMIC_LOCK "decl %0; sete %1" :"=m" (_rep.n), "=qm" (c) :"m" (_rep.n) : "memory"); return c != 0;}typedef AtomicIntTemplate<AtomicType> AtomicInt;PEGASUS_NAMESPACE_END#endif /* PEGASUS_PLATFORM_LINUX_X86_64_GNU *///==============================================================================//// PEGASUS_PLATFORM_LINUX_IA64_GNU////==============================================================================#if defined(PEGASUS_PLATFORM_LINUX_IA64_GNU)# define PEGASUS_ATOMIC_INT_DEFINEDPEGASUS_NAMESPACE_BEGINstruct AtomicType{ volatile int n;};PEGASUS_TEMPLATE_SPECIALIZATIONinline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n){ _rep.n = (int)n;}PEGASUS_TEMPLATE_SPECIALIZATIONinline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate(){ // Nothing to do!}PEGASUS_TEMPLATE_SPECIALIZATIONinline Uint32 AtomicIntTemplate<AtomicType>::get() const{ return (Uint32)_rep.n;}PEGASUS_TEMPLATE_SPECIALIZATIONinline void AtomicIntTemplate<AtomicType>::set(Uint32 n){ _rep.n = (int)n;}PEGASUS_TEMPLATE_SPECIALIZATIONinline void AtomicIntTemplate<AtomicType>::inc(){ unsigned long tmp; volatile int* v = &_rep.n; asm volatile( "fetchadd4.rel %0=[%1],%2" : "=r"(tmp) : "r"(v), "i"(1) : "memory");}PEGASUS_TEMPLATE_SPECIALIZATIONinline void AtomicIntTemplate<AtomicType>::dec(){ unsigned long tmp; volatile int* v = &_rep.n; asm volatile( "fetchadd4.rel %0=[%1],%2" : "=r"(tmp) : "r"(v), "i"(-1) : "memory");}PEGASUS_TEMPLATE_SPECIALIZATIONinline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero(){ unsigned long tmp; volatile int* v = &_rep.n; asm volatile( "fetchadd4.rel %0=[%1],%2" : "=r"(tmp) : "r"(v), "i"(-1) : "memory"); return tmp == 1;}typedef AtomicIntTemplate<AtomicType> AtomicInt;PEGASUS_NAMESPACE_END#endif /* PEGASUS_PLATFORM_LINUX_IA64_GNU *///==============================================================================//// PEGASUS_PLATFORM_LINUX_PPC_GNU////==============================================================================#if defined(PEGASUS_PLATFORM_LINUX_PPC_GNU)# define PEGASUS_ATOMIC_INT_DEFINEDPEGASUS_NAMESPACE_BEGINstruct AtomicType{ volatile Uint32 n;};PEGASUS_TEMPLATE_SPECIALIZATIONinline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n){ _rep.n = n;}PEGASUS_TEMPLATE_SPECIALIZATIONinline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate(){}PEGASUS_TEMPLATE_SPECIALIZATIONinline Uint32 AtomicIntTemplate<AtomicType>::get() const{ return _rep.n;}PEGASUS_TEMPLATE_SPECIALIZATIONinline void AtomicIntTemplate<AtomicType>::set(Uint32 n){ _rep.n = n;}PEGASUS_TEMPLATE_SPECIALIZATIONinline void AtomicIntTemplate<AtomicType>::inc(){ int t; asm volatile( "1: lwarx %0,0,%2\n" "addic %0,%0,1\n" "stwcx. %0,0,%2\n" "bne- 1b" : "=&r" (t), "=m" (_rep.n) : "r" (&_rep.n), "m" (_rep.n) : "cc");}PEGASUS_TEMPLATE_SPECIALIZATIONinline void AtomicIntTemplate<AtomicType>::dec(){ int c; asm volatile( "1: lwarx %0,0,%1\n" "addic %0,%0,-1\n" "stwcx. %0,0,%1\n" "bne- 1b" : "=&r" (c) : "r" (&_rep.n) : "cc", "memory");}PEGASUS_TEMPLATE_SPECIALIZATIONinline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero(){ int c; asm volatile( "1: lwarx %0,0,%1\n" "addic %0,%0,-1\n" "stwcx. %0,0,%1\n" "bne- 1b" : "=&r" (c) : "r" (&_rep.n) : "cc", "memory"); return c == 0;}typedef AtomicIntTemplate<AtomicType> AtomicInt;PEGASUS_NAMESPACE_END#endif /* PEGASUS_PLATFORM_LINUX_PPC_GNU *///==============================================================================//// PEGASUS_PLATFORM_WIN32_IX86_MSVC////==============================================================================#if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC)# define PEGASUS_ATOMIC_INT_DEFINED#include <Pegasus/Common/Network.h>#include <windows.h>PEGASUS_NAMESPACE_BEGINtypedef LONG AtomicType;PEGASUS_TEMPLATE_SPECIALIZATIONinline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n){ _rep = LONG(n);}PEGASUS_TEMPLATE_SPECIALIZATIONinline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate(){}PEGASUS_TEMPLATE_SPECIALIZATIONinline Uint32 AtomicIntTemplate<AtomicType>::get() const
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -