Moved __ASM_GLOBAL_FUNC macros and interlocked functions to port.[ch]
diff --git a/library/port.c b/library/port.c
index 9d46554..64f8149 100644
--- a/library/port.c
+++ b/library/port.c
@@ -738,3 +738,103 @@
return buff;
}
#endif /* HAVE_ECVT */
+
+
+/***********************************************************************
+ * interlocked functions
+ */
+#ifdef __i386__
+
+__ASM_GLOBAL_FUNC(interlocked_cmpxchg,
+ "movl 12(%esp),%eax\n\t"
+ "movl 8(%esp),%ecx\n\t"
+ "movl 4(%esp),%edx\n\t"
+ "lock; cmpxchgl %ecx,(%edx)\n\t"
+ "ret");
+__ASM_GLOBAL_FUNC(interlocked_cmpxchg_ptr,
+ "movl 12(%esp),%eax\n\t"
+ "movl 8(%esp),%ecx\n\t"
+ "movl 4(%esp),%edx\n\t"
+ "lock; cmpxchgl %ecx,(%edx)\n\t"
+ "ret");
+__ASM_GLOBAL_FUNC(interlocked_xchg,
+ "movl 8(%esp),%eax\n\t"
+ "movl 4(%esp),%edx\n\t"
+ "lock; xchgl %eax,(%edx)\n\t"
+ "ret");
+__ASM_GLOBAL_FUNC(interlocked_xchg_ptr,
+ "movl 8(%esp),%eax\n\t"
+ "movl 4(%esp),%edx\n\t"
+ "lock; xchgl %eax,(%edx)\n\t"
+ "ret");
+__ASM_GLOBAL_FUNC(interlocked_xchg_add,
+ "movl 8(%esp),%eax\n\t"
+ "movl 4(%esp),%edx\n\t"
+ "lock; xaddl %eax,(%edx)\n\t"
+ "ret");
+
+#elif defined(__sparc__) && defined(__sun__)
+
+/*
+ * As the earlier Sparc processors lack necessary atomic instructions,
+ * I'm simply falling back to the library-provided _lwp_mutex routines
+ * to ensure mutual exclusion in a way appropriate for the current
+ * architecture.
+ *
+ * FIXME: If we have the compare-and-swap instruction (Sparc v9 and above)
+ * we could use this to speed up the Interlocked operations ...
+ */
+#include <synch.h>
+static lwp_mutex_t interlocked_mutex = DEFAULTMUTEX;
+
+long interlocked_cmpxchg( long *dest, long xchg, long compare )
+{
+ _lwp_mutex_lock( &interlocked_mutex );
+ if (*dest == compare) *dest = xchg;
+ else compare = *dest;
+ _lwp_mutex_unlock( &interlocked_mutex );
+ return compare;
+}
+
+void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare )
+{
+ _lwp_mutex_lock( &interlocked_mutex );
+ if (*dest == compare) *dest = xchg;
+ else compare = *dest;
+ _lwp_mutex_unlock( &interlocked_mutex );
+ return compare;
+}
+
+long interlocked_xchg( long *dest, long val )
+{
+ long retv;
+ _lwp_mutex_lock( &interlocked_mutex );
+ retv = *dest;
+ *dest = val;
+ _lwp_mutex_unlock( &interlocked_mutex );
+ return retv;
+}
+
+void *interlocked_xchg_ptr( void **dest, void *val )
+{
+ long retv;
+ _lwp_mutex_lock( &interlocked_mutex );
+ retv = *dest;
+ *dest = val;
+ _lwp_mutex_unlock( &interlocked_mutex );
+ return retv;
+}
+
+long interlocked_xchg_add( long *dest, long incr )
+{
+ long retv;
+ _lwp_mutex_lock( &interlocked_mutex );
+ retv = *dest;
+ *dest += incr;
+ _lwp_mutex_unlock( &interlocked_mutex );
+ return retv;
+}
+
+#else
+# error You must implement the interlocked* functions for your CPU
+#endif