rwlock different behavior on glibc 2.28 then on previous versions

David Mozes david.mozes@silk.us
Mon Mar 7 20:13:26 GMT 2022


I like to consult with you regarding the flowing issue

The rwlock rewrite commit:

commit cc25c8b4c1196a8c29e9a45b1e096b99a87b7f8c
Author: Torvald Riegel <triegel@redhat.com>
Date:   Thu May 22 16:00:12 2014 +0200

changed the behavior of the rwlock as well!

On the previous version of Glibc (before the commit) We could release write lock with different thread as the one that owned the lock (If we like) . This is help very much for async program that has a many threads that communicate with some target.
And we like to define a call back function instead of blocking on aio thread that send the data in order to release the rwlock.this improves the performance dramatically .
For backward compatibility and better performance  I suggest a small change as describe below:
Remove the THREAD_SELF checking(See below) ,unless this change is danger!

Does such fix is danger ?
Do you aware why this check was added in the first place?


Other option is to define anther function /Type that enable less restricted operation to not violate the API agreement and it will be on the user responsibly whether to use the new type or not for better performance.
What do you think?

Thx
David



The  previous code before  cc25c8b4c1196a8c29e9a45b1e096b99a87b7f8c was look like that:
__pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
{
  lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);
  if (rwlock->__data.__writer)
    rwlock->__data.__writer = 0;
  else
    --rwlock->__data.__nr_readers;
  if (rwlock->__data.__nr_readers == 0)
    {
      if (rwlock->__data.__nr_writers_queued)
        {

Our application has many inflight IO threads


After the cc25c8b4c1196a8c29e9a45b1e096b99a87b7f8c commit:

     int
___pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
{
  LIBC_PROBE (rwlock_unlock, 1, rwlock);

  /* We distinguish between having acquired a read vs. a write lock by looking
     at the writer TID.  If it's equal to our TID, we must be the writer
     because nobody else can have stored this value.  Also, if we are a
     reader, we will read from the wrunlock store with value 0 by the most
     recent writer because that writer happens-before us.  */
  if (atomic_load_relaxed (&rwlock->__data.__cur_writer)
      == THREAD_GETMEM (THREAD_SELF, tid))
      __pthread_rwlock_wrunlock (rwlock);
  else
    __pthread_rwlock_rdunlock (rwlock);
  return 0;
}





The change I propose is :


What do you think regarding such a small fix  like this:

   if (atomic_load_relaxed (&rwlock->__data.__cur_writer))
      __pthread_rwlock_wrunlock (rwlock);
  else
    __pthread_rwlock_rdunlock (rwlock);
  return 0;
}




More information about the Libc-help mailing list