This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH 4/6] Do not call _xend if no transaction is active.
- From: Torvald Riegel <triegel at redhat dot com>
- To: libc-alpha at sourceware dot org
- Cc: Andi Kleen <andi at firstfloor dot org>
- Date: Wed, 11 Sep 2013 15:31:12 +0200
- Subject: Re: [PATCH 4/6] Do not call _xend if no transaction is active.
- Authentication-results: sourceware.org; auth=none
- References: <20130902075228 dot GA4792 at linux dot vnet dot ibm dot com> <20130902080450 dot GD4997 at linux dot vnet dot ibm dot com> <87fvtndjks dot fsf at tassilo dot jf dot intel dot com> <20130903074521 dot GC3368 at linux dot vnet dot ibm dot com>
On Tue, 2013-09-03 at 09:45 +0200, Dominik Vogt wrote:
> Example: A program uses glibc with lock elision and a library
> "foo". Foo provides the functions foo_lock() and foo_unlock() and
> also uses transactions. In foo it is perfectly valid to call
> foo_unlock() without foo_lock(). Let foo_unlock() be implemented
> like this (let's ignore any race conditions for simplicity):
>
> foo_unlock(foo_lock *x)
> {
> if (x->lock_count > 0)
> if (_xtest() != 0)
> _xend();
> else
> x->lock_count--;
> }
>
> If the program looks like this:
>
> foo_lock(x);
> phtread_mutex_lock(m);
foo(); // see below
> foo_unlock(x);
bar(); // see below
> phtread_mutex_unlock(m);
This is an incorrect use of transactions. When foo_unlock() commits a
transaction that it has not started, it potentially breaks the atomicity
guarantees of other code -- effectively, it makes the critical section
shorter. bar() would run nontransactionally, and thus, for example,
observe data that's been changed since it was observed in foo() -- same
as if foo_unlock() would release m early. This already can lead to all
sorts of crashes, and thus isn't a safe thing to do in general.
(One could argue that the program can rely on pthread_mutex_* to just
acquire/release this mutex in a traditional non-HLE way, without having
to rely on anything the program does. However, POSIX doesn't specify
what the implementation does, and foo_unlock() clearly messes with
potential implementations.)
Thus, I think that this is a buggy program and not a flaw in glibc.