mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 20:51:44 +00:00
futex: add double_unlock_hb()
Impact: cleanup The futex code uses double_lock_hb() which locks the hb->lock's in pointer value order. There is no parallel unlock routine, and the code unlocks them in name order, ignoring pointer value. This patch adds double_unlock_hb() to refactor the duplicated code segments. Build and boot tested on a 4 way Intel x86_64 workstation. Passes basic pthread_mutex and PI tests out of ltp/testcases/realtime. Signed-off-by: Darren Hart <dvhltc@us.ibm.com> Acked-by: Peter Zijlstra <peterz@infradead.org> Cc: Rusty Russell <rusty@rustcorp.com.au> LKML-Reference: <20090312075552.9856.48021.stgit@Aeon> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
de87fcc124
commit
5eb3dc62fc
@ -690,6 +690,19 @@ double_lock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
double_unlock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2)
|
||||
{
|
||||
if (hb1 <= hb2) {
|
||||
spin_unlock(&hb2->lock);
|
||||
if (hb1 < hb2)
|
||||
spin_unlock(&hb1->lock);
|
||||
} else { /* hb1 > hb2 */
|
||||
spin_unlock(&hb1->lock);
|
||||
spin_unlock(&hb2->lock);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wake up waiters matching bitset queued on this futex (uaddr).
|
||||
*/
|
||||
@ -767,9 +780,7 @@ retry:
|
||||
if (unlikely(op_ret < 0)) {
|
||||
u32 dummy;
|
||||
|
||||
spin_unlock(&hb1->lock);
|
||||
if (hb1 != hb2)
|
||||
spin_unlock(&hb2->lock);
|
||||
double_unlock_hb(hb1, hb2);
|
||||
|
||||
#ifndef CONFIG_MMU
|
||||
/*
|
||||
@ -833,9 +844,7 @@ retry:
|
||||
ret += op_ret;
|
||||
}
|
||||
|
||||
spin_unlock(&hb1->lock);
|
||||
if (hb1 != hb2)
|
||||
spin_unlock(&hb2->lock);
|
||||
double_unlock_hb(hb1, hb2);
|
||||
out_put_keys:
|
||||
put_futex_key(fshared, &key2);
|
||||
out_put_key1:
|
||||
@ -876,9 +885,7 @@ retry:
|
||||
ret = get_futex_value_locked(&curval, uaddr1);
|
||||
|
||||
if (unlikely(ret)) {
|
||||
spin_unlock(&hb1->lock);
|
||||
if (hb1 != hb2)
|
||||
spin_unlock(&hb2->lock);
|
||||
double_unlock_hb(hb1, hb2);
|
||||
|
||||
put_futex_key(fshared, &key2);
|
||||
put_futex_key(fshared, &key1);
|
||||
@ -925,9 +932,7 @@ retry:
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
spin_unlock(&hb1->lock);
|
||||
if (hb1 != hb2)
|
||||
spin_unlock(&hb2->lock);
|
||||
double_unlock_hb(hb1, hb2);
|
||||
|
||||
/* drop_futex_key_refs() must be called outside the spinlocks. */
|
||||
while (--drop_count >= 0)
|
||||
|
Loading…
Reference in New Issue
Block a user