(file) Return to AtomicInt.h CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

File: [Pegasus] / pegasus / src / Pegasus / Common / AtomicInt.h (download)
Revision: 1.8.2.2, Sat Jul 29 00:03:41 2006 UTC (17 years, 11 months ago) by mike
Branch: TASK_BUG_5314_IPC_REFACTORING_BRANCH
CVS Tags: TASK_BUG_5314_IPC_REFACTORING-V1
Changes since 1.8.2.1: +0 -12 lines
BUG#: 5314
TITLE: IPC Refactoring

DESCRIPTION: IPC Refactoring Branch Work

//%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.
//
//==============================================================================
//
// Author: Mike Brasher (m.brasher@inovadevelopment.com) - Inova Development
//
//%/////////////////////////////////////////////////////////////////////////////

#ifndef Pegasus_AtomicInt_h
#define Pegasus_AtomicInt_h

#include <Pegasus/Common/Config.h>

//==============================================================================
//
// class AtomicIntTemplate<>
//
//==============================================================================

PEGASUS_NAMESPACE_BEGIN

template<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
//
//==============================================================================

#if defined(PEGASUS_PLATFORM_LINUX_IX86_GNU)
# define PEGASUS_ATOMIC_INT_DEFINED

// Note: this lock can be eliminated for single processor systems.
# define PEGASUS_ATOMIC_LOCK "lock ; "

PEGASUS_NAMESPACE_BEGIN

