public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "snyder at bnl dot gov" <sourceware-bugzilla@sourceware.org>
To: glibc-bugs@sourceware.org
Subject: [Bug nptl/16657] Lock elision breaks pthread_mutex_detroy
Date: Tue, 18 Mar 2014 15:31:00 -0000	[thread overview]
Message-ID: <bug-16657-131-jMhftjyFvQ@http.sourceware.org/bugzilla/> (raw)
In-Reply-To: <bug-16657-131@http.sourceware.org/bugzilla/>

https://sourceware.org/bugzilla/show_bug.cgi?id=16657

scott snyder <snyder at bnl dot gov> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |snyder at bnl dot gov

--- Comment #9 from scott snyder <snyder at bnl dot gov> ---

Just switched to a new machine and promptly ran into this problem...

The boost thread wrappers check the abort on a failing return
from pthread_mutex_destroy:

  ~mutex()
  {
    BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
  }

Locking multiple times, as in the attached test case, is not necessary;
i can reproduce the problem with sequence like this:

  pthread_mutex_t m;
  if (pthread_mutex_init(&m, NULL) != 0) abort();
  pthread_mutex_trylock(&m);
  pthread_mutex_unlock (&m);
  if (pthread_mutex_destroy (&m) != 0) abort();


I think i see what the problem is.

In pthread_mutex_lock, we have this sequence:

  if (__builtin_expect (type == PTHREAD_MUTEX_TIMED_NP, 1))
    {
      FORCE_ELISION (mutex, goto elision);

FORCE_ELISION sets the PTHREAD_MUTEX_ELISION_NP flag in the lock's
type field, and then proceeds to do the elided lock.  The owner/users
fields are not updated in this case.

In pthread_mutex_unlock the first test fails because elision bit is set;
the second succeeds, and we do the elided unlock which again does not
change the owner/users flags:

  if (__builtin_expect (type, PTHREAD_MUTEX_TIMED_NP)
      == PTHREAD_MUTEX_TIMED_NP)
    {
      /* Always reset the owner field.  */
      ...
    }
  else if (__builtin_expect (type == PTHREAD_MUTEX_TIMED_ELISION_NP, 1))
    {
      /* Don't reset the owner/users fields for elision.  */
      return lll_unlock_elision (mutex->__data.__lock,
                      PTHREAD_MUTEX_PSHARED (mutex));


In trylock, however, we use DO_ELISION rather than FORCE_ELISION:

    case PTHREAD_MUTEX_TIMED_ELISION_NP:
    elision:
      if (lll_trylock_elision (mutex->__data.__lock,
                   mutex->__data.__elision) != 0)
        break;
      /* Don't record the ownership.  */
      return 0;

    case PTHREAD_MUTEX_TIMED_NP:
      if (DO_ELISION (mutex))
    goto elision;
      /*FALL THROUGH*/


DO_ELISION does _not_ set the elision bit in the type field.
If the lock was orginally free, the trylock succeeds, and does not
adjust the owner/user fields.

But then when we try to unlock after a trylock, the elision bit is still
clear.  So we take the code path starting at the comment 

      /* Always reset the owner field.  */

which proceeds to decrement the user field, corrupting the lock.

This problem might be fixable by changing the DO_ELISION in
pthread_mutex_trylock to FORCE_ELISION (though i haven't yet tried that).

I have checked that if i do a pthread_mutex_lock/pthread_mutex_unlock
on the lock before the first trylock, then the problem goes away,
as expected from the above analysis (since the lock will set the
elision flag).

-- 
You are receiving this mail because:
You are on the CC list for the bug.


  parent reply	other threads:[~2014-03-18 15:31 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-04  9:07 [Bug nptl/16657] New: Lock elision breaks pthread_mutex_trylock schwab@linux-m68k.org
2014-03-04 12:03 ` [Bug nptl/16657] " schwab@linux-m68k.org
2014-03-04 17:51 ` bugdal at aerifal dot cx
2014-03-05  0:32 ` andi-bz at firstfloor dot org
2014-03-05  1:12 ` bugdal at aerifal dot cx
2014-03-05  8:51 ` schwab@linux-m68k.org
2014-03-05 14:14 ` matz at suse dot de
2014-03-05 14:18 ` [Bug nptl/16657] Lock elision breaks pthread_mutex_detroy schwab@linux-m68k.org
2014-03-05 17:57 ` bugdal at aerifal dot cx
2014-03-06 16:03 ` carlos at redhat dot com
2014-03-10 14:14 ` triegel at redhat dot com
2014-03-18 15:31 ` snyder at bnl dot gov [this message]
2014-04-04 22:31 ` andi-bz at firstfloor dot org
2014-04-07  9:28 ` schwab@linux-m68k.org
2014-05-28 12:09 ` cvs-commit at gcc dot gnu.org
2014-06-02 14:25 ` pspacek at redhat dot com
2014-06-13  6:39 ` [Bug nptl/16657] Lock elision breaks pthread_mutex_destroy fweimer at redhat dot com
2014-06-16 16:41 ` fweimer at redhat dot com
2014-06-16 16:49 ` bugdal at aerifal dot cx
2014-06-16 16:55 ` fweimer at redhat dot com
2014-06-16 17:10 ` schwab@linux-m68k.org
2014-06-17 17:39 ` cvs-commit at gcc dot gnu.org
2014-06-25 19:23 ` cvs-commit at gcc dot gnu.org
2014-07-02 15:48 ` jmbnyc at gmail dot com
2014-07-02 16:19 ` bugdal at aerifal dot cx
2014-07-02 17:19 ` jmbnyc at gmail dot com
2014-07-02 18:07 ` bugdal at aerifal dot cx
2014-07-02 18:18 ` jmbnyc at gmail dot com
2014-07-03  3:13 ` andi-bz at firstfloor dot org
2014-07-03  3:25 ` jmbnyc at gmail dot com
2014-07-03 16:51 ` schwab@linux-m68k.org
2014-07-21 20:43 ` cvs-commit at gcc dot gnu.org
2014-08-19  0:36 ` cvs-commit at gcc dot gnu.org
2014-08-22 11:52 ` cvs-commit at gcc dot gnu.org
2014-08-25 13:05 ` cvs-commit at gcc dot gnu.org
2014-08-25 13:10 ` azanella at linux dot vnet.ibm.com
2014-10-01 18:43 ` carlos at redhat dot com
2014-10-01 20:49 ` schwab@linux-m68k.org
2014-10-01 21:00 ` carlos at redhat dot com
2014-10-01 21:04 ` azanella at linux dot vnet.ibm.com
2014-10-02 14:02 ` schwab@linux-m68k.org
2014-11-07 17:06 ` cvs-commit at gcc dot gnu.org
2014-12-11 11:45 ` cvs-commit at gcc dot gnu.org
2014-12-11 11:48 ` schwab@linux-m68k.org
2014-12-11 11:48 ` schwab@linux-m68k.org
2015-02-18 14:45 ` fweimer at redhat dot com
2015-08-28 20:43 ` cvs-commit at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-16657-131-jMhftjyFvQ@http.sourceware.org/bugzilla/ \
    --to=sourceware-bugzilla@sourceware.org \
    --cc=glibc-bugs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).