This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[RESEND][PATCH][BZ #13690] pthread_mutex_unlock: pass down private as a local variable to lll_unlock.
- From: OndÅej BÃlka <neleai at seznam dot cz>
- To: Atsushi Nemoto <anemo at mba dot ocn dot ne dot jp>
- Cc: libc-alpha at sourceware dot org
- Date: Fri, 6 Dec 2013 20:01:59 +0100
- Subject: [RESEND][PATCH][BZ #13690] pthread_mutex_unlock: pass down private as a local variable to lll_unlock.
- Authentication-results: sourceware.org; auth=none
Hi, a related issue to semaphore races is a race in mutex unlocking.
I take description from bugzilla:
In nptl/pthread_mutex_unlock.c, lll_unlock() is called like this:
lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex));
And PTHREAD_MUTEX_PSHARED() is defined like this:
# define PTHREAD_MUTEX_PSHARED(m) \
((m)->__data.__kind & 128)
On most platforms, lll_unlock() is defined as a macro like this:
#define lll_unlock(lock, private) \
((void) ({ \
int *__futex = &(lock); \
int __val = atomic_exchange_rel (__futex, 0); \
if (__builtin_expect (__val > 1, 0)) \
lll_futex_wake (__futex, 1, private); \
}))
Thus, the lll_unlock() call in pthread_mutex_unlock.c will be expanded
as:
int *__futex = &(mutex->__data.__lock);
int __val = atomic_exchange_rel (__futex, 0);
if (__builtin_expect (__val > 1, 0)) /* A */
lll_futex_wake (__futex, 1, ((mutex)->__data.__kind & 128)); /* B
*/
There was a patch acked by Carlos but waiting for second review for
year.
Do we need this for 2.19?
My comment is that this problem migth be more general, so perhaps proper
solution is refactor macros, this will come as followup.
>From b3596e31a43a88841c71d0bcba6ef9b8b41e8a47 Mon Sep 17 00:00:00 2001
From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Date: Thu, 16 Feb 2012 23:07:28 +0900
Subject: [PATCH] pthread_mutex_unlock: pass down private as a local variable to lll_unlock
2012-02-16 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
[BZ 13690]
* pthread_mutex_unlock.c (__pthread_mutex_unlock_usercnt)
(__pthread_mutex_unlock_full): pass down private as a copy of
local variable to lll_unlock and lll_robust_unlock.
---
nptl/pthread_mutex_unlock.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c
index f9fe10b..fdb35a4 100644
--- a/nptl/pthread_mutex_unlock.c
+++ b/nptl/pthread_mutex_unlock.c
@@ -49,7 +49,8 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
--mutex->__data.__nusers;
/* Unlock. */
- lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex));
+ int private = PTHREAD_MUTEX_PSHARED (mutex);
+ lll_unlock (mutex->__data.__lock, private);
return 0;
}
else if (__builtin_expect (type == PTHREAD_MUTEX_RECURSIVE_NP, 1))
@@ -136,8 +137,8 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
--mutex->__data.__nusers;
/* Unlock. */
- lll_robust_unlock (mutex->__data.__lock,
- PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
+ int private = PTHREAD_ROBUST_MUTEX_PSHARED (mutex);
+ lll_robust_unlock (mutex->__data.__lock, private);
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
break;
--
1.7.0.4