⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _mutex.h

📁 realview22.rar
💻 H
📖 第 1 页 / 共 3 页
字号:
#ifndef _RWSTD_NO_STATIC_MUTEX_INIT

inline __rw_mutex::~__rw_mutex () 

#else   // if defined (_RWSTD_NO_STATIC_MUTEX_INIT)

inline __rw_mutex_base::~__rw_mutex_base () 

#endif   // _RWSTD_NO_STATIC_MUTEX_INIT
{
    _RWSTD_MUTEX_DESTROY (_C_mutex);
}


// mutex factory function avoids problematic initialization dependencies
// introduced by definitions of mutexes with static storage duration
// instead of defining a static mutex member that may not be initialized
// before first use, a non-local class may either declare a unique type
// (enum or class) or use itself as this type, and call this template
// function with a ptr to that type to obtain an initialized mutex object
// that is the same for each unique type passed to the function

#ifndef _RWSTD_NO_STATIC_MUTEX_INIT

template <class _TypeT>
inline
__rw_mutex_base& __rw_get_static_mutex (_TypeT*)
{
    // POD mutex already initialized during static initialization
    return __rw_static_mutex<_TypeT>::_C_mutex;
}

#else   // if defined (_RWSTD_NO_STATIC_MUTEX_INIT)

#ifdef _INLINE_WITH_STATICS

template <class _TypeT>
_INLINE_WITH_STATICS
__rw_mutex_base& __rw_get_static_mutex (_TypeT*)

#else    // if !defined (_INLINE_WITH_STATICS)

template <class _TypeT>
__rw_mutex_base& __rw_get_static_mutex (_TypeT*)

#endif   // _INLINE_WITH_STATICS

{
    // allocate properly aligned memory for static mutex (necessary
    // to prevent static local mutex from being destroyed during
    // program termination)
    union __mutex_buf_t {
        long double __pad;   // force alignment (must be first)
        char        __buf [sizeof (__rw_mutex_base)];
    };

    // using a named union to work around a bug in HP aCC 3.14.10 (JAGad03246)
    static __mutex_buf_t __mutex_buf;

    // initialize mutex reference to refer to the static buffer space
    __rw_mutex_base &__mutex =
        _RWSTD_REINTERPRET_CAST (__rw_mutex_base&, __mutex_buf);

    // keep track of number of mutex initialization attempts
    // although `init' may reach a value greater than 1, `mutex'
    // will (should) never be multiply initialized

    // implicit initialization used to prevent a g++ 2.95.2 warning on Tru64
    // sorry: semantics of inline function static data are wrong (you'll wind
    // up with multiple copies)
    static volatile long __cntr /* = 0 */;   // initialization counter

#if defined (_WIN32) || defined (_WIN64)
    // MT safe
    if (0 == __cntr && 1 == InterlockedIncrement ((long*)&__cntr))
#else
    // not so safe (volatile should help)
    if (0 == __cntr && 1 == ++__cntr)
#endif   // _WIN32

    {
        // manually initialize `mutex' via a call to placement new
        new (&__mutex) __rw_mutex_base ();

        // indicate that `mutex' has been fully initialized
        // (unlikely that we'll have more than 1000 threads)
        __cntr += 1000;
    }
    else
        // busywait until `mutex' has been completely initialized
        while (__cntr < 1000);

    return __mutex;
}

#endif   //_RWSTD_NO_STATIC_MUTEX_INIT


// clean up
#undef _RWSTD_MUTEX_LOCK
#undef _RWSTD_MUTEX_UNLOCK
#undef _RWSTD_MUTEX_T


// allows safe use of a mutex in the presence of exceptions
class __rw_guard
{
    __rw_mutex_base *_C_mutex;

    // undefined
    __rw_guard& operator= (const __rw_guard&);
    
public:

    __rw_guard (__rw_guard &__rhs)
        : _C_mutex (__rhs._C_mutex) {
        __rhs._C_mutex = 0;
    }

    __rw_guard (__rw_mutex_base &__mutex): _C_mutex (&__mutex) {
        _C_mutex->_C_acquire ();
    }

    __rw_guard (__rw_mutex_base *__mutex): _C_mutex (__mutex) {
        if (_C_mutex)
            _C_mutex->_C_acquire ();
    }

    ~__rw_guard () {
        if (_C_mutex)
            _C_mutex->_C_release ();
    }

