+/*****************************************************************************
+ * vlc_threadvar_create: create a thread-local variable
+ *****************************************************************************/
+#define vlc_threadvar_create( PTHIS, P_TLS ) \
+ __vlc_threadvar_create( P_TLS )
+
+/*****************************************************************************
+ * vlc_threadvar_set: create: set the value of a thread-local variable
+ *****************************************************************************/
+static inline int vlc_threadvar_set( vlc_threadvar_t * p_tls, void *p_value )
+{
+ int i_ret;
+
+#if defined( HAVE_KERNEL_SCHEDULER_H )
+ return -1;
+
+#elif defined( UNDER_CE ) || defined( WIN32 )
+ i_ret = ( TlsSetValue( p_tls->handle, p_value ) != 0 );
+
+#elif defined(LIBVLC_USE_PTHREAD)
+ i_ret = pthread_setspecific( p_tls->handle, p_value );
+
+#endif
+
+ return i_ret;
+}
+
+/*****************************************************************************
+ * vlc_threadvar_get: create: get the value of a thread-local variable
+ *****************************************************************************/
+static inline void* vlc_threadvar_get( vlc_threadvar_t * p_tls )
+{
+ void* p_ret;
+
+#if defined( HAVE_KERNEL_SCHEDULER_H )
+ p_ret = NULL;
+#elif defined( UNDER_CE ) || defined( WIN32 )
+ p_ret = TlsGetValue( p_tls->handle );
+
+#elif defined(LIBVLC_USE_PTHREAD)
+ p_ret = pthread_getspecific( p_tls->handle );
+
+#endif
+
+ return p_ret;
+}
+
+# if defined (_POSIX_SPIN_LOCKS) && ((_POSIX_SPIN_LOCKS - 0) > 0)
+typedef struct
+{
+ pthread_spinlock_t spin;
+} vlc_spinlock_t;
+
+/**
+ * Initializes a spinlock.
+ */
+static inline int vlc_spin_init (vlc_spinlock_t *spin)
+{
+ return pthread_spin_init (&spin->spin, PTHREAD_PROCESS_PRIVATE);
+}
+
+/**
+ * Acquires a spinlock.
+ */
+static inline void vlc_spin_lock (vlc_spinlock_t *spin)
+{
+ int val = pthread_spin_lock (&spin->spin);
+ assert (val == 0);
+}
+
+/**
+ * Releases a spinlock.
+ */
+static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
+{
+ int val = pthread_spin_unlock (&spin->spin);
+ assert (val == 0);
+}
+
+/**
+ * Deinitializes a spinlock.
+ */
+static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
+{
+ int val = pthread_spin_destroy (&spin->spin);
+ assert (val == 0);
+}
+
+#elif defined( WIN32 )
+
+typedef CRITICAL_SECTION vlc_spinlock_t;
+
+/**
+ * Initializes a spinlock.
+ */
+static inline int vlc_spin_init (vlc_spinlock_t *spin)
+{
+ return !InitializeCriticalSectionAndSpinCount(spin, 4000);
+}
+
+/**
+ * Acquires a spinlock.
+ */
+static inline void vlc_spin_lock (vlc_spinlock_t *spin)
+{
+ EnterCriticalSection(spin);
+}
+
+/**
+ * Releases a spinlock.
+ */
+static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
+{
+ LeaveCriticalSection(spin);
+}
+
+/**
+ * Deinitializes a spinlock.
+ */
+static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
+{
+ DeleteCriticalSection(spin);
+}
+
+
+#else
+
+/* Fallback to plain mutexes if spinlocks are not available */
+typedef vlc_mutex_t vlc_spinlock_t;
+
+static inline int vlc_spin_init (vlc_spinlock_t *spin)
+{
+ return __vlc_mutex_init (spin);
+}
+
+# define vlc_spin_lock vlc_mutex_lock
+# define vlc_spin_unlock vlc_mutex_unlock
+# define vlc_spin_destroy vlc_mutex_destroy
+#endif
+