wanproxy/common/thread/atomic.h
2015-08-31 14:01:44 +02:00

95 lines
2.5 KiB
C++

/*
* Copyright (c) 2010-2011 Juli Mallett. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef COMMON_THREAD_ATOMIC_H
#define COMMON_THREAD_ATOMIC_H
template<typename T>
class Atomic {
T val_;
public:
Atomic(void)
: val_()
{ }
template<typename Ta>
Atomic(Ta arg)
: val_(arg)
{ }
~Atomic()
{ }
T val () const { return val_; }
bool operator == (T v) const { return (v == val_); }
bool operator != (T v) const { return (v != val_); }
/*
* Note that these are deliberately not operator overloads, to force
* deliberate use of this class.
*/
#if defined(__GNUC__)
template<typename Ta>
T add(Ta arg)
{
return (__sync_add_and_fetch (&val_, arg));
}
template<typename Ta>
T subtract(Ta arg)
{
return (__sync_sub_and_fetch (&val_, arg));
}
template<typename Ta>
T set(Ta arg)
{
return (__sync_or_and_fetch (&val_, arg));
}
template<typename Ta>
T mask(Ta arg)
{
return (__sync_and_and_fetch (&val_, arg));
}
template<typename Ta>
T clear(Ta arg)
{
return (__sync_and_and_fetch (&val_, ~arg));
}
template<typename To, typename Tn>
bool cmpset(To oldval, Tn newval)
{
return (__sync_bool_compare_and_swap (&val_, oldval, newval));
}
#else
#error "No support for atomic operations for your compiler. Why not add some?"
#endif
};
#endif /* !COMMON_THREAD_ATOMIC_H */