diff -Naur glib-2.6.1/configure.in glib-2.6.1-atomic/configure.in
--- glib-2.6.1/configure.in	2005-01-06 20:15:48.000000000 +0100
+++ glib-2.6.1-atomic/configure.in	2005-01-27 11:41:34.000000000 +0100
@@ -2734,6 +2734,7 @@
 docs/reference/gobject/version.xml
 tests/Makefile
 tests/gobject/Makefile
+tests/refcount/Makefile
 m4macros/Makefile
 ])
 
diff -Naur glib-2.6.1/glib/Makefile.am glib-2.6.1-atomic/glib/Makefile.am
--- glib-2.6.1/glib/Makefile.am	2005-01-06 20:15:48.000000000 +0100
+++ glib-2.6.1-atomic/glib/Makefile.am	2005-01-27 18:26:14.000000000 +0100
@@ -131,6 +131,7 @@
 	garray.h	\
 	gasyncqueue.h	\
 	gatomic.h	\
+	gatomic_impl.h	\
 	gbacktrace.h	\
 	gcache.h	\
 	gcompletion.h	\
diff -Naur glib-2.6.1/glib/gasyncqueue.c glib-2.6.1-atomic/glib/gasyncqueue.c
--- glib-2.6.1/glib/gasyncqueue.c	2004-11-08 19:49:35.000000000 +0100
+++ glib-2.6.1-atomic/glib/gasyncqueue.c	2005-01-27 18:01:08.000000000 +0100
@@ -28,6 +28,7 @@
 
 #include "galias.h"
 #include "glib.h"
+#include "gatomic_impl.h"
 
 
 struct _GAsyncQueue
diff -Naur glib-2.6.1/glib/gatomic.c glib-2.6.1-atomic/glib/gatomic.c
--- glib-2.6.1/glib/gatomic.c	2004-10-24 03:37:42.000000000 +0200
+++ glib-2.6.1-atomic/glib/gatomic.c	2005-01-27 17:53:12.000000000 +0100
@@ -26,623 +26,7 @@
 #include "glib.h"
 #include "gthreadinit.h"
 
-#if defined (__GNUC__)
-# if defined (G_ATOMIC_I486)
-/* Adapted from CVS version 1.10 of glibc's sysdeps/i386/i486/bits/atomic.h 
- */
-gint
-g_atomic_int_exchange_and_add (gint *atomic, 
-			       gint val)
-{
-  gint result;
+#define G_IMPLEMENT_ATOMIC 1
 
-  __asm__ __volatile__ ("lock; xaddl %0,%1"
-                        : "=r" (result), "=m" (*atomic) 
-			: "0" (val), "m" (*atomic));
-  return result;
-}
- 
-void
-g_atomic_int_add (gint *atomic, 
-		  gint val)
-{
-  __asm__ __volatile__ ("lock; addl %1,%0"
-			: "=m" (*atomic) 
-			: "ir" (val), "m" (*atomic));
-}
+#include "gatomic_impl.h"
 