struct AtomicType
{
    volatile int n; 
};

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
{
    _rep.n = n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
{
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline Uint32 AtomicIntTemplate<AtomicType>::get() const
{
    return _rep.n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
{
    _rep.n = n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::inc()
{
    asm volatile(
	PEGASUS_ATOMIC_LOCK "incl %0"
	:"=m" (_rep.n)
	:"m" (_rep.n));
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::dec()
{
    asm volatile(
        PEGASUS_ATOMIC_LOCK "decl %0"
        :"=m" (_rep.n)
        :"m" (_rep.n));
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline 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_BEGIN

struct AtomicType
{
    volatile int n; 
};

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
{
    _rep.n = n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
{
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline Uint32 AtomicIntTemplate<AtomicType>::get() const
{
    return _rep.n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
{
    _rep.n = n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::inc()
{
    asm volatile(
	PEGASUS_ATOMIC_LOCK "incl %0"
	:"=m" (_rep.n)
	:"m" (_rep.n));
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::dec()
{
    asm volatile(
        PEGASUS_ATOMIC_LOCK "decl %0"
        :"=m" (_rep.n)
        :"m" (_rep.n));
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline 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_DEFINED

PEGASUS_NAMESPACE_BEGIN

struct AtomicType
{
    volatile int n;
};

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
{
    _rep.n = (int)n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
{
    // Nothing to do!
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline Uint32 AtomicIntTemplate<AtomicType>::get() const
{
    return (Uint32)_rep.n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
{
    _rep.n = (int)n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline 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_SPECIALIZATION
inline 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_SPECIALIZATION
inline 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_DEFINED

PEGASUS_NAMESPACE_BEGIN

struct AtomicType
{
    volatile Uint32 n; 
};

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
{
    _rep.n = n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
{
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline Uint32 AtomicIntTemplate<AtomicType>::get() const
{
    return _rep.n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
{
    _rep.n = n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline 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_SPECIALIZATION
inline 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_SPECIALIZATION
inline 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_BEGIN

typedef LONG AtomicType;

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
{
    _rep = LONG(n);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
{
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline Uint32 AtomicIntTemplate<AtomicType>::get() const
{
    return Uint32(_rep);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
{
    _rep = LONG(n);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::inc()
{
    InterlockedIncrement(&_rep);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::dec()
{
    InterlockedDecrement(&_rep);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
{
    return InterlockedDecrement(&_rep) == 0;
}

typedef AtomicIntTemplate<AtomicType> AtomicInt;

PEGASUS_NAMESPACE_END

#endif /* PEGASUS_PLATFORM_WIN32_IX86_MSVC */

//==============================================================================
//
// PEGASUS_PLATFORM_ZOS_ZSERIES_IBM
//
//==============================================================================

#if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
# define PEGASUS_ATOMIC_INT_DEFINED

PEGASUS_NAMESPACE_BEGIN

struct AtomicType
{
    cs_t n;
};

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
{
    _rep.n = (cs_t)n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
{
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline Uint32 AtomicIntTemplate<AtomicType>::get() const
{
    return (Uint32)_rep.n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
{
    _rep.n = (cs_t)n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::inc()
{
    Uint32 x = (Uint32)_rep.n;
    Uint32 old = x;
    x++;
    while ( cs( (cs_t*)&old, &(_rep.n), (cs_t)x) )
    {
       x = (Uint32)_rep.n;
       old = x;
       x++;
    }
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::dec()
{
    Uint32 x = (Uint32)_rep.n;
    Uint32 old = x;
    x--;
    while ( cs( (cs_t*)&old, &(_rep.n), (cs_t) x) )
    {
       x = (Uint32) _rep.n;
       old = x;
       x--;
    }
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
{
    Uint32 x = (Uint32)_rep.n;
    Uint32 old = x;
    x--;
    while ( cs( (cs_t*)&old, &(_rep.n), (cs_t) x) )
    {
       x = (Uint32) _rep.n;
       old = x;
       x--;
    }
    return x==0;
}

typedef AtomicIntTemplate<AtomicType> AtomicInt;

PEGASUS_NAMESPACE_END

#endif /* PEGASUS_PLATFORM_ZOS_ZSERIES_IBM */

//==============================================================================
//
// PEGASUS_PLATFORM_HPUX_IA64_ACC
//
//==============================================================================

#if defined (PEGASUS_PLATFORM_HPUX_IA64_ACC)
# define PEGASUS_ATOMIC_INT_DEFINED

#include <machine/sys/inline.h>

PEGASUS_NAMESPACE_BEGIN

struct AtomicType
{
    volatile Uint32 n;
};

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
{
    _rep.n = n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
{
    // Nothing to do!
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline Uint32 AtomicIntTemplate<AtomicType>::get() const
{
    return _rep.n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
{
    _rep.n = n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::inc()
{
    _Asm_fetchadd(
	(_Asm_fasz)_FASZ_W,
	(_Asm_sem)_SEM_ACQ,
	(volatile Uint32*)&_rep.n,
	(int)1,
	(_Asm_ldhint)_LDHINT_NONE);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::dec()
{
    _Asm_fetchadd(
	(_Asm_fasz)_FASZ_W,
	(_Asm_sem)_SEM_ACQ,
	(volatile Uint32*)&_rep.n,
	(int)-1,
	(_Asm_ldhint)_LDHINT_NONE);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
{
    Uint32 x = _Asm_fetchadd(
	(_Asm_fasz)_FASZ_W,
	(_Asm_sem)_SEM_ACQ,
	(volatile Uint32*)&_rep.n,
	(int)-1,
	(_Asm_ldhint)_LDHINT_NONE);

    return x == 1;
}

typedef AtomicIntTemplate<AtomicType> AtomicInt;

PEGASUS_NAMESPACE_END

#endif /* PEGASUS_PLATFORM_HPUX_IA64_ACC */

//==============================================================================
//
// PEGASUS_PLATFORM_LINUX_XSCALE_GNU
//
//==============================================================================

#if defined (PEGASUS_PLATFORM_LINUX_XSCALE_GNU)
# define PEGASUS_ATOMIC_INT_DEFINED

PEGASUS_NAMESPACE_BEGIN

inline void AtomicIntDisableIRQs(unsigned long& flags)
{
    unsigned long temp;
    unsigned long x;

    asm volatile(
	"mrs %0, cpsr\n"
	"orr %1, %0, #128\n"
	"msr cpsr_c, %1\n"
	: "=r" (x), "=r" (temp)
	:
	: "memory");

    flags = x;
}

inline void AtomicIntEnableIRQs(unsigned long x)
{
    unsigned long temp;

    asm volatile(
	"mrs %0, cpsr\n"
	"orr %1, %0, #128\n"
	"msr cpsr_c, %1\n"
	: "=r" (x), "=r" (temp)
	:
	: "memory");
}

struct AtomicType
{
    volatile Uint32 n;
};

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
{
    _rep.n = n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
{
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline Uint32 AtomicIntTemplate<AtomicType>::get() const
{
    return _rep.n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
{
    _rep.n = n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::inc()
{
    unsigned long flags;
    AtomicIntDisableIRQs(flags);
    _rep.n++;
    AtomicIntEnableIRQs(flags);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::dec()
{
    unsigned long flags;
    AtomicIntDisableIRQs(flags);
    _rep.n--;
    AtomicIntEnableIRQs(flags);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
{
    Uint32 tmp;
    unsigned long flags;
    AtomicIntDisableIRQs(flags);
    tmp = --_rep.n;
    AtomicIntEnableIRQs(flags);
    return tmp == 0;
}

typedef AtomicIntTemplate<AtomicType> AtomicInt;

PEGASUS_NAMESPACE_END

#endif /* PEGASUS_PLATFORM_LINUX_XSCALE_GNU */

//==============================================================================
//
// PEGASUS_PLATFORM_VMS_ALPHA_DECCXX
// PEGASUS_PLATFORM_VMS_IA64_DECCXX
//
//==============================================================================

#if defined (PEGASUS_PLATFORM_VMS_ALPHA_DECCXX) || \
    defined (PEGASUS_PLATFORM_VMS_IA64_DECCXX)
# define PEGASUS_ATOMIC_INT_DEFINED

# include <sys/machine/builtins.h>

PEGASUS_NAMESPACE_BEGIN

struct AtomicType
{
    volatile int n; 
};

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
{
    _rep.n = n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
{
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline Uint32 AtomicIntTemplate<AtomicType>::get() const
{
    return _rep.n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
{
    _rep.n = n;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::inc()
{
    __ATOMIC_INCREMENT_LONG(&_rep.n);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::dec()
{
    __ATOMIC_DECREMENT_LONG(&_rep.n);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
{
    return __ATOMIC_DECREMENT_LONG(&_rep.n) == 1;
}

typedef AtomicIntTemplate<AtomicType> AtomicInt;

PEGASUS_NAMESPACE_END

#endif /* _Pegasus_Common_AtomicInt_VMS_h */

//==============================================================================
//
// Generic Implementation
//
//==============================================================================

#if !defined(PEGASUS_ATOMIC_INT_DEFINED)
# define PEGASUS_ATOMIC_INT_DEFINED

# include <Pegasus/Common/SpinLock.h>

PEGASUS_NAMESPACE_BEGIN

// Represents the atomic type counter.
struct AtomicType
{
    Uint32 n;
};

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::AtomicIntTemplate(Uint32 n)
{
    _rep.n = n;

    if (spinLockPoolInitialized == 0)
	SpinLockCreatePool();
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline AtomicIntTemplate<AtomicType>::~AtomicIntTemplate()
{
    // Nothing to do.
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline Uint32 AtomicIntTemplate<AtomicType>::get() const
{
    Uint32 tmp;
    size_t i = SpinLockIndex(&_rep);
    SpinLockLock(spinLockPool[i]);
    tmp = _rep.n;
    SpinLockUnlock(spinLockPool[i]);
    return tmp;
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::set(Uint32 n)
{
    size_t i = SpinLockIndex(&_rep);
    SpinLockLock(spinLockPool[i]);
    _rep.n = n;
    SpinLockUnlock(spinLockPool[i]);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::inc()
{
    size_t i = SpinLockIndex(&_rep);
    SpinLockLock(spinLockPool[i]);
    _rep.n++;
    SpinLockUnlock(spinLockPool[i]);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline void AtomicIntTemplate<AtomicType>::dec()
{
    size_t i = SpinLockIndex(&_rep);
    SpinLockLock(spinLockPool[i]);
    _rep.n--;
    SpinLockUnlock(spinLockPool[i]);
}

PEGASUS_TEMPLATE_SPECIALIZATION
inline bool AtomicIntTemplate<AtomicType>::decAndTestIfZero()
{
    Uint32 tmp;
    size_t i = SpinLockIndex(&_rep);
    SpinLockLock(spinLockPool[i]);
    tmp = --_rep.n;
    SpinLockUnlock(spinLockPool[i]);
    return tmp == 0;
}

typedef AtomicIntTemplate<AtomicType> AtomicInt;

PEGASUS_NAMESPACE_END

#endif /* !PEGASUS_ATOMIC_INT_DEFINED */

#endif /* Pegasus_AtomicInt_h */

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2