linux/include/asm-ppc
Jakub Jelinek 4732efbeb9 [PATCH] FUTEX_WAKE_OP: pthread_cond_signal() speedup
ATM pthread_cond_signal is unnecessarily slow, because it wakes one waiter
(which at least on UP usually means an immediate context switch to one of
the waiter threads).  This waiter wakes up and after a few instructions it
attempts to acquire the cv internal lock, but that lock is still held by
the thread calling pthread_cond_signal.  So it goes to sleep and eventually
the signalling thread is scheduled in, unlocks the internal lock and wakes
the waiter again.

Now, before 2003-09-21 NPTL was using FUTEX_REQUEUE in pthread_cond_signal
to avoid this performance issue, but it was removed when locks were
redesigned to the 3 state scheme (unlocked, locked uncontended, locked
contended).

Following scenario shows why simply using FUTEX_REQUEUE in
pthread_cond_signal together with using lll_mutex_unlock_force in place of
lll_mutex_unlock is not enough and probably why it has been disabled at
that time:

The number is value in cv->__data.__lock.
        thr1            thr2            thr3
0       pthread_cond_wait
1       lll_mutex_lock (cv->__data.__lock)
0       lll_mutex_unlock (cv->__data.__lock)
0       lll_futex_wait (&cv->__data.__futex, futexval)
0                       pthread_cond_signal
1                       lll_mutex_lock (cv->__data.__lock)
1                                       pthread_cond_signal
2                                       lll_mutex_lock (cv->__data.__lock)
2                                         lll_futex_wait (&cv->__data.__lock, 2)
2                       lll_futex_requeue (&cv->__data.__futex, 0, 1, &cv->__data.__lock)
                          # FUTEX_REQUEUE, not FUTEX_CMP_REQUEUE
2                       lll_mutex_unlock_force (cv->__data.__lock)
0                         cv->__data.__lock = 0
0                         lll_futex_wake (&cv->__data.__lock, 1)
1       lll_mutex_lock (cv->__data.__lock)
0       lll_mutex_unlock (cv->__data.__lock)
          # Here, lll_mutex_unlock doesn't know there are threads waiting
          # on the internal cv's lock

Now, I believe it is possible to use FUTEX_REQUEUE in pthread_cond_signal,
but it will cost us not one, but 2 extra syscalls and, what's worse, one of
these extra syscalls will be done for every single waiting loop in
pthread_cond_*wait.

We would need to use lll_mutex_unlock_force in pthread_cond_signal after
requeue and lll_mutex_cond_lock in pthread_cond_*wait after lll_futex_wait.