-gboolean
-g_atomic_int_compare_and_exchange (gint *atomic, 
-				   gint oldval, 
-				   gint newval)
-{
-  gint result;
- 
-  __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
-			: "=a" (result), "=m" (*atomic)
-			: "r" (newval), "m" (*atomic), "0" (oldval)); 
-
-  return result == oldval;
-}
-
-/* The same code as above, as on i386 gpointer is 32 bit as well.
- * Duplicating the code here seems more natural than casting the
- * arguments and calling the former function */
-
-gboolean
-g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
-				       gpointer  oldval, 
-				       gpointer  newval)
-{
-  gpointer result;
- 
-  __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
-			: "=a" (result), "=m" (*atomic)
-			: "r" (newval), "m" (*atomic), "0" (oldval)); 
-
-  return result == oldval;
-}
-
-# elif defined (G_ATOMIC_SPARCV9)
-/* Adapted from CVS version 1.3 of glibc's sysdeps/sparc/sparc64/bits/atomic.h
- */
-#  define ATOMIC_INT_CMP_XCHG(atomic, oldval, newval)			\
-  ({ 									\
-     gint __result;							\
-     __asm__ __volatile__ ("cas [%4], %2, %0"				\
-                           : "=r" (__result), "=m" (*(atomic))		\
-                           : "r" (oldval), "m" (*(atomic)), "r" (atomic),\
-                           "0" (newval));				\
-     __result == oldval;						\
-  })
-
-#  if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
-gboolean
-g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
-				       gpointer  oldval, 
-				       gpointer  newval)
-{
-  gpointer result;
-  __asm__ __volatile__ ("cas [%4], %2, %0"
-			: "=r" (result), "=m" (*atomic)
-			: "r" (oldval), "m" (*atomic), "r" (atomic),
-			"0" (newval));
-  return result == oldval;
-}
-#  elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
-gboolean
-g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
-				       gpointer  oldval, 
-				       gpointer  newval)
-{
-  gpointer result;
-  gpointer *a = atomic;
-  __asm__ __volatile__ ("casx [%4], %2, %0"
-			: "=r" (result), "=m" (*a)
-			: "r" (oldval), "m" (*a), "r" (a),
-			"0" (newval));
-  return result != 0;
-}
-#  else /* What's that */
-#    error "Your system has an unsupported pointer size"
-#  endif /* GLIB_SIZEOF_VOID_P */
-#  define G_ATOMIC_MEMORY_BARRIER					\
-  __asm__ __volatile__ ("membar #LoadLoad | #LoadStore"			\
-                        " | #StoreLoad | #StoreStore" : : : "memory")
-
-# elif defined (G_ATOMIC_ALPHA)
-/* Adapted from CVS version 1.3 of glibc's sysdeps/alpha/bits/atomic.h
- */
-#  define ATOMIC_INT_CMP_XCHG(atomic, oldval, newval)			\
-  ({ 									\
-     gint __result;							\
-     gint __prev;							\
-     __asm__ __volatile__ (						\
-        "       mb\n"							\
-        "1:     ldl_l   %0,%2\n"					\
-        "       cmpeq   %0,%3,%1\n"					\
-        "       beq     %1,2f\n"					\
-        "       mov     %4,%1\n"					\
-        "       stl_c   %1,%2\n"					\
-        "       beq     %1,1b\n"					\
-        "       mb\n"							\
-        "2:"								\
-        : "=&r" (__prev), 						\
-          "=&r" (__result)						\
-        : "m" (*(atomic)),						\
-          "Ir" (oldval),						\
-          "Ir" (newval)							\
-        : "memory");							\
-     __result != 0;							\
-  })
-#  if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
-gboolean
-g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
-				       gpointer  oldval, 
-				       gpointer  newval)
-{
-  gint result;
-  gpointer prev;
-  __asm__ __volatile__ (
-        "       mb\n"
-        "1:     ldl_l   %0,%2\n"
-        "       cmpeq   %0,%3,%1\n"
-        "       beq     %1,2f\n"
-        "       mov     %4,%1\n"
-        "       stl_c   %1,%2\n"
-        "       beq     %1,1b\n"
-        "       mb\n"
-        "2:"
-        : "=&r" (prev), 
-          "=&r" (result)
-        : "m" (*atomic),
-          "Ir" (oldval),
-          "Ir" (newval)
-        : "memory");
-  return result != 0;
-}
-#  elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
-gboolean
-g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
-				       gpointer  oldval, 
-				       gpointer  newval)
-{
-  gint result;
-  gpointer prev;
-  __asm__ __volatile__ (
-        "       mb\n"
-        "1:     ldq_l   %0,%2\n"
-        "       cmpeq   %0,%3,%1\n"
-        "       beq     %1,2f\n"
-        "       mov     %4,%1\n"
-        "       stq_c   %1,%2\n"
-        "       beq     %1,1b\n"
-        "       mb\n"
-        "2:"
-        : "=&r" (prev), 
-          "=&r" (result)
-        : "m" (*atomic),
-          "Ir" (oldval),
-          "Ir" (newval)
-        : "memory");
-  return result != 0;
-}
-#  else /* What's that */
-#   error "Your system has an unsupported pointer size"
-#  endif /* GLIB_SIZEOF_VOID_P */
-#  define G_ATOMIC_MEMORY_BARRIER  __asm__ ("mb" : : : "memory")
-# elif defined (G_ATOMIC_X86_64)
-/* Adapted from CVS version 1.9 of glibc's sysdeps/x86_64/bits/atomic.h 
- */
-gint
-g_atomic_int_exchange_and_add (gint *atomic, 
-			       gint val)
-{
-  gint result;
-
-  __asm__ __volatile__ ("lock; xaddl %0,%1"
-                        : "=r" (result), "=m" (*atomic) 
-			: "0" (val), "m" (*atomic));
-  return result;
-}
- 
-void
-g_atomic_int_add (gint *atomic, 
-		  gint val)
-{
-  __asm__ __volatile__ ("lock; addl %1,%0"
-			: "=m" (*atomic) 
-			: "ir" (val), "m" (*atomic));
-}
-
-gboolean
-g_atomic_int_compare_and_exchange (gint *atomic, 
-				   gint oldval, 
-				   gint newval)
-{
-  gint result;
- 
-  __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
-			: "=a" (result), "=m" (*atomic)
-			: "r" (newval), "m" (*atomic), "0" (oldval)); 
-
-  return result == oldval;
-}
-
-gboolean
-g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
-				       gpointer  oldval, 
-				       gpointer  newval)
-{
-  gpointer result;
- 
-  __asm__ __volatile__ ("lock; cmpxchgq %q2, %1"
-			: "=a" (result), "=m" (*atomic)
-			: "r" (newval), "m" (*atomic), "0" (oldval)); 
-
-  return result == oldval;
-}
-
-# elif defined (G_ATOMIC_POWERPC)
-/* Adapted from CVS version 1.12 of glibc's sysdeps/powerpc/bits/atomic.h 
- * and CVS version 1.3 of glibc's sysdeps/powerpc/powerpc32/bits/atomic.h 
- * and CVS version 1.2 of glibc's sysdeps/powerpc/powerpc64/bits/atomic.h 
- */
-#   ifdef __OPTIMIZE__
-/* Non-optimizing compile bails on the following two asm statements
- * for reasons unknown to the author */
-gint
-g_atomic_int_exchange_and_add (gint *atomic, 
-			       gint val)
-{
-  gint result, temp;
-  __asm__ __volatile__ ("1:       lwarx   %0,0,%3\n"
-			"         add     %1,%0,%4\n"
-			"         stwcx.  %1,0,%3\n"
-			"         bne-    1b"
-			: "=&b" (result), "=&r" (temp), "=m" (*atomic)
-			: "b" (atomic), "r" (val), "2" (*atomic)
-			: "cr0", "memory");
-  return result;
-}
- 
-/* The same as above, to save a function call repeated here */
-void
-g_atomic_int_add (gint *atomic, 
-		  gint val)
-{
-  gint result, temp;  
-  __asm__ __volatile__ ("1:       lwarx   %0,0,%3\n"
-			"         add     %1,%0,%4\n"
-			"         stwcx.  %1,0,%3\n"
-			"         bne-    1b"
-			: "=&b" (result), "=&r" (temp), "=m" (*atomic)
-			: "b" (atomic), "r" (val), "2" (*atomic)
-			: "cr0", "memory");
-}
-#   else /* !__OPTIMIZE__ */
-gint
-g_atomic_int_exchange_and_add (gint *atomic, 
-			       gint val)
-{
-  gint result;
-  do
-    result = *atomic;
-  while (!g_atomic_int_compare_and_exchange (atomic, result, result + val));
-
-  return result;
-}
- 
-void
-g_atomic_int_add (gint *atomic, 
-		  gint val)
-{
-  gint result;
-  do
-    result = *atomic;
-  while (!g_atomic_int_compare_and_exchange (atomic, result, result + val));
-}
-#   endif /* !__OPTIMIZE__ */
-
-#   if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
-gboolean
-g_atomic_int_compare_and_exchange (gint *atomic, 
-				   gint oldval, 
-				   gint newval)
-{
-  gint result;
-  __asm__ __volatile__ ("sync\n"
-			"1: lwarx   %0,0,%1\n"
-			"   subf.   %0,%2,%0\n"
-			"   bne     2f\n"
-			"   stwcx.  %3,0,%1\n"
-			"   bne-    1b\n"
-			"2: isync"
-			: "=&r" (result)
-			: "b" (atomic), "r" (oldval), "r" (newval)
-			: "cr0", "memory"); 
-  return result == 0;
-}
-
-gboolean
-g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
-				       gpointer  oldval, 
-				       gpointer  newval)
-{
-  gpointer result;
-  __asm__ __volatile__ ("sync\n"
-			"1: lwarx   %0,0,%1\n"
-			"   subf.   %0,%2,%0\n"
-			"   bne     2f\n"
-			"   stwcx.  %3,0,%1\n"
-			"   bne-    1b\n"
-			"2: isync"
-			: "=&r" (result)
-			: "b" (atomic), "r" (oldval), "r" (newval)
-			: "cr0", "memory"); 
-  return result == 0;
-}
-#   elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
-gboolean
-g_atomic_int_compare_and_exchange (gint *atomic, 
-				   gint oldval, 
-				   gint newval)
-{
-  gpointer result;
-  __asm__ __volatile__ ("sync\n"
-			"1: lwarx   %0,0,%1\n"
-			"   extsw   %0,%0\n"
-			"   subf.   %0,%2,%0\n"
-			"   bne     2f\n"
-			"   stwcx.  %3,0,%1\n"
-			"   bne-    1b\n"
-			"2: isync"
-			: "=&r" (result)
-			: "b" (atomic), "r" (oldval), "r" (newval)
-			: "cr0", "memory"); 
-  return result == 0;
-}
-
-gboolean
-g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
-				       gpointer  oldval, 
-				       gpointer  newval)
-{
-  gpointer result;
-  __asm__ __volatile__ ("sync\n"
-			"1: ldarx   %0,0,%1\n"
-			"   subf.   %0,%2,%0\n"
-			"   bne     2f\n"
-			"   stdcx.  %3,0,%1\n"
-			"   bne-    1b\n"
-			"2: isync"
-			: "=&r" (result)
-			: "b" (atomic), "r" (oldval), "r" (newval)
-			: "cr0", "memory"); 
-  return result == 0;
-}
-#  else /* What's that */
-#   error "Your system has an unsupported pointer size"
-#  endif /* GLIB_SIZEOF_VOID_P */
-
-#  define G_ATOMIC_MEMORY_BARRIER __asm__ ("sync" : : : "memory")
-
-# elif defined (G_ATOMIC_IA64)
-/* Adapted from CVS version 1.8 of glibc's sysdeps/ia64/bits/atomic.h
- */
-gint
-g_atomic_int_exchange_and_add (gint *atomic, 
-			       gint val)
-{
-  return __sync_fetch_and_add_si (atomic, val);
-}
- 
-void
-g_atomic_int_add (gint *atomic, 
-		  gint val)
-{
-  __sync_fetch_and_add_si (atomic, val);
-}
-
-gboolean
-g_atomic_int_compare_and_exchange (gint *atomic, 
-				   gint oldval, 
-				   gint newval)
-{
-  return __sync_bool_compare_and_swap_si (atomic, oldval, newval);
-}
-
-gboolean
-g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
-				       gpointer  oldval, 
-				       gpointer  newval)
-{
-  return __sync_bool_compare_and_swap_di ((long *)atomic, 
-					  (long)oldval, (long)newval);
-}
-
-#  define G_ATOMIC_MEMORY_BARRIER __sync_synchronize ()
-# else /* !G_ATOMIC */
-#  define DEFINE_WITH_MUTEXES
-# endif /* G_ATOMIC */
-#else /* !__GNUC__ */
-# ifdef G_PLATFORM_WIN32
-#  define DEFINE_WITH_WIN32_INTERLOCKED
-# else
-#  define DEFINE_WITH_MUTEXES
-# endif
-#endif /* __GNUC__ */
-
-#ifdef DEFINE_WITH_WIN32_INTERLOCKED
-# include <windows.h>
-gint32   
-g_atomic_int_exchange_and_add (gint32   *atomic, 
-			       gint32    val)
-{
-  return InterlockedExchangeAdd (atomic, val);
-}
-
-void     
-g_atomic_int_add (gint32   *atomic, 
-		  gint32    val)
-{
-  InterlockedExchangeAdd (atomic, val);
-}
-
-gboolean 
-g_atomic_int_compare_and_exchange (gint32   *atomic, 
-				   gint32    oldval, 
-				   gint32    newval)
-{
-  return (guint32)InterlockedCompareExchange ((PVOID*)atomic, 
-                                              (PVOID)newval, 
-                                              (PVOID)oldval) == oldval;
-}
-
-gboolean 
-g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
-				       gpointer  oldval, 
-				       gpointer  newval)
-{
-# if GLIB_SIZEOF_VOID_P != 4 /* no 32-bit system */
-#  error "InterlockedCompareExchangePointer needed"
-# else
-   return InterlockedCompareExchange (atomic, newval, oldval) == oldval;
-# endif
-}
-#endif /* DEFINE_WITH_WIN32_INTERLOCKED */
-
-#ifdef DEFINE_WITH_MUTEXES
-/* We have to use the slow, but safe locking method */
-static GMutex *g_atomic_mutex; 
-
-gint
-g_atomic_int_exchange_and_add (gint *atomic, 
-			       gint  val)
-{
-  gint result;
-    
-  g_mutex_lock (g_atomic_mutex);
-  result = *atomic;
-  *atomic += val;
-  g_mutex_unlock (g_atomic_mutex);
-
-  return result;
-}
-
-
-void
-g_atomic_int_add (gint *atomic,
-		  gint  val)
-{
-  g_mutex_lock (g_atomic_mutex);
-  *atomic += val;
-  g_mutex_unlock (g_atomic_mutex);
-}
-
-gboolean
-g_atomic_int_compare_and_exchange (gint *atomic, 
-				   gint  oldval, 
-				   gint  newval)
-{
-  gboolean result;
-    
-  g_mutex_lock (g_atomic_mutex);
-  if (*atomic == oldval)
-    {
-      result = TRUE;
-      *atomic = newval;
-    }
-  else
-    result = FALSE;
-  g_mutex_unlock (g_atomic_mutex);
-
-  return result;
-}
-
-gboolean
-g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
-				       gpointer  oldval, 
-				       gpointer  newval)
-{
-  gboolean result;
-    
-  g_mutex_lock (g_atomic_mutex);
-  if (*atomic == oldval)
-    {
-      result = TRUE;
-      *atomic = newval;
-    }
-  else
-    result = FALSE;
-  g_mutex_unlock (g_atomic_mutex);
-
-  return result;
-}
-
-#ifdef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED
-gint
-g_atomic_int_get (gint *atomic)
-{
-  gint result;
-
-  g_mutex_lock (g_atomic_mutex);
-  result = *atomic;
-  g_mutex_unlock (g_atomic_mutex);
-
-  return result;
-}
-
-gpointer
-g_atomic_pointer_get (gpointer *atomic)
-{
-  gpointer result;
-
-  g_mutex_lock (g_atomic_mutex);
-  result = *atomic;
-  g_mutex_unlock (g_atomic_mutex);
-
-  return result;
-}
-#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */   
-#elif defined (G_ATOMIC_OP_MEMORY_BARRIER_NEEDED)
-gint
-g_atomic_int_get (gint *atomic)
-{
-  gint result = *atomic;
-
-  G_ATOMIC_MEMORY_BARRIER;
-
-  return result;
-}
-
-gpointer
-g_atomic_pointer_get (gpointer *atomic)
-{
-  gpointer result = *atomic;
-
-  G_ATOMIC_MEMORY_BARRIER;
-
-  return result;
-}   
-#endif /* DEFINE_WITH_MUTEXES || G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
-
-#ifdef ATOMIC_INT_CMP_XCHG
-gboolean
-g_atomic_int_compare_and_exchange (gint *atomic, 
-				   gint oldval, 
-				   gint newval)
-{
-  return ATOMIC_INT_CMP_XCHG (atomic, oldval, newval);
-}
-
-gint
-g_atomic_int_exchange_and_add (gint *atomic, 
-			       gint val)
-{
-  gint result;
-  do
-    result = *atomic;
-  while (!ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
-
-  return result;
-}
- 
-void
-g_atomic_int_add (gint *atomic, 
-		  gint val)
-{
-  gint result;
-  do
-    result = *atomic;
-  while (!ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
-}
-#endif /* ATOMIC_INT_CMP_XCHG */
-
-void 
-_g_atomic_thread_init (void)
-{
-#ifdef DEFINE_WITH_MUTEXES
-  g_atomic_mutex = g_mutex_new ();
-#endif /* DEFINE_WITH_MUTEXES */
-}
diff -Naur glib-2.6.1/glib/gatomic_impl.h glib-2.6.1-atomic/glib/gatomic_impl.h
--- glib-2.6.1/glib/gatomic_impl.h	1970-01-01 01:00:00.000000000 +0100
+++ glib-2.6.1-atomic/glib/gatomic_impl.h	2005-01-27 17:59:23.000000000 +0100
@@ -0,0 +1,672 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * g_atomic_*: atomic operations.
+ * Copyright (C) 2003 Sebastian Wilhelmi
+ *
+ * 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 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 __G_ATOMIC_IMPL_H__
+#define __G_ATOMIC_IMPL_H__
+
+#include "config.h"
+
+#if defined (G_HAVE_INLINE) && defined (__GNUC__) && defined (__STRICT_ANSI__)
+#  undef inline
+#  define inline __inline__
+#elif !defined (G_HAVE_INLINE)
+#  undef inline
+#  if defined (G_HAVE___INLINE__)
+#    define inline __inline__
+#  elif defined (G_HAVE___INLINE)
+#    define inline __inline
+#  else /* !inline && !__inline__ && !__inline */
+#    define inline  /* don't inline, then */
+#  endif
+#endif
+#ifdef G_IMPLEMENT_ATOMIC
+#  define G_ATOMIC_FUNC
+#elif defined (__GNUC__)
+#  define G_ATOMIC_FUNC extern inline
+#elif defined (G_CAN_INLINE)
+#  define G_ATOMIC_FUNC static inline
+#else /* can't inline */
+#  define G_ATOMIC_FUNC
+#endif /* !G_ATOMIC_FUNC */
+
+
+#if defined (__GNUC__)
+# if defined (G_ATOMIC_I486)
+/* Adapted from CVS version 1.10 of glibc's sysdeps/i386/i486/bits/atomic.h 
+ */
+G_ATOMIC_FUNC gint
+g_atomic_int_exchange_and_add (gint *atomic, 
+			       gint val)
+{
+  gint result;
+
+  __asm__ __volatile__ ("lock; xaddl %0,%1"
+                        : "=r" (result), "=m" (*atomic) 
+			: "0" (val), "m" (*atomic));
+  return result;
+}
+ 
+G_ATOMIC_FUNC void
+g_atomic_int_add (gint *atomic, 
+		  gint val)
+{
+  __asm__ __volatile__ ("lock; addl %1,%0"
+			: "=m" (*atomic) 
+			: "ir" (val), "m" (*atomic));
+}
+
+G_ATOMIC_FUNC gboolean
+g_atomic_int_compare_and_exchange (gint *atomic, 
+				   gint oldval, 
+				   gint newval)
+{
+  gint result;
+ 
+  __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+			: "=a" (result), "=m" (*atomic)
+			: "r" (newval), "m" (*atomic), "0" (oldval)); 
+
+  return result == oldval;
+}
+
+/* The same code as above, as on i386 gpointer is 32 bit as well.
+ * Duplicating the code here seems more natural than casting the
+ * arguments and calling the former function */
+
+G_ATOMIC_FUNC gboolean
+g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
+				       gpointer  oldval, 
+				       gpointer  newval)
+{
+  gpointer result;
+ 
+  __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+			: "=a" (result), "=m" (*atomic)
+			: "r" (newval), "m" (*atomic), "0" (oldval)); 
+
+  return result == oldval;
+}
+
+# elif defined (G_ATOMIC_SPARCV9)
+/* Adapted from CVS version 1.3 of glibc's sysdeps/sparc/sparc64/bits/atomic.h
+ */
+#  define ATOMIC_INT_CMP_XCHG(atomic, oldval, newval)			\
+  ({ 									\
+     gint __result;							\
+     __asm__ __volatile__ ("cas [%4], %2, %0"				\
+                           : "=r" (__result), "=m" (*(atomic))		\
+                           : "r" (oldval), "m" (*(atomic)), "r" (atomic),\
+                           "0" (newval));				\
+     __result == oldval;						\
+  })
+
+#  if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
+G_ATOMIC_FUNC gboolean
+g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
+				       gpointer  oldval, 
+				       gpointer  newval)
+{
+  gpointer result;
+  __asm__ __volatile__ ("cas [%4], %2, %0"
+			: "=r" (result), "=m" (*atomic)
+			: "r" (oldval), "m" (*atomic), "r" (atomic),
+			"0" (newval));
+  return result == oldval;
+}
+#  elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
+G_ATOMIC_FUNC gboolean
+g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
+				       gpointer  oldval, 
+				       gpointer  newval)
+{
+  gpointer result;
+  gpointer *a = atomic;
+  __asm__ __volatile__ ("casx [%4], %2, %0"
+			: "=r" (result), "=m" (*a)
+			: "r" (oldval), "m" (*a), "r" (a),
+			"0" (newval));
+  return result != 0;
+}
+#  else /* What's that */
+#    error "Your system has an unsupported pointer size"
+#  endif /* GLIB_SIZEOF_VOID_P */
+#  define G_ATOMIC_MEMORY_BARRIER					\
+  __asm__ __volatile__ ("membar #LoadLoad | #LoadStore"			\
+                        " | #StoreLoad | #StoreStore" : : : "memory")
+
+# elif defined (G_ATOMIC_ALPHA)
+/* Adapted from CVS version 1.3 of glibc's sysdeps/alpha/bits/atomic.h
+ */
+#  define ATOMIC_INT_CMP_XCHG(atomic, oldval, newval)			\
+  ({ 									\
+     gint __result;							\
+     gint __prev;							\
+     __asm__ __volatile__ (						\
+        "       mb\n"							\
+        "1:     ldl_l   %0,%2\n"					\
+        "       cmpeq   %0,%3,%1\n"					\
+        "       beq     %1,2f\n"					\
+        "       mov     %4,%1\n"					\
+        "       stl_c   %1,%2\n"					\
+        "       beq     %1,1b\n"					\
+        "       mb\n"							\
+        "2:"								\
+        : "=&r" (__prev), 						\
+          "=&r" (__result)						\
+        : "m" (*(atomic)),						\
+          "Ir" (oldval),						\
+          "Ir" (newval)							\
+        : "memory");							\
+     __result != 0;							\
+  })
+#  if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
+G_ATOMIC_FUNC gboolean
+g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
+				       gpointer  oldval, 
+				       gpointer  newval)
+{
+  gint result;
+  gpointer prev;
+  __asm__ __volatile__ (
+        "       mb\n"
+        "1:     ldl_l   %0,%2\n"
+        "       cmpeq   %0,%3,%1\n"
+        "       beq     %1,2f\n"
+        "       mov     %4,%1\n"
+        "       stl_c   %1,%2\n"
+        "       beq     %1,1b\n"
+        "       mb\n"
+        "2:"
+        : "=&r" (prev), 
+          "=&r" (result)
+        : "m" (*atomic),
+          "Ir" (oldval),
+          "Ir" (newval)
+        : "memory");
+  return result != 0;
+}
+#  elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
+G_ATOMIC_FUNC gboolean
+g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
+				       gpointer  oldval, 
+				       gpointer  newval)
+{
+  gint result;
+  gpointer prev;
+  __asm__ __volatile__ (
+        "       mb\n"
+        "1:     ldq_l   %0,%2\n"
+        "       cmpeq   %0,%3,%1\n"
+        "       beq     %1,2f\n"
+        "       mov     %4,%1\n"
+        "       stq_c   %1,%2\n"
+        "       beq     %1,1b\n"
+        "       mb\n"
+        "2:"
+        : "=&r" (prev), 
+          "=&r" (result)
+        : "m" (*atomic),
+          "Ir" (oldval),
+          "Ir" (newval)
+        : "memory");
+  return result != 0;
+}
+#  else /* What's that */
+#   error "Your system has an unsupported pointer size"
+#  endif /* GLIB_SIZEOF_VOID_P */
+#  define G_ATOMIC_MEMORY_BARRIER  __asm__ ("mb" : : : "memory")
+# elif defined (G_ATOMIC_X86_64)
+/* Adapted from CVS version 1.9 of glibc's sysdeps/x86_64/bits/atomic.h 
+ */
+G_ATOMIC_FUNC gint
+g_atomic_int_exchange_and_add (gint *atomic, 
+			       gint val)
+{
+  gint result;
+
+  __asm__ __volatile__ ("lock; xaddl %0,%1"
+                        : "=r" (result), "=m" (*atomic) 
+			: "0" (val), "m" (*atomic));
+  return result;
+}
+ 
+G_ATOMIC_FUNC void
+g_atomic_int_add (gint *atomic, 
+		  gint val)
+{
+  __asm__ __volatile__ ("lock; addl %1,%0"
+			: "=m" (*atomic) 
+			: "ir" (val), "m" (*atomic));
+}
+
+G_ATOMIC_FUNC gboolean
+g_atomic_int_compare_and_exchange (gint *atomic, 
+				   gint oldval, 
+				   gint newval)
+{
+  gint result;
+ 
+  __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+			: "=a" (result), "=m" (*atomic)
+			: "r" (newval), "m" (*atomic), "0" (oldval)); 
+
+  return result == oldval;
+}
+
+G_ATOMIC_FUNC gboolean
+g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
+				       gpointer  oldval, 
+				       gpointer  newval)
+{
+  gpointer result;
+ 
+  __asm__ __volatile__ ("lock; cmpxchgq %q2, %1"
+			: "=a" (result), "=m" (*atomic)
+			: "r" (newval), "m" (*atomic), "0" (oldval)); 
+
+  return result == oldval;
+}
+
+# elif defined (G_ATOMIC_POWERPC)
+/* Adapted from CVS version 1.12 of glibc's sysdeps/powerpc/bits/atomic.h 
+ * and CVS version 1.3 of glibc's sysdeps/powerpc/powerpc32/bits/atomic.h 
+ * and CVS version 1.2 of glibc's sysdeps/powerpc/powerpc64/bits/atomic.h 
+ */
+#   ifdef __OPTIMIZE__
+/* Non-optimizing compile bails on the following two asm statements
+ * for reasons unknown to the author */
+G_ATOMIC_FUNC gint
+g_atomic_int_exchange_and_add (gint *atomic, 
+			       gint val)
+{
+  gint result, temp;
+  __asm__ __volatile__ ("1:       lwarx   %0,0,%3\n"
+			"         add     %1,%0,%4\n"
+			"         stwcx.  %1,0,%3\n"
+			"         bne-    1b"
+			: "=&b" (result), "=&r" (temp), "=m" (*atomic)
+			: "b" (atomic), "r" (val), "2" (*atomic)
+			: "cr0", "memory");
+  return result;
+}
+ 
+/* The same as above, to save a function call repeated here */
+G_ATOMIC_FUNC void
+g_atomic_int_add (gint *atomic, 
+		  gint val)
+{
+  gint result, temp;  
+  __asm__ __volatile__ ("1:       lwarx   %0,0,%3\n"
+			"         add     %1,%0,%4\n"
+			"         stwcx.  %1,0,%3\n"
+			"         bne-    1b"
+			: "=&b" (result), "=&r" (temp), "=m" (*atomic)
+			: "b" (atomic), "r" (val), "2" (*atomic)
+			: "cr0", "memory");
+}
+#   else /* !__OPTIMIZE__ */
+G_ATOMIC_FUNC gint
+g_atomic_int_exchange_and_add (gint *atomic, 
+			       gint val)
+{
+  gint result;
+  do
+    result = *atomic;
+  while (!g_atomic_int_compare_and_exchange (atomic, result, result + val));
+
+  return result;
+}
+ 
+G_ATOMIC_FUNC void
+g_atomic_int_add (gint *atomic, 
+		  gint val)
+{
+  gint result;
+  do
+    result = *atomic;
+  while (!g_atomic_int_compare_and_exchange (atomic, result, result + val));
+}
+#   endif /* !__OPTIMIZE__ */
+
+#   if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
+G_ATOMIC_FUNC gboolean
+g_atomic_int_compare_and_exchange (gint *atomic, 
+				   gint oldval, 
+				   gint newval)
+{
+  gint result;
+  __asm__ __volatile__ ("sync\n"
+			"1: lwarx   %0,0,%1\n"
+			"   subf.   %0,%2,%0\n"
+			"   bne     2f\n"
+			"   stwcx.  %3,0,%1\n"
+			"   bne-    1b\n"
+			"2: isync"
+			: "=&r" (result)
+			: "b" (atomic), "r" (oldval), "r" (newval)
+			: "cr0", "memory"); 
+  return result == 0;
+}
+
+G_ATOMIC_FUNC gboolean
+g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
+				       gpointer  oldval, 
+				       gpointer  newval)
+{
+  gpointer result;
+  __asm__ __volatile__ ("sync\n"
+			"1: lwarx   %0,0,%1\n"
+			"   subf.   %0,%2,%0\n"
+			"   bne     2f\n"
+			"   stwcx.  %3,0,%1\n"
+			"   bne-    1b\n"
+			"2: isync"
+			: "=&r" (result)
+			: "b" (atomic), "r" (oldval), "r" (newval)
+			: "cr0", "memory"); 
+  return result == 0;
+}
+#   elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
+G_ATOMIC_FUNC gboolean
+g_atomic_int_compare_and_exchange (gint *atomic, 
+				   gint oldval, 
+				   gint newval)
+{
+  gpointer result;
+  __asm__ __volatile__ ("sync\n"
+			"1: lwarx   %0,0,%1\n"
+			"   extsw   %0,%0\n"
+			"   subf.   %0,%2,%0\n"
+			"   bne     2f\n"
+			"   stwcx.  %3,0,%1\n"
+			"   bne-    1b\n"
+			"2: isync"
+			: "=&r" (result)
+			: "b" (atomic), "r" (oldval), "r" (newval)
+			: "cr0", "memory"); 
+  return result == 0;
+}
+
+G_ATOMIC_FUNC gboolean
+g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
+				       gpointer  oldval, 
+				       gpointer  newval)
+{
+  gpointer result;
+  __asm__ __volatile__ ("sync\n"
+			"1: ldarx   %0,0,%1\n"
+			"   subf.   %0,%2,%0\n"
+			"   bne     2f\n"
+			"   stdcx.  %3,0,%1\n"
+			"   bne-    1b\n"
+			"2: isync"
+			: "=&r" (result)
+			: "b" (atomic), "r" (oldval), "r" (newval)
+			: "cr0", "memory"); 
+  return result == 0;
+}
+#  else /* What's that */
+#   error "Your system has an unsupported pointer size"
+#  endif /* GLIB_SIZEOF_VOID_P */
+
+#  define G_ATOMIC_MEMORY_BARRIER __asm__ ("sync" : : : "memory")
+
+# elif defined (G_ATOMIC_IA64)
+/* Adapted from CVS version 1.8 of glibc's sysdeps/ia64/bits/atomic.h
+ */
+G_ATOMIC_FUNC gint
+g_atomic_int_exchange_and_add (gint *atomic, 
+			       gint val)
+{
+  return __sync_fetch_and_add_si (atomic, val);
+}
+ 
+G_ATOMIC_FUNC void
+g_atomic_int_add (gint *atomic, 
+		  gint val)
+{
+  __sync_fetch_and_add_si (atomic, val);
+}
+
+G_ATOMIC_FUNC gboolean
+g_atomic_int_compare_and_exchange (gint *atomic, 
+				   gint oldval, 
+				   gint newval)
+{
+  return __sync_bool_compare_and_swap_si (atomic, oldval, newval);
+}
+
+G_ATOMIC_FUNC gboolean
+g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
+				       gpointer  oldval, 
+				       gpointer  newval)
+{
+  return __sync_bool_compare_and_swap_di ((long *)atomic, 
+					  (long)oldval, (long)newval);
+}
+
+#  define G_ATOMIC_MEMORY_BARRIER __sync_synchronize ()
+# else /* !G_ATOMIC */
+#  define DEFINE_WITH_MUTEXES
+# endif /* G_ATOMIC */
+#else /* !__GNUC__ */
+# ifdef G_PLATFORM_WIN32
+#  define DEFINE_WITH_WIN32_INTERLOCKED
+# else
+#  define DEFINE_WITH_MUTEXES
+# endif
+#endif /* __GNUC__ */
+
+#ifdef DEFINE_WITH_WIN32_INTERLOCKED
+# include <windows.h>
+G_ATOMIC_FUNC gint32   
+g_atomic_int_exchange_and_add (gint32   *atomic, 
+			       gint32    val)
+{
+  return InterlockedExchangeAdd (atomic, val);
+}
+
+G_ATOMIC_FUNC void     
+g_atomic_int_add (gint32   *atomic, 
+		  gint32    val)
+{
+  InterlockedExchangeAdd (atomic, val);
+}
+
+G_ATOMIC_FUNC gboolean 
+g_atomic_int_compare_and_exchange (gint32   *atomic, 
+				   gint32    oldval, 
+				   gint32    newval)
+{
+  return (guint32)InterlockedCompareExchange ((PVOID*)atomic, 
+                                              (PVOID)newval, 
+                                              (PVOID)oldval) == oldval;
+}
+
+G_ATOMIC_FUNC gboolean 
+g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
+				       gpointer  oldval, 
+				       gpointer  newval)
+{
+# if GLIB_SIZEOF_VOID_P != 4 /* no 32-bit system */
+#  error "InterlockedCompareExchangePointer needed"
+# else
+   return InterlockedCompareExchange (atomic, newval, oldval) == oldval;
+# endif
+}
+#endif /* DEFINE_WITH_WIN32_INTERLOCKED */
+
+#ifdef DEFINE_WITH_MUTEXES
+/* We have to use the slow, but safe locking method */
+static GMutex *g_atomic_mutex; 
+
+G_ATOMIC_FUNC gint
+g_atomic_int_exchange_and_add (gint *atomic, 
+			       gint  val)
+{
+  gint result;
+    
+  g_mutex_lock (g_atomic_mutex);
+  result = *atomic;
+  *atomic += val;
+  g_mutex_unlock (g_atomic_mutex);
+
+  return result;
+}
+
+
+G_ATOMIC_FUNC void
+g_atomic_int_add (gint *atomic,
+		  gint  val)
+{
+  g_mutex_lock (g_atomic_mutex);
+  *atomic += val;
+  g_mutex_unlock (g_atomic_mutex);
+}
+
+G_ATOMIC_FUNC gboolean
+g_atomic_int_compare_and_exchange (gint *atomic, 
+				   gint  oldval, 
+				   gint  newval)
+{
+  gboolean result;
+    
+  g_mutex_lock (g_atomic_mutex);
+  if (*atomic == oldval)
+    {
+      result = TRUE;
+      *atomic = newval;
+    }
+  else
+    result = FALSE;
+  g_mutex_unlock (g_atomic_mutex);
+
+  return result;
+}
+
+G_ATOMIC_FUNC gboolean
+g_atomic_pointer_compare_and_exchange (gpointer *atomic, 
+				       gpointer  oldval, 
+				       gpointer  newval)
+{
+  gboolean result;
+    
+  g_mutex_lock (g_atomic_mutex);
+  if (*atomic == oldval)
+    {
+      result = TRUE;
+      *atomic = newval;
+    }
+  else
+    result = FALSE;
+  g_mutex_unlock (g_atomic_mutex);
+
+  return result;
+}
+
+#ifdef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED
+G_ATOMIC_FUNC gint
+g_atomic_int_get (gint *atomic)
+{
+  gint result;
+
+  g_mutex_lock (g_atomic_mutex);
+  result = *atomic;
+  g_mutex_unlock (g_atomic_mutex);
+
+  return result;
+}
+
+G_ATOMIC_FUNC gpointer
+g_atomic_pointer_get (gpointer *atomic)
+{
+  gpointer result;
+
+  g_mutex_lock (g_atomic_mutex);
+  result = *atomic;
+  g_mutex_unlock (g_atomic_mutex);
+
+  return result;
+}
+#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */   
+#elif defined (G_ATOMIC_OP_MEMORY_BARRIER_NEEDED)
+G_ATOMIC_FUNC gint
+g_atomic_int_get (gint *atomic)
+{
+  gint result = *atomic;
+
+  G_ATOMIC_MEMORY_BARRIER;
+
+  return result;
+}
+
+G_ATOMIC_FUNC gpointer
+g_atomic_pointer_get (gpointer *atomic)
+{
+  gpointer result = *atomic;
+
+  G_ATOMIC_MEMORY_BARRIER;
+
+  return result;
+}   
+#endif /* DEFINE_WITH_MUTEXES || G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
+
+#ifdef ATOMIC_INT_CMP_XCHG
+G_ATOMIC_FUNC gboolean
+g_atomic_int_compare_and_exchange (gint *atomic, 
+				   gint oldval, 
+				   gint newval)
+{
+  return ATOMIC_INT_CMP_XCHG (atomic, oldval, newval);
+}
+
+G_ATOMIC_FUNC gint
+g_atomic_int_exchange_and_add (gint *atomic, 
+			       gint val)
+{
+  gint result;
+  do
+    result = *atomic;
+  while (!ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
+
+  return result;
+}
+ 
+G_ATOMIC_FUNC void
+g_atomic_int_add (gint *atomic, 
+		  gint val)
+{
+  gint result;
+  do
+    result = *atomic;
+  while (!ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
+}
+#endif /* ATOMIC_INT_CMP_XCHG */
+
+G_ATOMIC_FUNC void 
+_g_atomic_thread_init (void)
+{
+#ifdef DEFINE_WITH_MUTEXES
+  g_atomic_mutex = g_mutex_new ();
+#endif /* DEFINE_WITH_MUTEXES */
+}
+#endif /* __G_ATOMIC_IMPL_H__ */
diff -Naur glib-2.6.1/glib/giochannel.c glib-2.6.1-atomic/glib/giochannel.c
--- glib-2.6.1/glib/giochannel.c	2004-11-08 19:49:35.000000000 +0100
+++ glib-2.6.1-atomic/glib/giochannel.c	2005-01-27 18:00:49.000000000 +0100
@@ -46,6 +46,7 @@
 #include "glib.h"
 
 #include "giochannel.h"
+#include "gatomic_impl.h"
 
 #include "glibintl.h"
 
@@ -96,7 +97,7 @@
 {
   g_return_val_if_fail (channel != NULL, NULL);
 
-  channel->ref_count++;
+  g_atomic_int_inc (&channel->ref_count);
 
   return channel;
 }
@@ -106,8 +107,7 @@
 {
   g_return_if_fail (channel != NULL);
 
-  channel->ref_count--;
-  if (channel->ref_count == 0)
+  if (G_UNLIKELY (g_atomic_int_dec_and_test (&channel->ref_count)))
     {
       if (channel->close_on_unref)
         g_io_channel_shutdown (channel, TRUE, NULL);
diff -Naur glib-2.6.1/glib/gmain.c glib-2.6.1-atomic/glib/gmain.c
--- glib-2.6.1/glib/gmain.c	2004-11-08 19:49:35.000000000 +0100
+++ glib-2.6.1-atomic/glib/gmain.c	2005-01-27 17:55:57.000000000 +0100
@@ -39,6 +39,7 @@
 #include "galias.h"
 #include "glib.h"
 #include "gthreadinit.h"
+#include "gatomic_impl.h"
 #include <signal.h>
 #include <sys/types.h>
 #include <time.h>
diff -Naur glib-2.6.1/gobject/gclosure.c glib-2.6.1-atomic/gobject/gclosure.c
--- glib-2.6.1/gobject/gclosure.c	2004-09-16 20:52:40.000000000 +0200
+++ glib-2.6.1-atomic/gobject/gclosure.c	2005-01-26 19:11:33.000000000 +0100
@@ -43,6 +43,8 @@
   POST_NOTIFY
 };
 
+G_LOCK_DEFINE_STATIC (ref_lock);
+
 
 /* --- functions --- */
 GClosure*
@@ -312,7 +314,9 @@
   g_return_val_if_fail (closure->ref_count > 0, NULL);
   g_return_val_if_fail (closure->ref_count < CLOSURE_MAX_REF_COUNT, NULL);
 
+  G_LOCK (ref_lock);
   closure->ref_count += 1;
+  G_UNLOCK (ref_lock);
 
   return closure;
 }
@@ -324,7 +328,9 @@
 
   if (!closure->is_invalid)
     {
+      G_LOCK (ref_lock);
       closure->ref_count += 1;	/* preserve floating flag */
+      G_UNLOCK (ref_lock);
       closure->is_invalid = TRUE;
       closure_invoke_notifiers (closure, INOTIFY);
       g_closure_unref (closure);
@@ -337,17 +343,27 @@
   g_return_if_fail (closure != NULL);
   g_return_if_fail (closure->ref_count > 0);
 
+  G_LOCK (ref_lock);
   if (closure->ref_count == 1)	/* last unref, invalidate first */
-    g_closure_invalidate (closure);
+    {
+      G_UNLOCK (ref_lock);
+      g_closure_invalidate (closure);
+      G_LOCK (ref_lock);
+    }
 
   closure->ref_count -= 1;
 
-  if (closure->ref_count == 0)
+  if (G_UNLIKELY(closure->ref_count == 0))
     {
+      G_UNLOCK (ref_lock);
       closure_invoke_notifiers (closure, FNOTIFY);
       g_free (closure->notifiers);
       g_free (closure);
     }
+  else
+    {
+      G_UNLOCK (ref_lock);
+    }
 }
 
 void
@@ -364,10 +380,7 @@
   if (closure->floating)
     {
       closure->floating = FALSE;
-      if (closure->ref_count > 1)
-	closure->ref_count -= 1;
-      else
-	g_closure_unref (closure);
+      g_closure_unref (closure);
     }
 }
 
@@ -420,7 +433,9 @@
 
       g_return_if_fail (closure->marshal || closure->meta_marshal);
 
+      G_LOCK (ref_lock);
       closure->ref_count += 1;	/* preserve floating flag */
+      G_UNLOCK (ref_lock);
       closure->in_marshal = TRUE;
       if (closure->meta_marshal)
 	{
diff -Naur glib-2.6.1/gobject/gobject.c glib-2.6.1-atomic/gobject/gobject.c
--- glib-2.6.1/gobject/gobject.c	2004-09-16 20:52:40.000000000 +0200
+++ glib-2.6.1-atomic/gobject/gobject.c	2005-01-27 17:26:06.000000000 +0100
@@ -31,6 +31,8 @@
 #include	<string.h>
 #include	<signal.h>
 
+#include	"gatomic_impl.h"
+
 
 #define	PREALLOC_CPARAMS	(8)
 
@@ -129,7 +131,7 @@
   g_message ("[%p] stale %s\tref_count=%u",
 	     object,
 	     G_OBJECT_TYPE_NAME (object),
-	     object->ref_count);
+	     g_atomic_int_get (&object->ref_count));
 }
 static void
 debug_objects_atexit (void)
