+ if (__gthread_active_p ())
+ return pthread_getspecific (_objc_thread_storage);
+ else
+ return thread_local_storage;
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+static inline int
+__gthread_objc_mutex_allocate (objc_mutex_t mutex)
+{
+ if (__gthread_active_p ())
+ {
+ mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
+
+ if (pthread_mutex_init ((pthread_mutex_t *) mutex->backend, NULL))
+ {
+ objc_free (mutex->backend);
+ mutex->backend = NULL;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/* Deallocate a mutex. */
+static inline int
+__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
+{
+ if (__gthread_active_p ())
+ {
+ int count;
+
+ /*
+ * Posix Threads specifically require that the thread be unlocked
+ * for pthread_mutex_destroy to work.
+ */
+
+ do
+ {
+ count = pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend);
+ if (count < 0)
+ return -1;
+ }
+ while (count);
+
+ if (pthread_mutex_destroy ((pthread_mutex_t *) mutex->backend))
+ return -1;
+
+ objc_free (mutex->backend);
+ mutex->backend = NULL;
+ }
+ return 0;
+}
+
+/* Grab a lock on a mutex. */
+static inline int
+__gthread_objc_mutex_lock (objc_mutex_t mutex)
+{
+ if (__gthread_active_p ()
+ && pthread_mutex_lock ((pthread_mutex_t *) mutex->backend) != 0)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Try to grab a lock on a mutex. */
+static inline int
+__gthread_objc_mutex_trylock (objc_mutex_t mutex)
+{
+ if (__gthread_active_p ()
+ && pthread_mutex_trylock ((pthread_mutex_t *) mutex->backend) != 0)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Unlock the mutex */
+static inline int
+__gthread_objc_mutex_unlock (objc_mutex_t mutex)
+{
+ if (__gthread_active_p ()
+ && pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend) != 0)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+static inline int
+__gthread_objc_condition_allocate (objc_condition_t condition)
+{
+ if (__gthread_active_p ())
+ {
+ condition->backend = objc_malloc (sizeof (pthread_cond_t));
+
+ if (pthread_cond_init ((pthread_cond_t *) condition->backend, NULL))
+ {
+ objc_free (condition->backend);
+ condition->backend = NULL;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/* Deallocate a condition. */
+static inline int
+__gthread_objc_condition_deallocate (objc_condition_t condition)
+{
+ if (__gthread_active_p ())
+ {
+ if (pthread_cond_destroy ((pthread_cond_t *) condition->backend))
+ return -1;
+
+ objc_free (condition->backend);
+ condition->backend = NULL;
+ }
+ return 0;
+}
+
+/* Wait on the condition */
+static inline int
+__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
+{
+ if (__gthread_active_p ())
+ return pthread_cond_wait ((pthread_cond_t *) condition->backend,
+ (pthread_mutex_t *) mutex->backend);
+ else
+ return 0;
+}
+
+/* Wake up all threads waiting on this condition. */
+static inline int
+__gthread_objc_condition_broadcast (objc_condition_t condition)
+{
+ if (__gthread_active_p ())
+ return pthread_cond_broadcast ((pthread_cond_t *) condition->backend);
+ else
+ return 0;
+}
+
+/* Wake up one thread waiting on this condition. */
+static inline int
+__gthread_objc_condition_signal (objc_condition_t condition)
+{
+ if (__gthread_active_p ())
+ return pthread_cond_signal ((pthread_cond_t *) condition->backend);