| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- /*
- AngelCode Scripting Library
- Copyright (c) 2003-2014 Andreas Jonsson
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any
- damages arising from the use of this software.
- Permission is granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and
- redistribute it freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you
- must not claim that you wrote the original software. If you use
- this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and
- must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source
- distribution.
- The original version of this library can be located at:
- http://www.angelcode.com/angelscript/
- Andreas Jonsson
- [email protected]
- */
-
- //
- // as_atomic.cpp
- //
- // The implementation of the atomic class for thread safe reference counting
- //
- #include "as_atomic.h"
- BEGIN_AS_NAMESPACE
- asCAtomic::asCAtomic()
- {
- value = 0;
- }
- asDWORD asCAtomic::get() const
- {
- // A very high ref count is highly unlikely. It most likely a problem with
- // memory that has been overwritten or is being accessed after it was deleted.
- asASSERT(value < 1000000);
- return value;
- }
- void asCAtomic::set(asDWORD val)
- {
- // A very high ref count is highly unlikely. It most likely a problem with
- // memory that has been overwritten or is being accessed after it was deleted.
- asASSERT(value < 1000000);
- value = val;
- }
- asDWORD asCAtomic::atomicInc()
- {
- // A very high ref count is highly unlikely. It most likely a problem with
- // memory that has been overwritten or is being accessed after it was deleted.
- asASSERT(value < 1000000);
- return asAtomicInc((int&)value);
- }
- asDWORD asCAtomic::atomicDec()
- {
- // A very high ref count is highly unlikely. It most likely a problem with
- // memory that has been overwritten or is being accessed after it was deleted.
- asASSERT(value < 1000000);
- return asAtomicDec((int&)value);
- }
- //
- // The following code implements the atomicInc and atomicDec on different platforms
- //
- #if defined(AS_NO_THREADS) || defined(AS_NO_ATOMIC)
- int asAtomicInc(int &value)
- {
- return ++value;
- }
- int asAtomicDec(int &value)
- {
- return --value;
- }
- #elif defined(AS_XENON) /// XBox360
- END_AS_NAMESPACE
- #include <xtl.h>
- BEGIN_AS_NAMESPACE
- int asAtomicInc(int &value)
- {
- return InterlockedIncrement((LONG*)&value);
- }
- int asAtomicDec(int &value)
- {
- return InterlockedDecrement((LONG*)&value);
- }
- #elif defined(AS_WIN)
- END_AS_NAMESPACE
- #define WIN32_MEAN_AND_LEAN
- #include <windows.h>
- BEGIN_AS_NAMESPACE
- int asAtomicInc(int &value)
- {
- return InterlockedIncrement((LONG*)&value);
- }
- int asAtomicDec(int &value)
- {
- asASSERT(value > 0);
- return InterlockedDecrement((LONG*)&value);
- }
- #elif defined(AS_LINUX) || defined(AS_BSD) || defined(AS_ILLUMOS) || defined(AS_ANDROID)
- //
- // atomic_inc_and_test() and atomic_dec_and_test() from asm/atomic.h is not meant
- // to be used outside the Linux kernel. Instead we should use the GNUC provided
- // __sync_add_and_fetch() and __sync_sub_and_fetch() functions.
- //
- // Reference: http://golubenco.org/blog/atomic-operations/
- //
- // These are only available in GCC 4.1 and above, so for older versions we
- // use the critical sections, though it is a lot slower.
- //
- int asAtomicInc(int &value)
- {
- return __sync_add_and_fetch(&value, 1);
- }
- int asAtomicDec(int &value)
- {
- return __sync_sub_and_fetch(&value, 1);
- }
- #elif defined(AS_MAC) || defined(AS_IPHONE)
- END_AS_NAMESPACE
- #include <libkern/OSAtomic.h>
- BEGIN_AS_NAMESPACE
- int asAtomicInc(int &value)
- {
- return OSAtomicIncrement32((int32_t*)&value);
- }
- int asAtomicDec(int &value)
- {
- return OSAtomicDecrement32((int32_t*)&value);
- }
- #else
- // If we get here, then the configuration in as_config.h
- // is wrong for the compiler/platform combination.
- int ERROR_PleaseFixTheConfig[-1];
- #endif
- END_AS_NAMESPACE
|