@@ -526,7 +528,7 @@
   /* yes, temporarily altering the ref_count is hackish, but that
    * enforces people not jerking around with weak_ref notifiers
    */
-  ref_count = object->ref_count;
+  ref_count = g_atomic_int_get (&object->ref_count);
   object->ref_count = 0;
   g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
   object->ref_count = ref_count;
@@ -552,9 +554,9 @@
 static void
 g_object_last_unref (GObject *object)
 {
-  g_return_if_fail (object->ref_count > 0);
+  g_return_if_fail (g_atomic_int_get (&object->ref_count) > 0);
   
-  if (object->ref_count == 1)	/* may have been re-referenced meanwhile */
+  if (g_atomic_int_get (&object->ref_count) == 1)	/* may have been re-referenced meanwhile */
     G_OBJECT_GET_CLASS (object)->dispose (object);
   
 #ifdef	G_ENABLE_DEBUG
@@ -562,9 +564,8 @@
     G_BREAKPOINT ();
 #endif	/* G_ENABLE_DEBUG */
 
-  object->ref_count -= 1;
-  
-  if (object->ref_count == 0)	/* may have been re-referenced meanwhile */
+  /* may have been re-referenced meanwhile */
+  if (G_LIKELY (g_atomic_int_dec_and_test (&object->ref_count))) 
     {
       g_signal_handlers_destroy (object);
       g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
@@ -597,7 +598,7 @@
 g_object_run_dispose (GObject *object)
 {
   g_return_if_fail (G_IS_OBJECT (object));
-  g_return_if_fail (object->ref_count > 0);
+  g_return_if_fail (g_atomic_int_get (&object->ref_count) > 0);
 
   g_object_ref (object);
   G_OBJECT_GET_CLASS (object)->dispose (object);
@@ -608,7 +609,8 @@
 g_object_freeze_notify (GObject *object)
 {
   g_return_if_fail (G_IS_OBJECT (object));
-  if (!object->ref_count)
+
+  if (g_atomic_int_get (&object->ref_count) == 0);
     return;
 
   g_object_ref (object);
@@ -624,7 +626,8 @@
   
   g_return_if_fail (G_IS_OBJECT (object));
   g_return_if_fail (property_name != NULL);
-  if (!object->ref_count)
+
+  if (g_atomic_int_get (&object->ref_count) == 0);
     return;
   
   g_object_ref (object);
@@ -658,7 +661,8 @@
   GObjectNotifyQueue *nqueue;
   
   g_return_if_fail (G_IS_OBJECT (object));
-  if (!object->ref_count)
+
+  if (g_atomic_int_get (&object->ref_count) == 0);
     return;
   
   g_object_ref (object);
@@ -1338,7 +1342,7 @@
   va_list var_args;
 
   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
-  g_return_val_if_fail (object->ref_count > 0, object);
+  g_return_val_if_fail (g_atomic_int_get (&object->ref_count) > 0, object);
 
   va_start (var_args, signal_spec);
   while (signal_spec)
@@ -1407,7 +1411,7 @@
   va_list var_args;
 
   g_return_if_fail (G_IS_OBJECT (object));
-  g_return_if_fail (object->ref_count > 0);
+  g_return_if_fail (g_atomic_int_get (&object->ref_count) > 0);
 
   va_start (var_args, signal_spec);
   while (signal_spec)
@@ -1476,7 +1480,7 @@
   
   g_return_if_fail (G_IS_OBJECT (object));
   g_return_if_fail (notify != NULL);
-  g_return_if_fail (object->ref_count >= 1);
+  g_return_if_fail (g_atomic_int_get (&object->ref_count) >= 1);
 
   wstack = g_datalist_id_remove_no_notify (&object->qdata, quark_weak_refs);
   if (wstack)
@@ -1560,14 +1564,14 @@
   GObject *object = _object;
 
   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
-  g_return_val_if_fail (object->ref_count > 0, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&object->ref_count) > 0, NULL);
   
 #ifdef  G_ENABLE_DEBUG
   if (g_trap_object_ref == object)
     G_BREAKPOINT ();
 #endif  /* G_ENABLE_DEBUG */
 
-  object->ref_count += 1;
+  g_atomic_int_inc (&object->ref_count);
   
   return object;
 }
@@ -1578,17 +1582,19 @@
   GObject *object = _object;
 
   g_return_if_fail (G_IS_OBJECT (object));
-  g_return_if_fail (object->ref_count > 0);
+  g_return_if_fail (g_atomic_int_get (&object->ref_count) > 0);
   
 #ifdef  G_ENABLE_DEBUG
   if (g_trap_object_ref == object)
     G_BREAKPOINT ();
 #endif  /* G_ENABLE_DEBUG */
 
-  if (object->ref_count > 1)
-    object->ref_count -= 1;
-  else
-    g_object_last_unref (object);
+  if (G_UNLIKELY (g_atomic_int_dec_and_test (&object->ref_count)))
+    {
+      /* inc again for performing last_unref */
+      g_atomic_int_inc (&object->ref_count);
+      g_object_last_unref (object);
+    }
 }
 
 gpointer
@@ -1945,7 +1951,7 @@
   g_return_if_fail (closure != NULL);
   g_return_if_fail (closure->is_invalid == FALSE);
   g_return_if_fail (closure->in_marshal == FALSE);
-  g_return_if_fail (object->ref_count > 0);	/* this doesn't work on finalizing objects */
+  g_return_if_fail (g_atomic_int_get (&object->ref_count) > 0); /* this doesn't work on finalizing objects */
   
   g_closure_add_invalidate_notifier (closure, object, object_remove_closure);
   g_closure_add_marshal_guards (closure,
@@ -1975,7 +1981,7 @@
   GClosure *closure;
 
   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
-  g_return_val_if_fail (object->ref_count > 0, NULL);     /* this doesn't work on finalizing objects */
+  g_return_val_if_fail (g_atomic_int_get (&object->ref_count) > 0, NULL); /* this doesn't work on finalizing objects */
 
   closure = g_closure_new_simple (sizeof_closure, object);
   g_object_watch_closure (object, closure);
@@ -1990,7 +1996,7 @@
   GClosure *closure;
 
   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
-  g_return_val_if_fail (object->ref_count > 0, NULL);     /* this doesn't work on finalizing objects */
+  g_return_val_if_fail (g_atomic_int_get (&object->ref_count) > 0, NULL); /* this doesn't work on finalizing objects */
   g_return_val_if_fail (callback_func != NULL, NULL);
 
   closure = g_cclosure_new (callback_func, object, NULL);
@@ -2006,7 +2012,7 @@
   GClosure *closure;
 
   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
-  g_return_val_if_fail (object->ref_count > 0, NULL);     /* this doesn't work on finalizing objects */
+  g_return_val_if_fail (g_atomic_int_get (&object->ref_count) > 0, NULL); /* this doesn't work on finalizing objects */
   g_return_val_if_fail (callback_func != NULL, NULL);
 
   closure = g_cclosure_new_swap (callback_func, object, NULL);
diff -Naur glib-2.6.1/gobject/gobjectnotifyqueue.c glib-2.6.1-atomic/gobject/gobjectnotifyqueue.c
--- glib-2.6.1/gobject/gobjectnotifyqueue.c	2003-10-21 21:12:27.000000000 +0200
+++ glib-2.6.1-atomic/gobject/gobjectnotifyqueue.c	2005-01-26 17:07:37.000000000 +0100
@@ -98,7 +98,7 @@
   nqueue->freeze_count--;
   if (nqueue->freeze_count)
     return;
-  g_return_if_fail (object->ref_count > 0);
+  g_return_if_fail (g_atomic_int_get (&object->ref_count) > 0);
 
   pspecs = nqueue->n_pspecs > 16 ? free_me = g_new (GParamSpec*, nqueue->n_pspecs) : pspecs_mem;
   /* set first entry to NULL since it's checked unconditionally */
diff -Naur glib-2.6.1/gobject/gparam.c glib-2.6.1-atomic/gobject/gparam.c
--- glib-2.6.1/gobject/gparam.c	2004-09-16 20:52:40.000000000 +0200
+++ glib-2.6.1-atomic/gobject/gparam.c	2005-01-27 18:03:40.000000000 +0100
@@ -24,6 +24,7 @@
 #include	"gobjectalias.h"
 #include	"gparam.h"
 #include        "gparamspecs.h"
+#include        "gatomic_impl.h"
 
 #include	"gvaluecollector.h"
 #include	<string.h>
@@ -64,7 +65,6 @@
 
 /* --- variables --- */
 static GQuark quark_floating = 0;
-G_LOCK_DEFINE_STATIC (pspec_ref_count);
 
 
 /* --- functions --- */
@@ -164,19 +164,10 @@
 g_param_spec_ref (GParamSpec *pspec)
 {
   g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
+  g_return_val_if_fail (g_atomic_int_get (&pspec->ref_count) > 0, NULL);
+
+  g_atomic_int_inc (&pspec->ref_count);
 
-  G_LOCK (pspec_ref_count);
-  if (pspec->ref_count > 0)
-    {
-      pspec->ref_count += 1;
-      G_UNLOCK (pspec_ref_count);
-    }
-  else
-    {
-      G_UNLOCK (pspec_ref_count);
-      g_return_val_if_fail (pspec->ref_count > 0, NULL);
-    }
-  
   return pspec;
 }
 
@@ -184,23 +175,11 @@
 g_param_spec_unref (GParamSpec *pspec)
 {
   g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+  g_return_if_fail (g_atomic_int_get (&pspec->ref_count) > 0);
 
-  G_LOCK (pspec_ref_count);
-  if (pspec->ref_count > 0)
-    {
-      gboolean need_finalize;
-
-      /* sync with _sink */
-      pspec->ref_count -= 1;
-      need_finalize = pspec->ref_count == 0;
-      G_UNLOCK (pspec_ref_count);
-      if (need_finalize)
-	G_PARAM_SPEC_GET_CLASS (pspec)->finalize (pspec);
-    }
-  else
+  if (G_UNLIKELY (g_atomic_int_dec_and_test (&pspec->ref_count)))
     {
-      G_UNLOCK (pspec_ref_count);
-      g_return_if_fail (pspec->ref_count > 0);
+      G_PARAM_SPEC_GET_CLASS (pspec)->finalize (pspec);
     }
 }
 
@@ -208,29 +187,11 @@
 g_param_spec_sink (GParamSpec *pspec)
 {
   g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+  g_return_if_fail (g_atomic_int_get (&pspec->ref_count) > 0);
 
-  G_LOCK (pspec_ref_count);
-  if (pspec->ref_count > 0)
-    {
-      if (g_datalist_id_remove_no_notify (&pspec->qdata, quark_floating))
-	{
-	  /* sync with _unref */
-	  if (pspec->ref_count > 1)
-	    pspec->ref_count -= 1;
-	  else
-	    {
-	      G_UNLOCK (pspec_ref_count);
-	      g_param_spec_unref (pspec);
-
-	      return;
-	    }
-	}
-      G_UNLOCK (pspec_ref_count);
-    }
-  else
+  if (g_datalist_id_remove_no_notify (&pspec->qdata, quark_floating))
     {
-      G_UNLOCK (pspec_ref_count);
-      g_return_if_fail (pspec->ref_count > 0);
+      g_param_spec_unref (pspec);
     }
 }
 
diff -Naur glib-2.6.1/gobject/gsignal.c glib-2.6.1-atomic/gobject/gsignal.c
--- glib-2.6.1/gobject/gsignal.c	2004-11-28 01:40:07.000000000 +0100
+++ glib-2.6.1-atomic/gobject/gsignal.c	2005-01-27 18:03:55.000000000 +0100
@@ -32,6 +32,7 @@
 #include        "gvaluecollector.h"
 #include	"gvaluetypes.h"
 #include	"gboxed.h"
+#include	"gatomic_impl.h"
 #include	<string.h> 
 #include	<signal.h>
 
@@ -219,8 +220,7 @@
   Handler      *next;
   Handler      *prev;
   GQuark	detail;
-  guint         ref_count : 16;
-#define HANDLER_MAX_REF_COUNT   (1 << 16)
+  guint         ref_count;	/* ABI change, was 16 bits but since it's internal... */
   guint         block_count : 12;
 #define HANDLER_MAX_BLOCK_COUNT (1 << 12)
   guint         after : 1;
@@ -562,14 +562,9 @@
 static inline void
 handler_ref (Handler *handler)
 {
-  g_return_if_fail (handler->ref_count > 0);
+  g_return_if_fail (g_atomic_int_get (&handler->ref_count) > 0);
   
-#ifndef G_DISABLE_CHECKS
-  if (handler->ref_count >= HANDLER_MAX_REF_COUNT - 1)
-    g_error (G_STRLOC ": handler ref_count overflow, %s", REPORT_BUG);
-#endif
-  
-  handler->ref_count += 1;
+  g_atomic_int_inc (&handler->ref_count);
 }
 
 static inline void
@@ -577,10 +572,9 @@
 		 gpointer instance,
 		 Handler *handler)
 {
-  g_return_if_fail (handler->ref_count > 0);
+  g_return_if_fail (g_atomic_int_get (&handler->ref_count) > 0);
   
-  handler->ref_count -= 1;
-  if (!handler->ref_count)
+  if (G_UNLIKELY (g_atomic_int_dec_and_test (&handler->ref_count)))
     {
       HandlerList *hlist = NULL;
 
diff -Naur glib-2.6.1/gobject/gtype.c glib-2.6.1-atomic/gobject/gtype.c
--- glib-2.6.1/gobject/gtype.c	2004-11-01 19:47:12.000000000 +0100
+++ glib-2.6.1-atomic/gobject/gtype.c	2005-01-27 18:04:09.000000000 +0100
@@ -27,6 +27,7 @@
 #include	"gtypeplugin.h"
 #include	"gvaluecollector.h"
 #include	"gbsearcharray.h"
+#include	"gatomic_impl.h"
 #include	<string.h>
 
 
@@ -1081,9 +1082,9 @@
     }
   else
     {
-      g_assert (node->data->common.ref_count > 0);
+      g_assert (g_atomic_int_get (&node->data->common.ref_count) > 0);
       
-      node->data->common.ref_count += 1;
+      g_atomic_int_inc (&node->data->common.ref_count);
     }
 }
 
@@ -1091,12 +1092,13 @@
 type_data_unref_Wm (TypeNode *node,
 		    gboolean  uncached)
 {
-  g_assert (node->data && node->data->common.ref_count);
+  g_assert (g_atomic_int_get (&node->data->common.ref_count));
   
-  if (node->data->common.ref_count > 1)
-    node->data->common.ref_count -= 1;
-  else
+  if (G_UNLIKELY (g_atomic_int_dec_and_test (&node->data->common.ref_count))) 
     {
+      /* ref for last_unref call */
+      g_atomic_int_inc (&node->data->common.ref_count);
+
       if (!node->plugin)
 	{
 	  g_warning ("static type `%s' unreferenced too often",
@@ -1948,7 +1950,8 @@
 {
   guint i;
 
-  g_assert (node->is_instantiatable && node->data && node->data->class.class && node->data->common.ref_count == 0);
+  g_assert (node->is_instantiatable && node->data && node->data->class.class && 
+		  g_atomic_int_get (&node->data->common.ref_count) == 0);
 
  reiterate:
   for (i = 0; i < CLASSED_NODE_N_IFACES (node); i++)
@@ -1980,7 +1983,7 @@
   GTypeClass *class = cdata->class;
   TypeNode *bnode;
   
-  g_assert (cdata->class && cdata->common.ref_count == 0);
+  g_assert (cdata->class && g_atomic_int_get (&cdata->common.ref_count) == 0);
   
   if (cdata->class_finalize)
     cdata->class_finalize (class, (gpointer) cdata->class_data);
@@ -2004,7 +2007,7 @@
   
   g_return_if_fail (node != NULL && node->plugin != NULL);
   
-  if (!node->data || node->data->common.ref_count == 0)
+  if (!node->data || g_atomic_int_get (&node->data->common.ref_count) == 0)
     {
       g_warning ("cannot drop last reference to unreferenced type `%s'",
 		 type_descriptive_name_I (type));
@@ -2027,7 +2030,7 @@
 	  G_READ_UNLOCK (&type_rw_lock);
 	  need_break = cache_func (cache_data, node->data->class.class);
 	  G_READ_LOCK (&type_rw_lock);
-	  if (!node->data || node->data->common.ref_count == 0)
+          if (!node->data || g_atomic_int_get (&node->data->common.ref_count) == 0)
 	    INVALID_RECURSION ("GType class cache function ", cache_func, NODE_NAME (node));
 	  if (need_break)
 	    break;
@@ -2036,15 +2039,11 @@
       G_WRITE_LOCK (&type_rw_lock);
     }
   
-  if (node->data->common.ref_count > 1)	/* may have been re-referenced meanwhile */
-    node->data->common.ref_count -= 1;
-  else
+  if (G_LIKELY (g_atomic_int_dec_and_test (&node->data->common.ref_count))) /* may have been re-referenced meanwhile */
     {
       GType ptype = NODE_PARENT_TYPE (node);
       TypeData *tdata;
       
-      node->data->common.ref_count = 0;
-      
       if (node->is_instantiatable && node->data->instance.mem_chunk)
 	{
 	  g_mem_chunk_destroy (node->data->instance.mem_chunk);
@@ -2369,7 +2368,7 @@
   G_WRITE_LOCK (&type_rw_lock);
   node = lookup_type_node_I (type);
   if (node && node->is_classed && node->data &&
-      node->data->class.class && node->data->common.ref_count > 0)
+      node->data->class.class && g_atomic_int_get (&node->data->common.ref_count) > 0)
     {
       type_data_ref_Wm (node);
       G_WRITE_UNLOCK (&type_rw_lock);
@@ -2378,7 +2377,7 @@
     }
   
   if (!node || !node->is_classed ||
-      (node->data && node->data->common.ref_count < 1))
+      (node->data && g_atomic_int_get (&node->data->common.ref_count) < 1))
     {
       G_WRITE_UNLOCK (&type_rw_lock);
       g_warning ("cannot retrieve class for invalid (unclassed) type `%s'",
@@ -2420,7 +2419,7 @@
   node = lookup_type_node_I (class->g_type);
   G_WRITE_LOCK (&type_rw_lock);
   if (node && node->is_classed && node->data &&
-      node->data->class.class == class && node->data->common.ref_count > 0)
+      node->data->class.class == class && g_atomic_int_get (&node->data->common.ref_count) > 0)
     type_data_unref_Wm (node, FALSE);
   else
     g_warning ("cannot unreference class of invalid (unclassed) type `%s'",
@@ -2439,7 +2438,7 @@
   G_WRITE_LOCK (&type_rw_lock);
   node = lookup_type_node_I (class->g_type);
   if (node && node->is_classed && node->data &&
-      node->data->class.class == class && node->data->common.ref_count > 0)
+      node->data->class.class == class && g_atomic_int_get (&node->data->common.ref_count) > 0)
     type_data_unref_Wm (node, TRUE);
   else
     g_warning ("cannot unreference class of invalid (unclassed) type `%s'",
@@ -2579,7 +2578,7 @@
   
   node = lookup_type_node_I (g_type);
   if (!node || !NODE_IS_IFACE (node) ||
-      (node->data && node->data->common.ref_count < 1))
+      (node->data && g_atomic_int_get (&node->data->common.ref_count) < 1))
     {
       G_WRITE_UNLOCK (&type_rw_lock);
       g_warning ("cannot retrieve default vtable for invalid or non-interface type '%s'",
@@ -2625,7 +2624,7 @@
   G_WRITE_LOCK (&type_rw_lock);
   if (node && NODE_IS_IFACE (node) &&
       node->data->iface.dflt_vtable == g_iface &&
-      node->data->common.ref_count > 0)
+      g_atomic_int_get (&node->data->common.ref_count) > 0)
     type_data_unref_Wm (node, FALSE);
   else
     g_warning ("cannot unreference invalid interface default vtable for '%s'",
@@ -3254,7 +3253,7 @@
  restart_check:
   if (node)
     {
-      if (node->data && node->data->common.ref_count > 0 &&
+      if (node->data && g_atomic_int_get (&node->data->common.ref_count) > 0 &&
 	  node->data->common.value_table->value_init)
 	tflags = GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags));
       else if (NODE_IS_IFACE (node))
@@ -3317,7 +3316,7 @@
   G_READ_LOCK (&type_rw_lock);
   
  restart_table_peek:
-  has_refed_data = node && node->data && node->data->common.ref_count;
+  has_refed_data = node && node->data && g_atomic_int_get (&node->data->common.ref_count);
   has_table = has_refed_data && node->data->common.value_table->value_init;
   if (has_refed_data)
     {
@@ -3567,7 +3566,7 @@
   if (NODE_PARENT_TYPE (private_node))
     {
       parent_node = lookup_type_node_I (NODE_PARENT_TYPE (private_node));
-      g_assert (parent_node->data && parent_node->data->common.ref_count);
+      g_assert (parent_node->data && g_atomic_int_get (&parent_node->data->common.ref_count));
 
       if (G_UNLIKELY (private_node->data->instance.private_size == parent_node->data->instance.private_size))
 	{
diff -Naur glib-2.6.1/tests/Makefile.am glib-2.6.1-atomic/tests/Makefile.am
--- glib-2.6.1/tests/Makefile.am	2004-11-24 16:54:20.000000000 +0100
+++ glib-2.6.1-atomic/tests/Makefile.am	2005-01-27 11:38:02.000000000 +0100
@@ -1,4 +1,4 @@
-SUBDIRS=gobject
+SUBDIRS=gobject refcount
 
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/glib -I$(top_srcdir)/gmodule $(GLIB_DEBUG_FLAGS)
 
diff -Naur glib-2.6.1/tests/refcount/Makefile.am glib-2.6.1-atomic/tests/refcount/Makefile.am
--- glib-2.6.1/tests/refcount/Makefile.am	1970-01-01 01:00:00.000000000 +0100
+++ glib-2.6.1-atomic/tests/refcount/Makefile.am	2005-01-27 13:48:03.000000000 +0100
@@ -0,0 +1,32 @@
+INCLUDES =					\
+	-I$(top_srcdir)				\
+	-I$(top_srcdir)/glib			\
+	-I$(top_srcdir)/gmodule			\
+	$(GLIB_DEBUG_FLAGS)
+
+libglib = $(top_builddir)/glib/libglib-2.0.la
+libgthread = $(top_builddir)/gthread/libgthread-2.0.la
+libgmodule = $(top_builddir)/gmodule/libgmodule-2.0.la
+libgobject = $(top_builddir)/gobject/libgobject-2.0.la
+
+LDADD = $(libgobject) $(libgthread)
+
+test_programs =					\
+	signal1					\
+	signal2					\
+	signal3					\
+	objects					\
+	objects2
+
+signal1_SOURCES = signals.c
+signal1_CFLAGS = -DTESTNUM=1 $(AM_CFLAGS)
+signal2_SOURCES = signals.c
+signal2_CFLAGS = -DTESTNUM=2 $(AM_CFLAGS)
+signal3_SOURCES = signals.c
+signal3_CFLAGS = -DTESTNUM=3 $(AM_CFLAGS)
+
+check_PROGRAMS = $(test_programs)
+
+TESTS = $(test_programs)
+TESTS_ENVIRONMENT = srcdir=$(srcdir) \
+	LIBCHARSET_ALIAS_DIR=$(top_builddir)/glib/libcharset
diff -Naur glib-2.6.1/tests/refcount/objects.c glib-2.6.1-atomic/tests/refcount/objects.c
--- glib-2.6.1/tests/refcount/objects.c	1970-01-01 01:00:00.000000000 +0100
+++ glib-2.6.1-atomic/tests/refcount/objects.c	2005-01-27 13:29:35.000000000 +0100
@@ -0,0 +1,155 @@
+#include <unistd.h>
+#include <glib.h>
+#include <glib-object.h>
+
+#define G_TYPE_TEST               (g_test_get_type ())
+#define G_TEST(test)              (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest))
+#define G_IS_TEST(test)           (G_TYPE_CHECK_INSTANCE_TYPE ((test), G_TYPE_TEST))
+#define G_TEST_CLASS(tclass)      (G_TYPE_CHECK_CLASS_CAST ((tclass), G_TYPE_TEST, GTestClass))
+#define G_IS_TEST_CLASS(tclass)   (G_TYPE_CHECK_CLASS_TYPE ((tclass), G_TYPE_TEST))
+#define G_TEST_GET_CLASS(test)    (G_TYPE_INSTANCE_GET_CLASS ((test), G_TYPE_TEST, GTestClass))
+
+typedef struct _GTest GTest;
+typedef struct _GTestClass GTestClass;
+
+struct _GTest
+{
+  GObject object;
+};
+
+struct _GTestClass
+{
+  GObjectClass parent_class;
+};
+
+static GType g_test_get_type (void);
+static gboolean stopping;
+
+static void g_test_class_init (GTestClass * klass);
+static void g_test_init (GTest * test);
+static void g_test_dispose (GObject * object);
+
+static GObjectClass *parent_class = NULL;
+
+static GType
+g_test_get_type (void)
+{
+  static GType test_type = 0;
+
+  if (!test_type) {
+    static const GTypeInfo test_info = {
+      sizeof (GTestClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) g_test_class_init,
+      NULL,
+      NULL,
+      sizeof (GTest),
+      0,
+      (GInstanceInitFunc) g_test_init,
+      NULL
+    };
+
+    test_type = g_type_register_static (G_TYPE_OBJECT, "GTest",
+        &test_info, 0);
+  }
+  return test_type;
+}
+
+static void
+g_test_class_init (GTestClass * klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = (GObjectClass *) klass;
+
+  parent_class = g_type_class_ref (G_TYPE_OBJECT);
+
+  gobject_class->dispose = g_test_dispose;
+}
+
+static void
+g_test_init (GTest * test)
+{
+  g_print ("init %p\n", test);
+}
+
+static void
+g_test_dispose (GObject * object)
+{
+  GTest *test;
+
+  test = G_TEST (object);
+
+  g_print ("dispose %p!\n", object);
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+g_test_do_refcount (GTest * test)
+{
+  g_object_ref (test); 
+  g_object_unref (test); 
+}
+
+static gpointer
+run_thread (GTest * test)
+{
+  gint i = 0;
+
+  while (!stopping) {
+    g_test_do_refcount (test);
+    if ((i++ % 100000) == 0) {
+      g_print (".");
+      g_usleep (1);             /* context switch */
+    }
+  }
+
+  return NULL;
+}
+
+int
+main (int argc, char **argv)
+{
+  gint i;
+  GTest *test1, *test2;
+  GArray *test_threads;
+
+  g_thread_init (NULL);
+  g_type_init ();
+
+  test1 = g_object_new (G_TYPE_TEST, NULL);
+  test2 = g_object_new (G_TYPE_TEST, NULL);
+
+  test_threads = g_array_new (FALSE, FALSE, sizeof (GThread *));
+
+  stopping = FALSE;
+
+  for (i = 0; i < 20; i++) {
+    GThread *thread;
+
+    thread = g_thread_create ((GThreadFunc) run_thread, test1, TRUE, NULL);
+    g_array_append_val (test_threads, thread);
+
+    thread = g_thread_create ((GThreadFunc) run_thread, test2, TRUE, NULL);
+    g_array_append_val (test_threads, thread);
+  }
+  sleep (5);
+
+  stopping = TRUE;
+
+  g_print ("\nstopping\n");
+
+  /* join all threads */
+  for (i = 0; i < 40; i++) {
+    GThread *thread;
+
+    thread = g_array_index (test_threads, GThread *, i);
+    g_thread_join (thread);
+  }
+
+  g_print ("stopped\n");
+
+  return 0;
+}
diff -Naur glib-2.6.1/tests/refcount/objects2.c glib-2.6.1-atomic/tests/refcount/objects2.c
--- glib-2.6.1/tests/refcount/objects2.c	1970-01-01 01:00:00.000000000 +0100
+++ glib-2.6.1-atomic/tests/refcount/objects2.c	2005-01-27 13:47:47.000000000 +0100
@@ -0,0 +1,111 @@
+#include <unistd.h>
+#include <glib.h>
+#include <glib-object.h>
+
+#define G_TYPE_TEST               (g_test_get_type ())
+#define G_TEST(test)              (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest))
+#define G_IS_TEST(test)           (G_TYPE_CHECK_INSTANCE_TYPE ((test), G_TYPE_TEST))
+#define G_TEST_CLASS(tclass)      (G_TYPE_CHECK_CLASS_CAST ((tclass), G_TYPE_TEST, GTestClass))
+#define G_IS_TEST_CLASS(tclass)   (G_TYPE_CHECK_CLASS_TYPE ((tclass), G_TYPE_TEST))
+#define G_TEST_GET_CLASS(test)    (G_TYPE_INSTANCE_GET_CLASS ((test), G_TYPE_TEST, GTestClass))
+
+typedef struct _GTest GTest;
+typedef struct _GTestClass GTestClass;
+
+struct _GTest
+{
+  GObject object;
+};
+
+struct _GTestClass
+{
+  GObjectClass parent_class;
+};
+
+static GType g_test_get_type (void);
+
+static void g_test_class_init (GTestClass * klass);
+static void g_test_init (GTest * test);
+static void g_test_dispose (GObject * object);
+
+static GObjectClass *parent_class = NULL;
+
+static GType
+g_test_get_type (void)
+{
+  static GType test_type = 0;
+
+  if (!test_type) {
+    static const GTypeInfo test_info = {
+      sizeof (GTestClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) g_test_class_init,
+      NULL,
+      NULL,
+      sizeof (GTest),
+      0,
+      (GInstanceInitFunc) g_test_init,
+      NULL
+    };
+
+    test_type = g_type_register_static (G_TYPE_OBJECT, "GTest",
+        &test_info, 0);
+  }
+  return test_type;
+}
+
+static void
+g_test_class_init (GTestClass * klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = (GObjectClass *) klass;
+
+  parent_class = g_type_class_ref (G_TYPE_OBJECT);
+
+  gobject_class->dispose = g_test_dispose;
+}
+
+static void
+g_test_init (GTest * test)
+{
+  g_print ("init %p\n", test);
+}
+
+static void
+g_test_dispose (GObject * object)
+{
+  GTest *test;
+
+  test = G_TEST (object);
+
+  g_print ("dispose %p!\n", object);
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+g_test_do_refcount (GTest * test)
+{
+  g_object_ref (test); 
+  g_object_unref (test); 
+}
+
+int
+main (int argc, char **argv)
+{
+  gint i;
+  GTest *test;
+
+  g_thread_init (NULL);
+  g_type_init ();
+
+  test = g_object_new (G_TYPE_TEST, NULL);
+
+  for (i=0; i<100000000; i++) {
+    g_test_do_refcount (test);
+  }
+
+  return 0;
+}
diff -Naur glib-2.6.1/tests/refcount/signals.c glib-2.6.1-atomic/tests/refcount/signals.c
--- glib-2.6.1/tests/refcount/signals.c	1970-01-01 01:00:00.000000000 +0100
+++ glib-2.6.1-atomic/tests/refcount/signals.c	2005-01-27 13:19:57.000000000 +0100
@@ -0,0 +1,259 @@
+#include <unistd.h>
+#include <glib.h>
+#include <glib-object.h>
+
+#define G_TYPE_TEST               (g_test_get_type ())
+#define G_TEST(test)              (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest))
+#define G_IS_TEST(test)           (G_TYPE_CHECK_INSTANCE_TYPE ((test), G_TYPE_TEST))
+#define G_TEST_CLASS(tclass)      (G_TYPE_CHECK_CLASS_CAST ((tclass), G_TYPE_TEST, GTestClass))
+#define G_IS_TEST_CLASS(tclass)   (G_TYPE_CHECK_CLASS_TYPE ((tclass), G_TYPE_TEST))
+#define G_TEST_GET_CLASS(test)    (G_TYPE_INSTANCE_GET_CLASS ((test), G_TYPE_TEST, GTestClass))
+
+typedef struct _GTest GTest;
+typedef struct _GTestClass GTestClass;
+
+struct _GTest
+{
+  GObject object;
+};
+
+struct _GTestClass
+{
+  GObjectClass parent_class;
+
+  void (*test_signal1) (GTest * test, gint an_int);
+  void (*test_signal2) (GTest * test, gint an_int);
+};
+
+static GType g_test_get_type (void);
+static gboolean stopping;
+
+/* Element signals and args */
+enum
+{
+  TEST_SIGNAL1,
+  TEST_SIGNAL2,
+  /* add more above */
+  LAST_SIGNAL
+};
+
+enum
+{
+  ARG_0,
+  ARG_TEST_PROP
+};
+
+static void g_test_class_init (GTestClass * klass);
+static void g_test_init (GTest * test);
+static void g_test_dispose (GObject * object);
+
+static void signal2_handler (GTest * test, gint anint);
+
+static void g_test_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void g_test_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static GObjectClass *parent_class = NULL;
+
+static guint g_test_signals[LAST_SIGNAL] = { 0 };
+
+static GType
+g_test_get_type (void)
+{
+  static GType test_type = 0;
+
+  if (!test_type) {
+    static const GTypeInfo test_info = {
+      sizeof (GTestClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) g_test_class_init,
+      NULL,
+      NULL,
+      sizeof (GTest),
+      0,
+      (GInstanceInitFunc) g_test_init,
+      NULL
+    };
+
+    test_type = g_type_register_static (G_TYPE_OBJECT, "GTest",
+        &test_info, 0);
+  }
+  return test_type;
+}
+
+static void
+g_test_class_init (GTestClass * klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = (GObjectClass *) klass;
+
+  parent_class = g_type_class_ref (G_TYPE_OBJECT);
+
+  if (!g_thread_supported ())
+    g_thread_init (NULL);
+
+  gobject_class->dispose = g_test_dispose;
+  gobject_class->set_property = g_test_set_property;
+  gobject_class->get_property = g_test_get_property;
+
+  g_test_signals[TEST_SIGNAL1] =
+      g_signal_new ("test-signal1", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GTestClass, test_signal1), NULL,
+      NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+  g_test_signals[TEST_SIGNAL2] =
+      g_signal_new ("test-signal2", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GTestClass, test_signal2), NULL,
+      NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TEST_PROP,
+      g_param_spec_int ("test-prop", "Test Prop", "Test property",
+          0, 1, 0, G_PARAM_READWRITE));
+
+  klass->test_signal2 = signal2_handler;
+}
+
+static void
+g_test_init (GTest * test)
+{
+  g_print ("init %p\n", test);
+}
+
+static void
+g_test_dispose (GObject * object)
+{
+  GTest *test;
+
+  test = G_TEST (object);
+
+  g_print ("dispose %p!\n", object);
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+g_test_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GTest *test;
+
+  test = G_TEST (object);
+
+  switch (prop_id) {
+    case ARG_TEST_PROP:
+      g_value_get_int (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+g_test_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GTest *test;
+
+  test = G_TEST (object);
+
+  switch (prop_id) {
+    case ARG_TEST_PROP:
+      g_value_set_int (value, 0);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+g_test_do_signal1 (GTest * test)
+{
+  g_signal_emit (G_OBJECT (test), g_test_signals[TEST_SIGNAL1], 0, 0);
+}
+
+static void
+signal2_handler (GTest * test, gint anint)
+{
+}
+
+static void
+g_test_do_signal2 (GTest * test)
+{
+  g_signal_emit (G_OBJECT (test), g_test_signals[TEST_SIGNAL2], 0, 0);
+}
+
+static void
+g_test_do_prop (GTest * test)
+{
+  g_object_notify (G_OBJECT (test), "test-prop");
+}
+
+static gpointer
+run_thread (GTest * test)
+{
+  gint i = 0;
+
+  while (!stopping) {
+    if (TESTNUM == 1)
+      g_test_do_signal1 (test);
+    if (TESTNUM == 2)
+      g_test_do_signal2 (test);
+    if (TESTNUM == 3)
+      g_test_do_prop (test);
+    if ((i++ % 100000) == 0) {
+      g_print (".");
+      g_usleep (1);             /* context switch */
+    }
+  }
+
+  return NULL;
+}
+
+int
+main (int argc, char **argv)
+{
+  gint i;
+  GTest *test1, *test2;
+  GArray *test_threads;
+
+  g_thread_init (NULL);
+  g_type_init ();
+
+  test1 = g_object_new (G_TYPE_TEST, NULL);
+  test2 = g_object_new (G_TYPE_TEST, NULL);
+
+  test_threads = g_array_new (FALSE, FALSE, sizeof (GThread *));
+
+  stopping = FALSE;
+
+  for (i = 0; i < 20; i++) {
+    GThread *thread;
+
+    thread = g_thread_create ((GThreadFunc) run_thread, test1, TRUE, NULL);
+    g_array_append_val (test_threads, thread);
+
+    thread = g_thread_create ((GThreadFunc) run_thread, test2, TRUE, NULL);
+    g_array_append_val (test_threads, thread);
+  }
+  sleep (5);
+
+  stopping = TRUE;
+
+  g_print ("\nstopping\n");
+
+  /* join all threads */
+  for (i = 0; i < 40; i++) {
+    GThread *thread;
+
+    thread = g_array_index (test_threads, GThread *, i);
+    g_thread_join (thread);
+  }
+
+  g_print ("stopped\n");
+
+  return 0;
+}
