Re: making GStaticMutexes faster



Hi again,
 
> GMutex *
> g_static_mutex_get_mutex_impl (GMutex** mutex)
> {
>   GMutex *new_mutex;
> 
>   if (*mutex)
>     return *mutex;
> 
>   g_mutex_lock (g_mutex_protect_static_mutex_allocation);
> 
>   if (!(*mutex))
>     new_mutex = g_mutex_new ();
> 
>   g_mutex_unlock (g_mutex_protect_static_mutex_allocation);
> 
>   /* No problems with write reordering, as between here and the 
>      creation of new_mutex is a memory barrier */
> 
>   *mutex = new_mutex;
> 
>   return *mutex;
> }
> 
> So the only issue is indeed cache coherency. See my other reply as
> well.

Following up on myself, the above version of course is also broken, as again
there can be a race testing *mutex. The following version however should do,
what it is supposed to do:

GMutex *
g_static_mutex_get_mutex_impl (GMutex **mutex)
{
  if (*mutex)
    return *mutex;

  if (!g_thread_supported ())
    return NULL;

  g_assert (g_mutex_protect_static_mutex_allocation);

  g_mutex_lock (g_mutex_protect_static_mutex_allocation);

  if (!(*mutex))
    {
      GMutex *new_mutex = g_mutex_new (); 
      
      /* The following is a memory barrier to avoid the write 
       * to *new_mutex being reordered to after writing *mutex, 
       * which of course is only theoretically possible */
      g_mutex_lock (new_mutex);
      g_mutex_unlock (new_mutex);

      *mutex = new_mutex;
    }

  g_mutex_unlock (g_mutex_protect_static_mutex_allocation);
  
  return *mutex;
}

Ok?

Bye,
Sebastian
-- 
Sebastian Wilhelmi
mailto:wilhelmi ira uka de
http://goethe.ira.uka.de/~wilhelmi




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]