summaryrefslogtreecommitdiffstats
path: root/3rdparty/openpgm-svn-r1085/pgm/include/pgm/atomic.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/openpgm-svn-r1085/pgm/include/pgm/atomic.h')
-rw-r--r--3rdparty/openpgm-svn-r1085/pgm/include/pgm/atomic.h140
1 files changed, 140 insertions, 0 deletions
diff --git a/3rdparty/openpgm-svn-r1085/pgm/include/pgm/atomic.h b/3rdparty/openpgm-svn-r1085/pgm/include/pgm/atomic.h
new file mode 100644
index 0000000..15a5272
--- /dev/null
+++ b/3rdparty/openpgm-svn-r1085/pgm/include/pgm/atomic.h
@@ -0,0 +1,140 @@
+/* vim:ts=8:sts=8:sw=4:noai:noexpandtab
+ *
+ * 32-bit atomic operations.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * 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 GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __PGM_ATOMIC_H__
+#define __PGM_ATOMIC_H__
+
+#ifdef sun
+# include <atomic.h>
+#endif
+#include <pgm/types.h>
+
+static inline
+uint32_t
+pgm_atomic_exchange_and_add32 (
+ volatile uint32_t* atomic,
+ const uint32_t val
+ )
+{
+#if defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
+ uint32_t result;
+ asm volatile ( "lock\n\t"
+ "xaddl %0, %1"
+ : "=r" (result), "=m" (*atomic)
+ : "0" (val), "m" (*atomic)
+ : "memory", "cc" );
+ return result;
+#elif defined( __SUNPRO_C ) && (defined( __i386 ) || defined( __amd64 ))
+ uint32_t result = val;
+ asm volatile ( "lock\n\t"
+ "xaddl %0, %1"
+ :: "r" (result), "m" (*atomic) );
+ return result;
+#elif defined( sun )
+ const uint32_t nv = atomic_add_32_nv (atomic, (int32_t)val);
+ return nv - val;
+#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+ return __sync_fetch_and_add (atomic, val);
+#elif defined( _WIN32 )
+ return InterlockedExchangeAdd ((volatile LONG*)atomic, val);
+#else
+# error "No supported atomic operations for this platform."
+#endif
+}
+
+static inline
+void
+pgm_atomic_add32 (
+ volatile uint32_t* atomic,
+ const uint32_t val
+ )
+{
+#if defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
+ asm volatile ( "lock\n\t"
+ "addl %1, %0"
+ : "=m" (*atomic)
+ : "ir" (val), "m" (*atomic)
+ : "memory", "cc" );
+#elif defined( __SUNPRO_C ) && (defined( __i386 ) || defined( __amd64 ))
+ asm volatile ( "lock\n\t"
+ "addl %1, %0"
+ :: "r" (val), "m" (*atomic) );
+#elif defined( sun )
+ atomic_add_32 (atomic, (int32_t)val);
+#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+ __sync_fetch_and_add (atomic, val);
+#elif defined( _WIN32 )
+ InterlockedExchangeAdd ((volatile LONG*)atomic, val);
+#endif
+}
+
+static inline
+void
+pgm_atomic_inc32 (
+ volatile uint32_t* atomic
+ )
+{
+#if (defined( __GNUC__ ) && (defined( __i386__ ) || defined( __x86_64__ ))) || (defined( __SUNPRO_C ) && (defined( __i386 ) || defined( __amd64 )))
+ pgm_atomic_add32 (atomic, 1);
+#elif defined( sun )
+ atomic_inc_32 (atomic);
+#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+ pgm_atomic_add32 (atomic, 1);
+#elif defined( _WIN32 )
+ InterlockedIncrement ((volatile LONG*)atomic);
+#endif
+}
+
+static inline
+void
+pgm_atomic_dec32 (
+ volatile uint32_t* atomic
+ )
+{
+#if (defined( __GNUC__ ) && (defined( __i386__ ) || defined( __x86_64__ ))) || (defined( __SUNPRO_C ) && (defined( __i386 ) || defined( __amd64 )))
+ pgm_atomic_add32 (atomic, (uint32_t)-1);
+#elif defined( sun )
+ atomic_dec_32 (atomic);
+#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+ pgm_atomic_add32 (atomic, (uint32_t)-1);
+#elif defined( _WIN32 )
+ InterlockedDecrement ((volatile LONG*)atomic);
+#endif
+}
+
+static inline
+uint32_t
+pgm_atomic_read32 (
+ const volatile uint32_t* atomic
+ )
+{
+ return *atomic;
+}
+
+static inline
+void
+pgm_atomic_write32 (
+ volatile uint32_t* atomic,
+ const uint32_t val
+ )
+{
+ *atomic = val;
+}
+
+#endif /* __PGM_ATOMIC_H__ */