Another alternative is to do the unlocking pthread_cond_signal needs to do
(the lock can't be unlocked before lll_futex_wake, as that is racy) in the
kernel.

I have implemented both variants, futex-requeue-glibc.patch is the first
one and futex-wake_op{,-glibc}.patch is the unlocking inside of the kernel.
 The kernel interface allows userland to specify how exactly an unlocking
operation should look like (some atomic arithmetic operation with optional
constant argument and comparison of the previous futex value with another
constant).

It has been implemented just for ppc*, x86_64 and i?86, for other
architectures I'm including just a stub header which can be used as a
starting point by maintainers to write support for their arches and ATM
will just return -ENOSYS for FUTEX_WAKE_OP.  The requeue patch has been
(lightly) tested just on x86_64, the wake_op patch on ppc64 kernel running
32-bit and 64-bit NPTL and x86_64 kernel running 32-bit and 64-bit NPTL.

With the following benchmark on UP x86-64 I get:

for i in nptl-orig nptl-requeue nptl-wake_op; do echo time elf/ld.so --library-path .:$i /tmp/bench; \
for j in 1 2; do echo ( time elf/ld.so --library-path .:$i /tmp/bench ) 2>&1; done; done
time elf/ld.so --library-path .:nptl-orig /tmp/bench
real 0m0.655s user 0m0.253s sys 0m0.403s
real 0m0.657s user 0m0.269s sys 0m0.388s
time elf/ld.so --library-path .:nptl-requeue /tmp/bench
real 0m0.496s user 0m0.225s sys 0m0.271s
real 0m0.531s user 0m0.242s sys 0m0.288s
time elf/ld.so --library-path .:nptl-wake_op /tmp/bench
real 0m0.380s user 0m0.176s sys 0m0.204s
real 0m0.382s user 0m0.175s sys 0m0.207s

The benchmark is at:
http://sourceware.org/ml/libc-alpha/2005-03/txt00001.txt
Older futex-requeue-glibc.patch version is at:
http://sourceware.org/ml/libc-alpha/2005-03/txt00002.txt
Older futex-wake_op-glibc.patch version is at:
http://sourceware.org/ml/libc-alpha/2005-03/txt00003.txt
Will post a new version (just x86-64 fixes so that the patch
applies against pthread_cond_signal.S) to libc-hacker ml soon.

Attached is the kernel FUTEX_WAKE_OP patch as well as a simple-minded
testcase that will not test the atomicity of the operation, but at least
check if the threads that should have been woken up are woken up and
whether the arithmetic operation in the kernel gave the expected results.

Acked-by: Ingo Molnar <mingo@redhat.com>
Cc: Ulrich Drepper <drepper@redhat.com>
Cc: Jamie Lokier <jamie@shareable.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-09-07 16:57:17 -07:00
..
8xx_immap.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
a.out.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
amigahw.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
amigaints.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
amigappc.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
amigayle.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
amipcmcia.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ans-lcd.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
atomic.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
backlight.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
bitops.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
bootinfo.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
bootx.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
bseip.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
btext.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
bug.h [PATCH] remove all kernel BUGs 2005-05-01 08:59:01 -07:00
byteorder.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
cache.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
cacheflush.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
checksum.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
commproc.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
cpm2.h [PATCH] ppc32: Add proper prototype for cpm2_reset() 2005-07-27 16:25:55 -07:00
cputable.h [PATCH] ppc32: Support 36-bit physical addressing on e500 2005-04-16 15:24:22 -07:00
current.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
dbdma.h [PATCH] ppc64: very basic desktop g5 sound support 2005-04-16 15:24:32 -07:00
delay.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
dma-mapping.h [PATCH] ppc32: fix asm-ppc/dma-mapping.h sparse warning 2005-09-05 00:05:55 -07:00
dma.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
elf.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
fcntl.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
floppy.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
futex.h [PATCH] FUTEX_WAKE_OP: pthread_cond_signal() speedup 2005-09-07 16:57:17 -07:00
gg2.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
gt64260_defs.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
gt64260.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
hardirq.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
harrier.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
hawk_defs.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
hawk.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
heathrow.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
highmem.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
hw_irq.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
hydra.h [PATCH] ppc trivial iomem annotations: chrp 2005-04-24 14:58:08 -07:00
i8259.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ibm4xx.h [PATCH] ppc32: Remove board support for REDWOOD 2005-09-05 00:05:54 -07:00
ibm44x.h [PATCH] ppc32: Fix PPC440SP SRAM controller DCRs 2005-08-18 12:53:58 -07:00
ibm403.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ibm405.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ibm_ocp_pci.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ibm_ocp.h [PATCH] ppc32: add missing sysfs node for ocp_func_emac_data.phy_feat_exc 2005-09-07 16:57:15 -07:00
ide.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
immap_85xx.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
immap_cpm2.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
io.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ipcbuf.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ipic.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
irq.h [PATCH] ppc32: Add ppc_sys descriptions for PowerQUICC II devices 2005-09-05 00:05:56 -07:00
kexec.h [PATCH] kexec-ppc: fix for ksysfs crash_notes 2005-07-12 16:01:03 -07:00
keylargo.h [PATCH] ppc64: very basic desktop g5 sound support 2005-04-16 15:24:32 -07:00
kgdb.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
kmap_types.h [PATCH] ppc32: Don't sleep in flush_dcache_icache_page() 2005-09-05 00:05:57 -07:00
m48t35.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
m8260_pci.h [PATCH] ppc32: Support for 82xx PQII on-chip PCI bridge 2005-05-28 16:46:15 -07:00
machdep.h [PATCH] kexec: kexec ppc support 2005-06-25 16:24:51 -07:00
macio.h [PATCH] openfirmware: generate device table for userspace 2005-07-06 12:55:20 -07:00
md.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mediabay.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mk48t59.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mmu_context.h [PATCH] ppc32: fix destroy_context() race condition 2005-07-13 11:25:24 -07:00
mmu.h [PATCH] ppc32: Add support for Freescale e200 (Book-E) core 2005-06-25 16:24:26 -07:00
mpc8xx.h [PATCH] ppc32: Remove board support for SPD823TS 2005-09-05 00:05:55 -07:00
mpc10x.h [PATCH] ppc32: Make the UARTs on MPC824x individual platform devices 2005-07-27 16:25:55 -07:00
mpc52xx_psc.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mpc52xx.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mpc83xx.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mpc85xx.h [PATCH] ppc32: Added support for all MPC8548 internal interrupts 2005-06-21 18:46:24 -07:00
mpc8260_pci9.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mpc8260.h [PATCH] ppc32: Add ppc_sys descriptions for PowerQUICC II devices 2005-09-05 00:05:56 -07:00
msgbuf.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
mv64x60_defs.h [PATCH] ppc32: mv64x60 updates & enhancements 2005-09-05 00:06:00 -07:00
mv64x60.h [PATCH] ppc32: mv64x60 updates & enhancements 2005-09-05 00:06:00 -07:00
nvram.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ocp_ids.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ocp.h [PATCH] ppc32: Remove FSL OCP support 2005-06-25 16:24:27 -07:00
of_device.h [PATCH] openfirmware: generate device table for userspace 2005-07-06 12:55:20 -07:00
ohare.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
open_pic.h [PATCH] ppc32: Bump PMU interrupt priority 2005-06-27 15:11:42 -07:00
page.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
param.h [PATCH] ppc32: add CONFIG_HZ 2005-09-05 00:05:58 -07:00
parport.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
pc_serial.h [PATCH] Serial: Split 8250 port table (part 2) 2005-06-29 18:45:19 +01:00
pci-bridge.h [PATCH] ppc iomem annotations: ->io_base_virt 2005-04-25 07:55:57 -07:00
pci.h [PATCH] pci and yenta: pcibios_bus_to_resource 2005-08-04 21:32:46 -07:00
perfmon.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
pgalloc.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
pgtable.h [PATCH] ppc32: ppc440 pagetable attributes (comments updates) 2005-08-06 09:23:57 -07:00
pmac_feature.h [PATCH] ppc64: Add missing include 2005-09-06 16:07:35 +10:00
pmac_low_i2c.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
pnp.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
posix_types.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ppc4xx_dma.h [PATCH] ppc32: fix ppc4xx stb03xxx dma build 2005-08-18 12:53:58 -07:00
ppc4xx_pic.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ppc_asm.h [PATCH] ppc32: add 440ep support 2005-08-01 19:14:01 -07:00
ppc_sys.h [PATCH] ppc32: ppc_sys system on chip identification additions 2005-09-05 00:05:58 -07:00
ppcboot.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
prep_nvram.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
processor.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
prom.h [PATCH] ppc32: fix compilation error in include/asm/prom.h 2005-04-16 15:24:28 -07:00
ptrace.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
raven.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
reg_booke.h [PATCH] ppc32: Add support for Freescale e200 (Book-E) core 2005-06-25 16:24:26 -07:00
reg.h [PATCH] ppc32: Add support for Freescale e200 (Book-E) core 2005-06-25 16:24:26 -07:00
residual.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
rheap.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
rtc.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
rwsem.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
scatterlist.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
seccomp.h Add missing asm-ppc/seccomp.h. Must learn to use git properly. 2005-05-11 11:36:21 +01:00
sections.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
segment.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
semaphore.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
serial.h [PATCH] ppc32: Remove board support for MCPN765 2005-09-05 00:05:54 -07:00
setup.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sigcontext.h [PATCH] ppc32: add <linux/compiler.h> to <asm/sigcontext.h> 2005-06-06 17:02:02 -07:00
signal.h [PATCH] asm/signal.h unification 2005-05-04 07:33:15 -07:00
smp.h [PATCH] smp_processor_id() cleanup 2005-06-21 18:46:13 -07:00
spinlock.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
stat.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
statfs.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
suspend.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
system.h [PATCH] ppc32: export cacheable_memcpy() 2005-09-05 00:06:00 -07:00
thread_info.h [PATCH] streamline preempt_count type across archs 2005-06-23 09:45:19 -07:00
time.h [PATCH] qualifiers in return types - easy cases 2005-08-23 18:43:45 -07:00
timex.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
tlb.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
tlbflush.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
todc.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
topology.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
traps.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
types.h [PATCH] sab: consolidate kmem_bufctl_t 2005-09-05 00:05:48 -07:00
uaccess.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ucontext.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
uninorth.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
unistd.h [PATCH] ppc32: inotify syscalls 2005-07-30 10:14:46 -07:00
user.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
vga.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
xmon.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
xparameters.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
zorro.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00