* Author: Ryan Lortie <desrt@desrt.ca>
*/
+#include "config.h"
+
#include "gbitlock.h"
#include <glib/gmessages.h>
#include <glib/gslice.h>
#include "gthreadprivate.h"
-#include "config.h"
-
#ifdef G_BIT_LOCK_FORCE_FUTEX_EMULATION
#undef HAVE_FUTEX
#endif
#ifndef HAVE_FUTEX
-static GStaticMutex g_futex_mutex = G_STATIC_MUTEX_INIT;
+static GMutex g_futex_mutex;
static GSList *g_futex_address_list = NULL;
#endif
{
const volatile gint *address;
gint ref_count;
- GCond *wait_queue;
+ GCond wait_queue;
} WaitAddress;
static WaitAddress *
g_futex_wait (const volatile gint *address,
gint value)
{
- g_static_mutex_lock (&g_futex_mutex);
+ g_mutex_lock (&g_futex_mutex);
if G_LIKELY (g_atomic_int_get (address) == value)
{
WaitAddress *waiter;
{
waiter = g_slice_new (WaitAddress);
waiter->address = address;
- waiter->wait_queue = g_cond_new ();
+ g_cond_init (&waiter->wait_queue);
waiter->ref_count = 0;
g_futex_address_list =
g_slist_prepend (g_futex_address_list, waiter);
}
waiter->ref_count++;
- g_cond_wait (waiter->wait_queue, g_static_mutex_get_mutex (&g_futex_mutex));
+ g_cond_wait (&waiter->wait_queue, &g_futex_mutex);
if (!--waiter->ref_count)
{
g_futex_address_list =
g_slist_remove (g_futex_address_list, waiter);
- g_cond_free (waiter->wait_queue);
+ g_cond_clear (&waiter->wait_queue);
g_slice_free (WaitAddress, waiter);
}
}
- g_static_mutex_unlock (&g_futex_mutex);
+ g_mutex_unlock (&g_futex_mutex);
}
static void
* 2) need to -stay- locked until the end to ensure a wake()
* in another thread doesn't cause 'waiter' to stop existing
*/
- g_static_mutex_lock (&g_futex_mutex);
+ g_mutex_lock (&g_futex_mutex);
if ((waiter = g_futex_find_address (address)))
- g_cond_signal (waiter->wait_queue);
- g_static_mutex_unlock (&g_futex_mutex);
+ g_cond_signal (&waiter->wait_queue);
+ g_mutex_unlock (&g_futex_mutex);
}
#endif
* g_bit_trylock:
* @address: a pointer to an integer
* @lock_bit: a bit value between 0 and 31
- * @returns: %TRUE if the lock was acquired
*
* Sets the indicated @lock_bit in @address, returning %TRUE if
* successful. If the bit is already set, returns %FALSE immediately.
* @address must be atomic in order for this function to work
* reliably.
*
+ * Returns: %TRUE if the lock was acquired
+ *
* Since: 2.24
**/
gboolean
{
const volatile gint *int_address = address;
+ /* this implementation makes these (reasonable) assumptions: */
+ G_STATIC_ASSERT (G_BYTE_ORDER == G_LITTLE_ENDIAN ||
+ (G_BYTE_ORDER == G_BIG_ENDIAN &&
+ sizeof (int) == 4 &&
+ (sizeof (gpointer) == 4 || sizeof (gpointer) == 8)));
+
#if G_BYTE_ORDER == G_BIG_ENDIAN && GLIB_SIZEOF_VOID_P == 8
int_address++;
#endif
* g_pointer_bit_trylock:
* @address: a pointer to a #gpointer-sized value
* @lock_bit: a bit value between 0 and 31
- * @returns: %TRUE if the lock was acquired
*
* This is equivalent to g_bit_trylock, but working on pointers (or
* other pointer-sized values).
* For portability reasons, you may only lock on the bottom 32 bits of
* the pointer.
*
+ * Returns: %TRUE if the lock was acquired
+ *
* Since: 2.30
**/
gboolean