Hi,

To be compliant with the submission protocol, I'm sending the whole file instead of a patch.

On 07/09/12 12:01, Piotr Domagalski wrote:
Hi!

Currently, code using OpenSceneGraph doesn't build with clang due to the
way __sync_bool_compare_and_swap() is used in OpenThreads/Atomic header
file.

I tested it with clang 3.1 and it seems that clang is enforcing the use
of the same type for all parameters in this builtin. Looking at the
function declaration [1]

bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)

it seems to be doing the right thing: here the same type is used for
*ptr, oldval and newval.

[1]
http://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html#g_t_005f_005fsync-Builtins




_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org



--
Piotr Domagalski
Poznan Supercomputing and Networking Center
/* -*-c++-*- OpenThreads library, Copyright (C) 2008  The Open Thread Group
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#ifndef _OPENTHREADS_ATOMIC_
#define _OPENTHREADS_ATOMIC_

#include <OpenThreads/Config>
#include <OpenThreads/Exports>

#if defined(_OPENTHREADS_ATOMIC_USE_BSD_ATOMIC)
# include <libkern/OSAtomic.h>
# define _OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES
#elif defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS) && defined(__i386__)
# define _OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES
#elif defined(_OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED)
# define _OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
# include <atomic.h>
# include "Mutex"
# include "ScopedLock"
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
# include "Mutex"
# include "ScopedLock"
#endif

#if defined(_OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES)
#define _OPENTHREADS_ATOMIC_INLINE
#else
#define _OPENTHREADS_ATOMIC_INLINE inline
#endif

namespace OpenThreads {

/**
 *  @class Atomic
 *  @brief  This class provides an atomic increment and decrement operation.
 */
class OPENTHREAD_EXPORT_DIRECTIVE Atomic {
 public:
    Atomic(unsigned value = 0) : _value(value)
    { }
    _OPENTHREADS_ATOMIC_INLINE unsigned operator++();
    _OPENTHREADS_ATOMIC_INLINE unsigned operator--();
    _OPENTHREADS_ATOMIC_INLINE unsigned AND(unsigned value);
    _OPENTHREADS_ATOMIC_INLINE unsigned OR(unsigned value);
    _OPENTHREADS_ATOMIC_INLINE unsigned XOR(unsigned value);
    _OPENTHREADS_ATOMIC_INLINE unsigned exchange(unsigned value = 0);
    _OPENTHREADS_ATOMIC_INLINE operator unsigned() const;
 private:

    Atomic(const Atomic&);
    Atomic& operator=(const Atomic&);

#if defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
    mutable Mutex _mutex;
#endif
#if defined(_OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED)
    volatile long _value;
#elif defined(_OPENTHREADS_ATOMIC_USE_BSD_ATOMIC)
    volatile int32_t _value;
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
    volatile uint_t _value;
    mutable Mutex _mutex;  // needed for xor
#else
    volatile unsigned _value;
#endif
};

/**
 *  @class AtomicPtr
 *  @brief  This class provides an atomic pointer assignment using cas 
operations.
 */
class OPENTHREAD_EXPORT_DIRECTIVE AtomicPtr {
public:
    AtomicPtr(void* ptr = 0) : _ptr(ptr)
    { }
    ~AtomicPtr()
    { _ptr = 0; }

    // assigns a new pointer
    _OPENTHREADS_ATOMIC_INLINE bool assign(void* ptrNew, const void* const 
ptrOld);
    _OPENTHREADS_ATOMIC_INLINE void* get() const;

private:
    AtomicPtr(const AtomicPtr&);
    AtomicPtr& operator=(const AtomicPtr&);

#if defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
    mutable Mutex _mutex;
#endif
    void* volatile _ptr;
};

#if !defined(_OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES)