    __rw_mutex_base* _C_set (__rw_mutex_base *__mutex) {
        __rw_mutex_base *__tmp = _C_mutex;
        return _C_mutex = __mutex, __tmp;
    }
};


// base class for obects required to guarantee some degree of MT safety
struct _RWSTD_EXPORT __rw_synchronized
{
    __rw_mutex _C_mutex;

    void _C_lock () {
        _C_mutex._C_acquire ();
    }

    void _C_unlock () {
        _C_mutex._C_release ();
    }

    __rw_guard _C_guard () {
        __rw_guard __guard (_C_mutex);
        return __guard;
    }
};


// helper functions for atomic value [in|de]crement and exchange
// the functions are atomic with respect to each other as long as
// they are passed the same mutex by the callers
template <class _TypeT>
inline
_TypeT __rw_atomic_preincrement (_TypeT &__t, __rw_mutex_base &__mutex)
{
    _RWSTD_MT_GUARD (__mutex);

    return ++__t;
}


template <class _TypeT>
inline
_TypeT __rw_atomic_predecrement (_TypeT &__t, __rw_mutex_base &__mutex)
{
    _RWSTD_MT_GUARD (__mutex);

    return --__t;
}


template <class _TypeT, class _TypeU>
inline
_TypeT __rw_atomic_exchange (_TypeT &__t, const _TypeU &__u,
                             __rw_mutex_base &__mutex)
{
    _RWSTD_MT_GUARD (__mutex);

    _TypeT __tmp = __t;
    __t = __u;
    return __tmp;
}


// for use on class statics or on namespace-scope variables
// the unused argument is only here so that all functions can be
// called from the same set of macros

template <class _TypeT>
inline
_TypeT __rw_atomic_preincrement (_TypeT &__t, bool)
{
    return __rw_atomic_preincrement (__t,
                                     __rw_get_static_mutex ((_TypeT*)0));
}


template <class _TypeT>
inline
_TypeT __rw_atomic_predecrement (_TypeT &__t, bool)
{
    return __rw_atomic_predecrement (__t,
                                     __rw_get_static_mutex ((_TypeT*)0));
}


template <class _TypeT, class _TypeU>
inline
_TypeT __rw_atomic_exchange (_TypeT &__t, const _TypeU &__u, bool)
{
    return __rw_atomic_exchange (__t, __u,
                                 __rw_get_static_mutex ((_TypeT*)0));
}

/********************** DEC CXX **************************************/

#if defined (__DECCXX) && !defined (_RWSTD_NO_ATOMIC_OPERATIONS)

// __ATOMIC_[DE|IN]CREMENT_[LONG|QUAD] and __ATOMIC_EXCH_[LONG|QUAD] are
// intrinsic functions declared in <machine/builtins.h> that atomically
// modify their argument and return its original value (__ATOMIC_XXX_LONG
// is misnamed -- it actually operates on an int, not a long)

inline
int __rw_atomic_preincrement (int &__x, bool)
{
    return 1 + __ATOMIC_INCREMENT_LONG (&__x);
}


inline
unsigned __rw_atomic_preincrement (unsigned &__x, bool)
{
    return __rw_atomic_preincrement (_RWSTD_REINTERPRET_CAST (int&, __x),
                                     false);
}


inline
long __rw_atomic_preincrement (long &__x, bool)
{
    return 1 + __ATOMIC_INCREMENT_QUAD (&__x);
}


inline
unsigned long __rw_atomic_preincrement (unsigned long &__x, bool)
{
    return __rw_atomic_preincrement (_RWSTD_REINTERPRET_CAST (long&, __x),
                                     false);
}


template <class _TypeT>
inline _TypeT* __rw_atomic_preincrement (_TypeT* &__x, bool)
{
    _RWSTD_COMPILE_ASSERT (sizeof __x == sizeof (long));

    return _RWSTD_REINTERPRET_CAST (_TypeT*,
             __rw_atomic_preincrement (_RWSTD_REINTERPRET_CAST (long&, __x),
                                       false));
}


inline
int __rw_atomic_predecrement (int &__x, bool)
{
    return __ATOMIC_DECREMENT_LONG (&__x) - 1;
}

