[glib] GThread posix: switch to Windows ABI
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GThread posix: switch to Windows ABI
- Date: Mon, 3 Oct 2011 02:33:20 +0000 (UTC)
commit e081eadda598bc708fbf9dd53a190fc3b0e7fa76
Author: Ryan Lortie <desrt desrt ca>
Date: Sun Oct 2 20:43:28 2011 -0400
GThread posix: switch to Windows ABI
Modify the POSIX implementation of the synchronisation primatives to use
the same ABI as Windows: one pointer for each type.
This frees us from having to #include <pthread.h> and avoids the problem
with pthread_rwlock_t not being defined under certain compiler defines.
A few more changes are expected to the ABI -- they will be committed
separately.
https://bugzilla.gnome.org/show_bug.cgi?id=659866
glib/gthread-posix.c | 198 ++++++++++++++++++++++++++++++++++++++------------
glib/gthread.h | 29 -------
2 files changed, 152 insertions(+), 75 deletions(-)
---
diff --git a/glib/gthread-posix.c b/glib/gthread-posix.c
index 0423f42..f2c35ae 100644
--- a/glib/gthread-posix.c
+++ b/glib/gthread-posix.c
@@ -78,6 +78,58 @@ g_thread_abort (gint status,
/* {{{1 GMutex */
+static pthread_mutex_t *
+g_mutex_impl_new (void)
+{
+ pthread_mutexattr_t *pattr = NULL;
+ pthread_mutex_t *mutex;
+ gint status;
+
+ mutex = malloc (sizeof (pthread_mutex_t));
+ if G_UNLIKELY (mutex == NULL)
+ g_thread_abort (errno, "malloc");
+
+#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init (&attr);
+ pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
+ pattr = &attr;
+#endif
+
+ if G_UNLIKELY ((status = pthread_mutex_init (mutex, pattr)) != 0)
+ g_thread_abort (status, "pthread_mutex_init");
+
+#ifdef PTHREAD_ADAPTIVE_MUTEX_NP
+ pthread_mutexattr_destroy (&attr);
+#endif
+
+ return mutex;
+}
+
+static void
+g_mutex_impl_free (pthread_mutex_t *mutex)
+{
+ pthread_mutex_destroy (mutex);
+ free (mutex);
+}
+
+static pthread_mutex_t *
+g_mutex_get_impl (GMutex *mutex)
+{
+ pthread_mutex_t *impl = mutex->impl;
+
+ if G_UNLIKELY (impl == NULL)
+ {
+ impl = g_mutex_impl_new ();
+ if (!g_atomic_pointer_compare_and_exchange (&mutex->impl, NULL, impl))
+ g_mutex_impl_free (impl);
+ impl = mutex->impl;
+ }
+
+ return impl;
+}
+
+
/**
* g_mutex_init:
* @mutex: an uninitialized #GMutex
@@ -113,21 +165,7 @@ g_thread_abort (gint status,
void
g_mutex_init (GMutex *mutex)
{
- gint status;
- pthread_mutexattr_t *pattr = NULL;
-#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
- pthread_mutexattr_t attr;
- pthread_mutexattr_init (&attr);
- pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
- pattr = &attr;
-#endif
-
- if G_UNLIKELY ((status = pthread_mutex_init (&mutex->impl, pattr)) != 0)
- g_thread_abort (status, "pthread_mutex_init");
-
-#ifdef PTHREAD_ADAPTIVE_MUTEX_NP
- pthread_mutexattr_destroy (&attr);
-#endif
+ mutex->impl = g_mutex_impl_new ();
}
/**
@@ -147,10 +185,7 @@ g_mutex_init (GMutex *mutex)
void
g_mutex_clear (GMutex *mutex)
{
- gint status;
-
- if G_UNLIKELY ((status = pthread_mutex_destroy (&mutex->impl)) != 0)
- g_thread_abort (status, "pthread_mutex_destroy");
+ g_mutex_impl_free (mutex->impl);
}
/**
@@ -174,7 +209,7 @@ g_mutex_lock (GMutex *mutex)
{
gint status;
- if G_UNLIKELY ((status = pthread_mutex_lock (&mutex->impl)) != 0)
+ if G_UNLIKELY ((status = pthread_mutex_lock (g_mutex_get_impl (mutex))) != 0)
g_thread_abort (status, "pthread_mutex_lock");
}
@@ -196,7 +231,7 @@ g_mutex_unlock (GMutex *mutex)
{
gint status;
- if G_UNLIKELY ((status = pthread_mutex_unlock (&mutex->impl)) != 0)
+ if G_UNLIKELY ((status = pthread_mutex_unlock (g_mutex_get_impl (mutex))) != 0)
g_thread_abort (status, "pthread_mutex_lock");
}
@@ -223,7 +258,7 @@ g_mutex_trylock (GMutex *mutex)
{
gint status;
- if G_LIKELY ((status = pthread_mutex_trylock (&mutex->impl)) == 0)
+ if G_LIKELY ((status = pthread_mutex_trylock (g_mutex_get_impl (mutex))) == 0)
return TRUE;
if G_UNLIKELY (status != EBUSY)
@@ -261,7 +296,7 @@ g_rec_mutex_get_impl (GRecMutex *rec_mutex)
{
pthread_mutex_t *impl = rec_mutex->impl;
- if G_UNLIKELY (rec_mutex->impl == NULL)
+ if G_UNLIKELY (impl == NULL)
{
impl = g_rec_mutex_impl_new ();
if (!g_atomic_pointer_compare_and_exchange (&rec_mutex->impl, NULL, impl))
@@ -330,8 +365,7 @@ g_rec_mutex_init (GRecMutex *rec_mutex)
void
g_rec_mutex_clear (GRecMutex *rec_mutex)
{
- if (rec_mutex->impl)
- g_rec_mutex_impl_free (rec_mutex->impl);
+ g_rec_mutex_impl_free (rec_mutex->impl);
}
/**
@@ -395,6 +429,45 @@ g_rec_mutex_trylock (GRecMutex *rec_mutex)
/* {{{1 GRWLock */
+static pthread_rwlock_t *
+g_rw_lock_impl_new (void)
+{
+ pthread_rwlock_t *rwlock;
+ gint status;
+
+ rwlock = malloc (sizeof (pthread_rwlock_t));
+ if G_UNLIKELY (rwlock == NULL)
+ g_thread_abort (errno, "malloc");
+
+ if G_UNLIKELY ((status = pthread_rwlock_init (rwlock, NULL)) != 0)
+ g_thread_abort (status, "pthread_rwlock_init");
+
+ return rwlock;
+}
+
+static void
+g_rw_lock_impl_free (pthread_rwlock_t *rwlock)
+{
+ pthread_rwlock_destroy (rwlock);
+ free (rwlock);
+}
+
+static pthread_rwlock_t *
+g_rw_lock_get_impl (GRWLock *lock)
+{
+ pthread_rwlock_t *impl = lock->impl;
+
+ if G_UNLIKELY (impl == NULL)
+ {
+ impl = g_rw_lock_impl_new ();
+ if (!g_atomic_pointer_compare_and_exchange (&lock->impl, NULL, impl))
+ g_rw_lock_impl_free (impl);
+ impl = lock->impl;
+ }
+
+ return impl;
+}
+
/**
* g_rw_lock_init:
* @rw_lock: an uninitialized #GRWLock
@@ -429,7 +502,7 @@ g_rec_mutex_trylock (GRecMutex *rec_mutex)
void
g_rw_lock_init (GRWLock *rw_lock)
{
- pthread_rwlock_init (&rw_lock->impl, NULL);
+ rw_lock->impl = g_rw_lock_impl_new ();
}
/**
@@ -446,7 +519,7 @@ g_rw_lock_init (GRWLock *rw_lock)
void
g_rw_lock_clear (GRWLock *rw_lock)
{
- pthread_rwlock_destroy (&rw_lock->impl);
+ g_rw_lock_impl_free (rw_lock->impl);
}
/**
@@ -462,7 +535,7 @@ g_rw_lock_clear (GRWLock *rw_lock)
void
g_rw_lock_writer_lock (GRWLock *rw_lock)
{
- pthread_rwlock_wrlock (&rw_lock->impl);
+ pthread_rwlock_wrlock (g_rw_lock_get_impl (rw_lock));
}
/**
@@ -480,7 +553,7 @@ g_rw_lock_writer_lock (GRWLock *rw_lock)
gboolean
g_rw_lock_writer_trylock (GRWLock *rw_lock)
{
- if (pthread_rwlock_trywrlock (&rw_lock->impl) != 0)
+ if (pthread_rwlock_trywrlock (g_rw_lock_get_impl (rw_lock)) != 0)
return FALSE;
return TRUE;
@@ -500,7 +573,7 @@ g_rw_lock_writer_trylock (GRWLock *rw_lock)
void
g_rw_lock_writer_unlock (GRWLock *rw_lock)
{
- pthread_rwlock_unlock (&rw_lock->impl);
+ pthread_rwlock_unlock (g_rw_lock_get_impl (rw_lock));
}
/**
@@ -519,7 +592,7 @@ g_rw_lock_writer_unlock (GRWLock *rw_lock)
void
g_rw_lock_reader_lock (GRWLock *rw_lock)
{
- pthread_rwlock_rdlock (&rw_lock->impl);
+ pthread_rwlock_rdlock (g_rw_lock_get_impl (rw_lock));
}
/**
@@ -537,7 +610,7 @@ g_rw_lock_reader_lock (GRWLock *rw_lock)
gboolean
g_rw_lock_reader_trylock (GRWLock *rw_lock)
{
- if (pthread_rwlock_tryrdlock (&rw_lock->impl) != 0)
+ if (pthread_rwlock_tryrdlock (g_rw_lock_get_impl (rw_lock)) != 0)
return FALSE;
return TRUE;
@@ -557,11 +630,50 @@ g_rw_lock_reader_trylock (GRWLock *rw_lock)
void
g_rw_lock_reader_unlock (GRWLock *rw_lock)
{
- pthread_rwlock_unlock (&rw_lock->impl);
+ pthread_rwlock_unlock (g_rw_lock_get_impl (rw_lock));
}
/* {{{1 GCond */
+static pthread_cond_t *
+g_cond_impl_new (void)
+{
+ pthread_cond_t *cond;
+ gint status;
+
+ cond = malloc (sizeof (pthread_cond_t));
+ if G_UNLIKELY (cond == NULL)
+ g_thread_abort (errno, "malloc");
+
+ if G_UNLIKELY ((status = pthread_cond_init (cond, NULL)) != 0)
+ g_thread_abort (status, "pthread_cond_init");
+
+ return cond;
+}
+
+static void
+g_cond_impl_free (pthread_cond_t *cond)
+{
+ pthread_cond_destroy (cond);
+ free (cond);
+}
+
+static pthread_cond_t *
+g_cond_get_impl (GCond *cond)
+{
+ pthread_cond_t *impl = cond->impl;
+
+ if G_UNLIKELY (impl == NULL)
+ {
+ impl = g_cond_impl_new ();
+ if (!g_atomic_pointer_compare_and_exchange (&cond->impl, NULL, impl))
+ g_cond_impl_free (impl);
+ impl = cond->impl;
+ }
+
+ return impl;
+}
+
/**
* g_cond_init:
* @cond: an uninitialized #GCond
@@ -585,10 +697,7 @@ g_rw_lock_reader_unlock (GRWLock *rw_lock)
void
g_cond_init (GCond *cond)
{
- gint status;
-
- if G_UNLIKELY ((status = pthread_cond_init (&cond->impl, NULL)) != 0)
- g_thread_abort (status, "pthread_cond_init");
+ cond->impl = g_cond_impl_new ();
}
/**
@@ -608,10 +717,7 @@ g_cond_init (GCond *cond)
void
g_cond_clear (GCond *cond)
{
- gint status;
-
- if G_UNLIKELY ((status = pthread_cond_destroy (&cond->impl)) != 0)
- g_thread_abort (status, "pthread_cond_destroy");
+ g_cond_impl_free (cond->impl);
}
/**
@@ -631,7 +737,7 @@ g_cond_wait (GCond *cond,
{
gint status;
- if G_UNLIKELY ((status = pthread_cond_wait (&cond->impl, &mutex->impl)) != 0)
+ if G_UNLIKELY ((status = pthread_cond_wait (g_cond_get_impl (cond), g_mutex_get_impl (mutex))) != 0)
g_thread_abort (status, "pthread_cond_wait");
}
@@ -652,7 +758,7 @@ g_cond_signal (GCond *cond)
{
gint status;
- if G_UNLIKELY ((status = pthread_cond_signal (&cond->impl)) != 0)
+ if G_UNLIKELY ((status = pthread_cond_signal (g_cond_get_impl (cond))) != 0)
g_thread_abort (status, "pthread_cond_signal");
}
@@ -673,7 +779,7 @@ g_cond_broadcast (GCond *cond)
{
gint status;
- if G_UNLIKELY ((status = pthread_cond_broadcast (&cond->impl)) != 0)
+ if G_UNLIKELY ((status = pthread_cond_broadcast (g_cond_get_impl (cond))) != 0)
g_thread_abort (status, "pthread_cond_broadcast");
}
@@ -714,7 +820,7 @@ g_cond_timed_wait (GCond *cond,
end_time.tv_sec = abs_time->tv_sec;
end_time.tv_nsec = abs_time->tv_usec * 1000;
- if ((status = pthread_cond_timedwait (&cond->impl, &mutex->impl, &end_time)) == 0)
+ if ((status = pthread_cond_timedwait (g_cond_get_impl (cond), g_mutex_get_impl (mutex), &end_time)) == 0)
return TRUE;
if G_UNLIKELY (status != ETIMEDOUT)
@@ -748,7 +854,7 @@ g_cond_timedwait (GCond *cond,
end_time.tv_sec = abs_time / 1000000;
end_time.tv_nsec = (abs_time % 1000000) * 1000;
- if ((status = pthread_cond_timedwait (&cond->impl, &mutex->impl, &end_time)) == 0)
+ if ((status = pthread_cond_timedwait (g_cond_get_impl (cond), g_mutex_get_impl (mutex), &end_time)) == 0)
return TRUE;
if G_UNLIKELY (status != ETIMEDOUT)
diff --git a/glib/gthread.h b/glib/gthread.h
index 93b78dd..4ef6bab 100644
--- a/glib/gthread.h
+++ b/glib/gthread.h
@@ -59,8 +59,6 @@ typedef struct _GCond GCond;
typedef struct _GPrivate GPrivate;
typedef struct _GStaticPrivate GStaticPrivate;
-#ifdef G_OS_WIN32
-
#define G_MUTEX_INIT { NULL }
struct _GMutex
{
@@ -78,33 +76,6 @@ struct _GCond
{
gpointer impl;
};
-#else
-
-#include <pthread.h>
-
-#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
-#define G_MUTEX_INIT { PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP }
-#else
-#define G_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER }
-#endif
-struct _GMutex
-{
- pthread_mutex_t impl;
-};
-
-#define G_RW_LOCK_INIT { PTHREAD_RWLOCK_INITIALIZER }
-struct _GRWLock
-{
- pthread_rwlock_t impl;
-};
-
-#define G_COND_INIT { PTHREAD_COND_INITIALIZER }
-struct _GCond
-{
- pthread_cond_t impl;
-};
-
-#endif
#define G_REC_MUTEX_INIT { NULL }
struct _GRecMutex
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]