_OPENTHREADS_ATOMIC_INLINE unsigned
Atomic::operator++()
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
    return __sync_add_and_fetch(&_value, 1);
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
    return __add_and_fetch(&_value, 1);
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
    return atomic_inc_uint_nv(&_value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
    ScopedLock<Mutex> lock(_mutex);
    return ++_value;
#else
    return ++_value;
#endif
}

_OPENTHREADS_ATOMIC_INLINE unsigned
Atomic::operator--()
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
    return __sync_sub_and_fetch(&_value, 1);
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
    return __sub_and_fetch(&_value, 1);
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
    return atomic_dec_uint_nv(&_value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
    ScopedLock<Mutex> lock(_mutex);
    return --_value;
#else
    return --_value;
#endif
}

_OPENTHREADS_ATOMIC_INLINE unsigned
Atomic::AND(unsigned value)
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
    return __sync_fetch_and_and(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
    return __and_and_fetch(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
    return atomic_and_uint_nv(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
    ScopedLock<Mutex> lock(_mutex);
    _value &= value;
    return _value;
#else
    _value &= value;
    return _value;
#endif
}

_OPENTHREADS_ATOMIC_INLINE unsigned
Atomic::OR(unsigned value)
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
    return __sync_fetch_and_or(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
    return __or_and_fetch(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
    return atomic_or_uint_nv(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
    ScopedLock<Mutex> lock(_mutex);
    _value |= value;
    return _value;
#else
    _value |= value;
    return _value;
#endif
}

_OPENTHREADS_ATOMIC_INLINE unsigned
Atomic::XOR(unsigned value)
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
    return __sync_fetch_and_xor(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
    return __xor_and_fetch(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
    ScopedLock<Mutex> lock(_mutex);
    _value ^= value;
    return _value;
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
    ScopedLock<Mutex> lock(_mutex);
    _value ^= value;
    return _value;
#else
    _value ^= value;
    return _value;
#endif
}

_OPENTHREADS_ATOMIC_INLINE unsigned
Atomic::exchange(unsigned value)
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
    return __sync_lock_test_and_set(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
    return __compare_and_swap(&_value, _value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
    return atomic_cas_uint(&_value, _value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
    ScopedLock<Mutex> lock(_mutex);
    unsigned oldval = _value;
    _value = value;
    return oldval;
#else
    unsigned oldval = _value;
    _value = value;
    return oldval;
#endif
}

_OPENTHREADS_ATOMIC_INLINE
Atomic::operator unsigned() const
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
    __sync_synchronize();
    return _value;
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
    __synchronize();
    return _value;
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
    membar_consumer(); // Hmm, do we need???
    return _value;
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
    ScopedLock<Mutex> lock(_mutex);
    return _value;
#else
    return _value;
#endif
}

_OPENTHREADS_ATOMIC_INLINE bool
AtomicPtr::assign(void* ptrNew, const void* const ptrOld)
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
    return __sync_bool_compare_and_swap(&_ptr, (void *)ptrOld, ptrNew);
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
    return __compare_and_swap((unsigned long*)&_ptr, (unsigned long)ptrOld, 
(unsigned long)ptrNew);
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
    return ptrOld == atomic_cas_ptr(&_ptr, const_cast<void*>(ptrOld), ptrNew);
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
    ScopedLock<Mutex> lock(_mutex);
    if (_ptr != ptrOld)
        return false;
    _ptr = ptrNew;
    return true;
#else
    if (_ptr != ptrOld)
        return false;
    _ptr = ptrNew;
    return true;
#endif
}

_OPENTHREADS_ATOMIC_INLINE void*
AtomicPtr::get() const
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
    __sync_synchronize();
    return _ptr;
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
    __synchronize();
    return _ptr;
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
    membar_consumer(); // Hmm, do we need???
    return _ptr;
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
    ScopedLock<Mutex> lock(_mutex);
    return _ptr;
#else
    return _ptr;
#endif
}

#endif // !defined(_OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES)

}

#endif // _OPENTHREADS_ATOMIC_
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to