inline
unsigned __rw_atomic_predecrement (unsigned &__x, bool)
{
    return __rw_atomic_predecrement (_RWSTD_REINTERPRET_CAST (int&, __x),
                                     false);
}


inline
long __rw_atomic_predecrement (long &__x, bool)
{
    return __ATOMIC_DECREMENT_QUAD (&__x) - 1;
}


inline
unsigned long __rw_atomic_predecrement (unsigned long &__x, bool)
{
    return __rw_atomic_predecrement (_RWSTD_REINTERPRET_CAST (long&, __x),
                                     false);
}


template <class _TypeT>
inline _TypeT* __rw_atomic_predecrement (_TypeT* &__x, bool)
{
    _RWSTD_COMPILE_ASSERT (sizeof __x == sizeof (long));

    return _RWSTD_REINTERPRET_CAST (_TypeT*,
             __rw_atomic_predecrement (_RWSTD_REINTERPRET_CAST (long&, __x),
                                       false));
}


inline
int __rw_atomic_exchange (int &__x, int __y, bool)
{
    return __ATOMIC_EXCH_LONG (&__x, __y);
}


inline
unsigned __rw_atomic_exchange (unsigned &__x, unsigned __y, bool)
{
    return __rw_atomic_exchange (_RWSTD_REINTERPRET_CAST (unsigned&, __x),
                                 _RWSTD_STATIC_CAST (int, __y), false);
}


inline
long __rw_atomic_exchange (long &__x, long __y, bool)
{
    return __ATOMIC_EXCH_QUAD (&__x, __y);
}


inline
unsigned long __rw_atomic_exchange (unsigned long &__x, unsigned long __y, bool)
{
    return __rw_atomic_exchange (_RWSTD_REINTERPRET_CAST (unsigned long&, __x),
                                 _RWSTD_STATIC_CAST (long, __y), false);
}


template <class _TypeT>
inline _TypeT* __rw_atomic_exchange (_TypeT* &__x, const _TypeT* __y, bool)
{
    _RWSTD_COMPILE_ASSERT (sizeof __x == sizeof (long));

    return _RWSTD_REINTERPRET_CAST (_TypeT*,
             __rw_atomic_exchange (_RWSTD_REINTERPRET_CAST (long&, __x),
                                   _RWSTD_REINTERPRET_CAST (long,  __y),
                                   false));
}

/********************** gcc/i86 **************************************/

#elif defined (__i386__) && defined (__GNUG__)

inline
int __rw_atomic_preincrement (int &__x, bool)
{
    __asm__ __volatile__ ("lock; addl $1,%0" : : "m" (__x));

    return __x;
}


inline
unsigned __rw_atomic_preincrement (unsigned &__x, bool)
{
    return __rw_atomic_preincrement (_RWSTD_REINTERPRET_CAST (int&, __x),
                                     false);
}


inline
long __rw_atomic_preincrement (long &__x, bool)
{
    return __rw_atomic_preincrement (_RWSTD_REINTERPRET_CAST (int&, __x),
                                     false);
}


inline
unsigned long __rw_atomic_preincrement (unsigned long &__x, bool)
{
    return __rw_atomic_preincrement (_RWSTD_REINTERPRET_CAST (int&, __x),
                                     false);
}


template <class _TypeT>
inline _TypeT* __rw_atomic_preincrement (_TypeT* &__x, bool)
{
    _RWSTD_COMPILE_ASSERT (sizeof __x == sizeof (long));

    return _RWSTD_REINTERPRET_CAST (_TypeT*,
             __rw_atomic_preincrement (_RWSTD_REINTERPRET_CAST (long&, __x),
                                       false));
}


inline
int __rw_atomic_predecrement (int &__x, bool)
{
    __asm__ __volatile__ ("lock; subl $1,%0" : : "m" (__x));

    return __x;
}

inline
unsigned __rw_atomic_predecrement (unsigned &__x, bool)
{
    _RWSTD_COMPILE_ASSERT (sizeof __x == sizeof (int));

    return __rw_atomic_predecrement (_RWSTD_REINTERPRET_CAST (int&, __x),
                                     false);
}


inline
long __rw_atomic_predecrement (long &__x, bool)
{
    _RWSTD_COMPILE_ASSERT (sizeof __x == sizeof (int));

    return __rw_atomic_predecrement (_RWSTD_REINTERPRET_CAST (int&, __x),
                                     false);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -