+#endif
+
+#undef vlc_gc_init
+#undef vlc_hold
+#undef vlc_release
+
+/**
+ * Atomically set the reference count to 1.
+ * @param p_gc reference counted object
+ * @param pf_destruct destruction calback
+ * @return p_gc.
+ */
+void *vlc_gc_init (gc_object_t *p_gc, void (*pf_destruct) (gc_object_t *))
+{
+ /* There is no point in using the GC if there is no destructor... */
+ assert (pf_destruct);
+ p_gc->pf_destructor = pf_destruct;
+
+ p_gc->refs = 1;
+#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+ __sync_synchronize ();
+#elif defined (WIN32) && defined (__GNUC__)
+#elif defined(__APPLE__)
+ OSMemoryBarrier ();
+#else
+ /* Nobody else can possibly lock the spin - it's there as a barrier */
+ vlc_spin_init (&p_gc->spin);
+ vlc_spin_lock (&p_gc->spin);
+ vlc_spin_unlock (&p_gc->spin);
+#endif
+ return p_gc;
+}
+
+/**
+ * Atomically increment the reference count.
+ * @param p_gc reference counted object
+ * @return p_gc.
+ */
+void *vlc_hold (gc_object_t * p_gc)
+{
+ uintptr_t refs;
+ assert( p_gc );
+ assert ((((uintptr_t)&p_gc->refs) & (sizeof (void *) - 1)) == 0); /* alignment */
+
+#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+ refs = __sync_add_and_fetch (&p_gc->refs, 1);
+#elif defined (WIN64)
+ refs = InterlockedIncrement64 (&p_gc->refs);
+#elif defined (WIN32)
+ refs = InterlockedIncrement (&p_gc->refs);
+#elif defined(__APPLE__)
+ refs = OSAtomicIncrement32Barrier((int*)&p_gc->refs);
+#else
+ vlc_spin_lock (&p_gc->spin);
+ refs = ++p_gc->refs;
+ vlc_spin_unlock (&p_gc->spin);
+#endif
+ assert (refs != 1); /* there had to be a reference already */
+ return p_gc;
+}
+
+/**
+ * Atomically decrement the reference count and, if it reaches zero, destroy.
+ * @param p_gc reference counted object.
+ */
+void vlc_release (gc_object_t *p_gc)
+{
+ unsigned refs;
+
+ assert( p_gc );
+ assert ((((uintptr_t)&p_gc->refs) & (sizeof (void *) - 1)) == 0); /* alignment */
+
+#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+ refs = __sync_sub_and_fetch (&p_gc->refs, 1);
+#elif defined (WIN64)
+ refs = InterlockedDecrement64 (&p_gc->refs);
+#elif defined (WIN32)
+ refs = InterlockedDecrement (&p_gc->refs);
+#elif defined(__APPLE__)
+ refs = OSAtomicDecrement32Barrier((int*)&p_gc->refs);
+#else
+ vlc_spin_lock (&p_gc->spin);
+ refs = --p_gc->refs;
+ vlc_spin_unlock (&p_gc->spin);
+#endif
+
+ assert (refs != (uintptr_t)(-1)); /* reference underflow?! */
+ if (refs == 0)
+ {
+#ifdef USE_SYNC
+#elif defined (WIN32) && defined (__GNUC__)
+#elif defined(__APPLE__)
+#else
+ vlc_spin_destroy (&p_gc->spin);
+#endif
+ p_gc->pf_destructor (p_gc);
+ }
+}