summaryrefslogtreecommitdiff
path: root/libpthread/nptl/sysdeps/unix/sysv
diff options
context:
space:
mode:
Diffstat (limited to 'libpthread/nptl/sysdeps/unix/sysv')
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/Makefile13
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in256
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/__syscall_error.c18
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/accept.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/Makefile2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h100
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h168
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/semaphore.h34
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/clone.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/createthread.c23
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/fork.c30
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h284
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/pt-vfork.S43
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c97
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/sem_post.c5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h177
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_create.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_delete.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_getoverr.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_gettime.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_settime.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/alpha/vfork.S46
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/Makefile13
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/Makefile.arch58
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/atomic.h122
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/pthreadtypes.h181
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h35
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/clone.S3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/createthread.c23
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/fork.c31
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.c134
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.h282
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/nptl-aeabi_unwind_cpp_pr1.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-__syscall_error.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-__syscall_rt_sigaction.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-gettimeofday.c5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-vfork.S38
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/pthread_once.c100
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h137
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c149
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c90
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind.h279
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/arm/vfork.S39
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h100
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h192
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/close.S21
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/connect.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/creat.S7
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/createthread.c24
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/exit-thread.S23
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/fork.c229
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/fork.h60
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/getpid.c64
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile13
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile.arch71
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h173
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h36
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/clone.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/createthread.c49
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/fork.c31
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S459
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S234
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S187
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S239
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S216
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S694
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S591
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S195
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S245
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S238
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S157
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S186
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S142
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S329
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S79
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S269
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevellock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevellock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelrobustlock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_barrier_wait.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_broadcast.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_signal.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_timedwait.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_wait.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_rdlock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedrdlock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedwrlock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_unlock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_wrlock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_post.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevellock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrobustlock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_barrier_wait.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_broadcast.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_signal.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_timedwait.S21
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_wait.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_rdlock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedrdlock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedwrlock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_unlock.S21
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_wrlock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_post.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h584
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-__syscall_error.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-vfork.S68
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S197
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_init.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_unlock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/smp.h56
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h155
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/i386/vfork.S38
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/internaltypes.h162
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c39
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c21
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c26
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c74
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym16
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c127
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c114
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym6
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym16
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/lseek.S7
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile13
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile.arch50
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/bits/pthreadtypes.h229
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/bits/semaphore.h37
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/createthread.c24
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/fork.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/lowlevellock.h295
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-__syscall_rt_sigaction.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-clone.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-vfork.S38
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/pthread_once.c95
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h188
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mq_notify.c286
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/msync.S7
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/nanosleep.S9
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h105
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/open.S21
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pause.S7
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h221
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h41
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c25
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/fork.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h314
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/not-cancel.h1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S9
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/pt-vfork.S49
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h119
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S57
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S9
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/pt-vfork.S49
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h125
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_create.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_delete.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_getoverr.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_gettime.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_settime.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S55
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c37
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c101
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c29
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c47
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-accept.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-close.S9
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-connect.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-fcntl.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-fork.c29
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-fsync.c2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-llseek.c3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-lseek.S7
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-msgrcv.c2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-msgsnd.c2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-msync.S7
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-nanosleep.S9
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-open.S9
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-open64.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-pause.S7
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-pread_pwrite.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-raise.c52
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-read.S9
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-recv.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-recvfrom.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-recvmsg.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-send.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-sendmsg.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-sendto.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-sigwait.c2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-sleep.c2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-tcdrain.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-wait.c2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-waitpid.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pt-write.S9
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym8
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c54
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c80
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getaffinity.c46
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c57
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pthread_kill.c78
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c14
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c91
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pthread_sigqueue.c83
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pthread_yield.c30
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/raise.c74
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/read.S19
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/recv.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/recvfrom.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/recvmsg.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/register-atfork.c149
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sem_post.c58
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c111
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sem_trywait.c44
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sem_wait.c84
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/send.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sendmsg.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sendto.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile13
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch85
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h183
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h36
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/clone.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/createthread.c24
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/fork.c30
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S19
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h81
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S540
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h420
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S265
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pt-initfini.c126
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pt-vfork.S65
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S216
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S263
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S190
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S861
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S754
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S263
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S255
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S314
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S298
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S199
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S235
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S110
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S358
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S90
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S303
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h4
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/smp.h24
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h169
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/vfork.S71
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sigtimedwait.c88
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sigwait.c2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sigwaitinfo.c88
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sleep.c2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/smp.h28
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile13
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch67
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h100
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h221
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h41
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/clone.S5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/fork.c29
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/internaltypes.h34
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/libc-lowlevellock.c21
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c133
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h297
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pt-vfork.S5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_destroy.c45
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_init.c55
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_wait.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c95
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c57
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S45
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c94
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c55
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c148
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c54
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c127
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h112
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S49
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S45
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h110
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_create.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_delete.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_getoverr.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_gettime.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_settime.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S49
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sparc/vfork.S5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/structsem.sym12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/timer_create.c243
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/timer_delete.c115
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/timer_getoverr.c81
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c83
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/timer_routines.c204
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c88
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c123
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/unwindbuf.sym7
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/waitpid.S19
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/write.S19
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile13
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile.arch78
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h225
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h41
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S116
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/compat-timer.h46
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/fork.c31
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S22
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S20
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S22
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S457
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h598
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S306
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-__syscall_error.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-vfork.S33
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S161
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S178
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S161
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S804
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S487
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S190
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S180
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S276
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S268
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S131
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S168
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c14
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_init.c1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_unlock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S89
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S379
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S52
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S174
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h111
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S43
350 files changed, 31183 insertions, 0 deletions
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile
new file mode 100644
index 000000000..34d647527
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile
@@ -0,0 +1,13 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../../../../
+top_builddir=../../../../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.in
+include $(top_srcdir)Makerules
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in
new file mode 100644
index 000000000..ac642f272
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in
@@ -0,0 +1,256 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+libpthread_CSRC = pthread_attr_getaffinity.c \
+ pthread_attr_setaffinity.c pthread_getaffinity.c \
+ pthread_getcpuclockid.c pthread_kill.c \
+ pthread_mutex_cond_lock.c pthread_setaffinity.c \
+ pthread_yield.c sem_post.c sem_timedwait.c \
+ pthread_sigqueue.c \
+ sem_trywait.c sem_wait.c pt-fork.c \
+ sigtimedwait.c sigwaitinfo.c sigwait.c pt-sleep.c
+
+libpthread_SSRC = #ptw-close.S ptw-open.S ptw-waitid.S ptw-waidpid.S ptw-write.S
+
+libc_CSRC = libc_pthread_init.c libc_multiple_threads.c \
+ register-atfork.c unregister-atfork.c getpid.c \
+ raise.c sleep.c jmp-unwind.c
+
+# These provide both a cancellable and a not cancellable implementation
+libc_SSRC = close.S open.S write.S read.S waitpid.S
+
+librt_CSRC := mq_notify.c timer_create.c timer_delete.c \
+ timer_getoverr.c timer_gettime.c timer_routines.c \
+ timer_settime.c
+
+
+ifeq ($(TARGET_ARCH),alpha)
+libpthread_CSRC += lowlevellock.c
+libc_CSRC += libc-lowlevellock.c
+librt_CSRC := mq_notify.c
+endif
+
+ifeq ($(TARGET_ARCH),arm)
+libc_SSRC := $(filter-out waitpid.S,$(libc_SSRC))
+libpthread_CSRC += lowlevelrobustlock.c
+endif
+
+ifeq ($(TARGET_ARCH),mips)
+libpthread_CSRC += lowlevellock.c lowlevelrobustlock.c
+libc_CSRC += libc-lowlevellock.c
+endif
+
+ifeq ($(TARGET_ARCH),powerpc)
+libpthread_CSRC += lowlevellock.c
+libc_CSRC += libc-lowlevellock.c
+librt_CSRC := mq_notify.c
+endif
+
+ifeq ($(TARGET_ARCH),sparc)
+libpthread_CSRC += __syscall_error.c lowlevelrobustlock.c
+librt_CSRC += __syscall_error.c
+endif
+
+ifeq ($(TARGET_ARCH),sh)
+SH_PTHREAD_SPECIFIC := sem_post.c sem_wait.c sem_timedwait.c sem_trywait.c
+libpthread_CSRC := $(filter-out $(SH_PTHREAD_SPECIFIC),$(libpthread_CSRC))
+endif
+
+ifeq ($(TARGET_ARCH),i386)
+X86_PTHREAD_SPECIFIC := sem_post.c sem_wait.c sem_timedwait.c sem_trywait.c
+libpthread_CSRC := $(filter-out $(X86_PTHREAD_SPECIFIC),$(libpthread_CSRC))
+endif
+
+ifeq ($(TARGET_ARCH),x86_64)
+libc_SSRC := $(filter-out waitpid.S,$(libc_SSRC))
+X64_PTHREAD_SPECIFIC := sem_post.c sem_wait.c sem_timedwait.c sem_trywait.c
+libpthread_CSRC := $(filter-out $(X64_PTHREAD_SPECIFIC),$(libpthread_CSRC))
+endif
+
+CFLAGS-pthread_getcpuclockid.c = -I$(top_srcdir)librt
+CFLAGS-pt-pread_pwrite.c = -I$(top_srcdir)libc/sysdeps/linux/$(TARGET_ARCH) \
+ -I$(top_srcdir)libc/sysdeps/linux/common
+CFLAGS-mq_notify.c = -I$(top_srcdir)librt -DIS_IN_librt=1
+CFLAGS-timer_create.c = -I$(top_srcdir)librt -DIS_IN_librt=1
+CFLAGS-timer_delete.c = -I$(top_srcdir)librt -DIS_IN_librt=1
+CFLAGS-timer_getoverr.c = -I$(top_srcdir)librt -DIS_IN_librt=1
+CFLAGS-timer_gettime.c = -I$(top_srcdir)librt -DIS_IN_librt=1
+CFLAGS-timer_routines.c = -I$(top_srcdir)librt -DIS_IN_librt=1
+CFLAGS-timer_settime.c = -I$(top_srcdir)librt -DIS_IN_librt=1
+
+CFLAGS-linux = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 $(SSP_ALL_CFLAGS)
+#CFLAGS:=$(CFLAGS:-O1=-O2)
+
+CFLAGS-OMIT-libc_pthread_init.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-libc_multiple_threads.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-register-atfork.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-unregister-atfork.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-getpid.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-raise.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-sleep.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-libc-lowlevellock.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
+CFLAGS-OMIT-close.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-open.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-read.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-write.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-waitpid.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
+CFLAGS-OMIT-mq_notify.c = -DIS_IN_libpthread=1
+CFLAGS-OMIT-timer_create.c = -DIS_IN_libpthread=1
+CFLAGS-OMIT-timer_delete.c = -DIS_IN_libpthread=1
+CFLAGS-OMIT-timer_getoverr.c = -DIS_IN_libpthread=1
+CFLAGS-OMIT-timer_gettime.c = -DIS_IN_libpthread=1
+CFLAGS-OMIT-timer_routines.c = -DIS_IN_libpthread=1
+CFLAGS-OMIT-timer_settime.c = -DIS_IN_libpthread=1
+
+PTHREAD_LINUX_DIR := $(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux
+PTHREAD_LINUX_OUT := $(top_builddir)libpthread/nptl/sysdeps/unix/sysv/linux
+
+PTHREAD_LINUX_OBJ := $(patsubst %.c,$(PTHREAD_LINUX_OUT)/%.o,$(libpthread_CSRC))
+PTHREAD_LINUX_OBJ += $(patsubst %.S,$(PTHREAD_LINUX_OUT)/%.o,$(libpthread_SSRC))
+
+ifeq ($(DOPIC),y)
+libpthread-a-y += $(PTHREAD_LINUX_OBJ:.o=.os)
+else
+libpthread-a-y += $(PTHREAD_LINUX_OBJ)
+endif
+libpthread-so-y += $(PTHREAD_LINUX_OBJ:.o=.oS)
+libpthread-so-y += $(PTHREAD_LINUX_OUT)/pt-raise.oS
+libpthread-nomulti-y += $(PTHREAD_LINUX_OBJ)
+
+ASFLAGS-open.S = -D_LIBC_REENTRANT
+ASFLAGS-close.S = -D_LIBC_REENTRANT
+ASFLAGS-read.S = -D_LIBC_REENTRANT
+ASFLAGS-write.S = -D_LIBC_REENTRANT
+ASFLAGS-waitpid.S = -D_LIBC_REENTRANT
+
+LIBC_LINUX_OBJ := $(patsubst %.c,$(PTHREAD_LINUX_OUT)/%.o,$(libc_CSRC))
+LIBC_LINUX_OBJ += $(patsubst %.S,$(PTHREAD_LINUX_OUT)/%.o,$(libc_SSRC))
+
+libc-static-y += $(LIBC_LINUX_OBJ)
+libc-shared-y += $(LIBC_LINUX_OBJ:.o=.oS)
+libc-nomulti-y += $(LIBC_LINUX_OBJ)
+
+LIBRT_LINUX_OBJ := $(patsubst %.c,$(PTHREAD_LINUX_OUT)/%.o,$(librt_CSRC))
+
+librt-a-y += $(LIBRT_LINUX_OBJ)
+librt-so-y += $(LIBRT_LINUX_OBJ:.o=.oS)
+
+objclean-y += nptl_linux_clean
+headers_clean-y += nptl_linux_headers_clean
+
+#
+# Create header files.
+#
+CFLAGS-gen_lowlevelbarrier.c = -S
+CFLAGS-gen_lowlevelcond.c = -S
+CFLAGS-gen_lowlevelrwlock.c = -S
+CFLAGS-gen_lowlevelrobustlock.c = -S
+CFLAGS-gen_lunwindbuf.c = -S
+CFLAGS-gen_lstructsem.c = -S
+CFLAGS-gen_lpthread-pi-defines.c = -S
+
+$(PTHREAD_LINUX_OUT)/gen_lowlevelbarrier.c: $(PTHREAD_LINUX_DIR)/lowlevelbarrier.sym
+ $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@
+
+$(PTHREAD_LINUX_OUT)/gen_lowlevelcond.c: $(PTHREAD_LINUX_DIR)/lowlevelcond.sym
+ $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@
+
+$(PTHREAD_LINUX_OUT)/gen_lowlevelrwlock.c: $(PTHREAD_LINUX_DIR)/lowlevelrwlock.sym
+ $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@
+
+$(PTHREAD_LINUX_OUT)/gen_lowlevelrobustlock.c: $(PTHREAD_LINUX_DIR)/lowlevelrobustlock.sym
+ $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@
+
+$(PTHREAD_LINUX_OUT)/gen_lunwindbuf.c: $(PTHREAD_LINUX_DIR)/unwindbuf.sym
+ $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@
+
+$(PTHREAD_LINUX_OUT)/gen_lstructsem.c: $(PTHREAD_LINUX_DIR)/structsem.sym
+ $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@
+
+$(PTHREAD_LINUX_OUT)/gen_lpthread-pi-defines.c: $(PTHREAD_LINUX_DIR)/pthread-pi-defines.sym
+ $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@
+
+
+$(PTHREAD_LINUX_OUT)/gen_lowlevelbarrier.s: $(PTHREAD_LINUX_OUT)/gen_lowlevelbarrier.c
+ $(compile.c)
+
+$(PTHREAD_LINUX_OUT)/gen_lowlevelcond.s: $(PTHREAD_LINUX_OUT)/gen_lowlevelcond.c
+ $(compile.c)
+
+$(PTHREAD_LINUX_OUT)/gen_lowlevelrwlock.s: $(PTHREAD_LINUX_OUT)/gen_lowlevelrwlock.c
+ $(compile.c)
+
+$(PTHREAD_LINUX_OUT)/gen_lowlevelrobustlock.s: $(PTHREAD_LINUX_OUT)/gen_lowlevelrobustlock.c
+ $(compile.c)
+
+$(PTHREAD_LINUX_OUT)/gen_lunwindbuf.s: $(PTHREAD_LINUX_OUT)/gen_lunwindbuf.c
+ $(compile.c)
+
+$(PTHREAD_LINUX_OUT)/gen_lstructsem.s: $(PTHREAD_LINUX_OUT)/gen_lstructsem.c
+ $(compile.c)
+
+$(PTHREAD_LINUX_OUT)/gen_lpthread-pi-defines.s: $(PTHREAD_LINUX_OUT)/gen_lpthread-pi-defines.c
+ $(compile.c)
+
+
+$(PTHREAD_LINUX_OUT)/lowlevelbarrier.h: $(PTHREAD_LINUX_OUT)/gen_lowlevelbarrier.s
+ $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@
+
+$(PTHREAD_LINUX_OUT)/lowlevelcond.h: $(PTHREAD_LINUX_OUT)/gen_lowlevelcond.s
+ $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@
+
+$(PTHREAD_LINUX_OUT)/lowlevelrwlock.h: $(PTHREAD_LINUX_OUT)/gen_lowlevelrwlock.s
+ $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@
+
+$(PTHREAD_LINUX_OUT)/lowlevelrobustlock.h: $(PTHREAD_LINUX_OUT)/gen_lowlevelrobustlock.s
+ $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@
+
+$(PTHREAD_LINUX_OUT)/unwindbuf.h: $(PTHREAD_LINUX_OUT)/gen_lunwindbuf.s
+ $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@
+
+$(PTHREAD_LINUX_OUT)/structsem.h: $(PTHREAD_LINUX_OUT)/gen_lstructsem.s
+ $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@
+
+$(PTHREAD_LINUX_OUT)/pthread-pi-defines.h: $(PTHREAD_LINUX_OUT)/gen_lpthread-pi-defines.s
+ $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@
+
+pregen-headers-$(UCLIBC_HAS_THREADS_NATIVE) += \
+ $(PTHREAD_LINUX_OUT)/lowlevelbarrier.h \
+ $(PTHREAD_LINUX_OUT)/lowlevelcond.h \
+ $(PTHREAD_LINUX_OUT)/lowlevelrwlock.h \
+ $(PTHREAD_LINUX_OUT)/lowlevelrobustlock.h \
+ $(PTHREAD_LINUX_OUT)/unwindbuf.h \
+ $(PTHREAD_LINUX_OUT)/structsem.h \
+ $(PTHREAD_LINUX_OUT)/pthread-pi-defines.h
+
+HEADERS_BITS_PTHREAD := $(notdir $(wildcard $(PTHREAD_LINUX_DIR)/bits/*.h))
+ALL_HEADERS_BITS_PTHREAD := $(addprefix include/bits/,$(HEADERS_BITS_PTHREAD))
+
+$(ALL_HEADERS_BITS_PTHREAD):
+ $(do_ln) ../../$(PTHREAD_LINUX_DIR)/bits/$(@F) $(top_builddir)$@
+
+nptl_linux_headers_clean:
+ $(do_rm) $(addprefix $(PTHREAD_LINUX_OUT)/gen_lowlevelbarrier., c s) \
+ $(addprefix $(PTHREAD_LINUX_OUT)/gen_lowlevelcond., c s) \
+ $(addprefix $(PTHREAD_LINUX_OUT)/gen_lowlevelrwlock., c s) \
+ $(addprefix $(PTHREAD_LINUX_OUT)/gen_lowlevelrobustlock., c s) \
+ $(addprefix $(PTHREAD_LINUX_OUT)/gen_lunwindbuf., c s) \
+ $(addprefix $(PTHREAD_LINUX_OUT)/gen_lstructsem., c s) \
+ $(addprefix $(PTHREAD_LINUX_OUT)/gen_lpthread-pi-defines., c s) \
+ $(PTHREAD_LINUX_OUT)/lowlevelbarrier.h \
+ $(PTHREAD_LINUX_OUT)/lowlevelcond.h \
+ $(PTHREAD_LINUX_OUT)/lowlevelrwlock.h \
+ $(PTHREAD_LINUX_OUT)/lowlevelrobustlock.h \
+ $(PTHREAD_LINUX_OUT)/unwindbuf.h \
+ $(PTHREAD_LINUX_OUT)/structsem.h \
+ $(PTHREAD_LINUX_OUT)/pthread-pi-defines.h
+
+
+nptl_linux_clean:
+ $(do_rm) $(addprefix $(PTHREAD_LINUX_OUT)/*., o os oS)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/__syscall_error.c b/libpthread/nptl/sysdeps/unix/sysv/linux/__syscall_error.c
new file mode 100644
index 000000000..5e109a83b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/__syscall_error.c
@@ -0,0 +1,18 @@
+/* Wrapper for setting errno.
+ *
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <errno.h>
+#include <features.h>
+
+/* This routine is jumped to by all the syscall handlers, to stash
+ * an error number into errno. */
+int __syscall_error(int err_no) attribute_hidden;
+int __syscall_error(int err_no)
+{
+ __set_errno(err_no);
+ return -1;
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/accept.S b/libpthread/nptl/sysdeps/unix/sysv/linux/accept.S
new file mode 100644
index 000000000..529763d80
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/accept.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_accept
+#error Missing definition of NR_accept needed for cancellation.
+#endif
+PSEUDO (__libc_accept, accept, 3)
+ret
+PSEUDO_END(__libc_accept)
+libc_hidden_def (__libc_accept)
+weak_alias (__libc_accept, __accept)
+libc_hidden_weak (__accept)
+weak_alias (__libc_accept, accept)
+libc_hidden_weak (accept)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/Makefile
new file mode 100644
index 000000000..8c8084079
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/Makefile
@@ -0,0 +1,2 @@
+# pull in __syscall_error routine, __sigprocmask, __syscall_rt_sigaction
+libpthread-routines += ptw-sysdep ptw-sigprocmask ptw-rt_sigaction
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h
new file mode 100644
index 000000000..a7c9740a0
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h
@@ -0,0 +1,100 @@
+/* Minimum guaranteed maximum values for system limits. Linux/Alpha version.
+ Copyright (C) 1993-1998,2000,2002-2004,2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* The kernel header pollutes the namespace with the NR_OPEN symbol
+ and defines LINK_MAX although filesystems have different maxima. A
+ similar thing is true for OPEN_MAX: the limit can be changed at
+ runtime and therefore the macro must not be defined. Remove this
+ after including the header if necessary. */
+#ifndef NR_OPEN
+# define __undef_NR_OPEN
+#endif
+#ifndef LINK_MAX
+# define __undef_LINK_MAX
+#endif
+#ifndef OPEN_MAX
+# define __undef_OPEN_MAX
+#endif
+#ifndef ARG_MAX
+# define __undef_ARG_MAX
+#endif
+
+/* The kernel sources contain a file with all the needed information. */
+#include <linux/limits.h>
+
+/* Have to remove NR_OPEN? */
+#ifdef __undef_NR_OPEN
+# undef NR_OPEN
+# undef __undef_NR_OPEN
+#endif
+/* Have to remove LINK_MAX? */
+#ifdef __undef_LINK_MAX
+# undef LINK_MAX
+# undef __undef_LINK_MAX
+#endif
+/* Have to remove OPEN_MAX? */
+#ifdef __undef_OPEN_MAX
+# undef OPEN_MAX
+# undef __undef_OPEN_MAX
+#endif
+/* Have to remove ARG_MAX? */
+#ifdef __undef_ARG_MAX
+# undef ARG_MAX
+# undef __undef_ARG_MAX
+#endif
+
+/* The number of data keys per process. */
+#define _POSIX_THREAD_KEYS_MAX 128
+/* This is the value this implementation supports. */
+#define PTHREAD_KEYS_MAX 1024
+
+/* Controlling the iterations of destructors for thread-specific data. */
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+/* Number of iterations this implementation does. */
+#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+
+/* The number of threads per process. */
+#define _POSIX_THREAD_THREADS_MAX 64
+/* We have no predefined limit on the number of threads. */
+#undef PTHREAD_THREADS_MAX
+
+/* Maximum amount by which a process can descrease its asynchronous I/O
+ priority level. */
+#define AIO_PRIO_DELTA_MAX 20
+
+/* Minimum size for a thread. We are free to choose a reasonable value. */
+#define PTHREAD_STACK_MIN 24576
+
+/* Maximum number of timer expiration overruns. */
+#define DELAYTIMER_MAX 2147483647
+
+/* Maximum tty name length. */
+#define TTY_NAME_MAX 32
+
+/* Maximum login name length. This is arbitrary. */
+#define LOGIN_NAME_MAX 256
+
+/* Maximum host name length. */
+#define HOST_NAME_MAX 64
+
+/* Maximum message queue priority level. */
+#define MQ_PRIO_MAX 32768
+
+/* Maximum value the semaphore can have. */
+#define SEM_VALUE_MAX (2147483647)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
new file mode 100644
index 000000000..41c0be197
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
@@ -0,0 +1,168 @@
+/* Machine-specific pthread type layouts. Alpha version.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H 1
+
+#define __SIZEOF_PTHREAD_ATTR_T 56
+#define __SIZEOF_PTHREAD_MUTEX_T 40
+#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+#define __SIZEOF_PTHREAD_COND_T 48
+#define __SIZEOF_PTHREAD_CONDATTR_T 4
+#define __SIZEOF_PTHREAD_RWLOCK_T 56
+#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+#define __SIZEOF_PTHREAD_BARRIER_T 32
+#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+
+
+/* Thread identifiers. The structure of the attribute type is
+ deliberately not exposed. */
+typedef unsigned long int pthread_t;
+
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_ATTR_T];
+ long int __align;
+} pthread_attr_t;
+
+
+typedef struct __pthread_internal_list
+{
+ struct __pthread_internal_list *__prev;
+ struct __pthread_internal_list *__next;
+} __pthread_list_t;
+
+
+/* Data structures for mutex handling. The structure of the attribute
+ type is deliberately not exposed. */
+typedef union
+{
+ struct __pthread_mutex_s
+ {
+ int __lock;
+ unsigned int __count;
+ int __owner;
+ unsigned int __nusers;
+ /* KIND must stay at this position in the structure to maintain
+ binary compatibility. */
+ int __kind;
+ int __spins;
+ __pthread_list_t __list;
+#define __PTHREAD_MUTEX_HAVE_PREV 1
+ } __data;
+ char __size[__SIZEOF_PTHREAD_MUTEX_T];
+ long int __align;
+} pthread_mutex_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+ int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling. The structure of
+ the attribute type is deliberately not exposed. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned int __futex;
+ __extension__ unsigned long long int __total_seq;
+ __extension__ unsigned long long int __wakeup_seq;
+ __extension__ unsigned long long int __woken_seq;
+ void *__mutex;
+ unsigned int __nwaiters;
+ unsigned int __broadcast_seq;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_COND_T];
+ __extension__ long long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+ int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Data structure for read-write lock variable handling. The
+ structure of the attribute type is deliberately not exposed. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned int __nr_readers;
+ unsigned int __readers_wakeup;
+ unsigned int __writer_wakeup;
+ unsigned int __nr_readers_queued;
+ unsigned int __nr_writers_queued;
+ int __writer;
+ int __shared;
+ unsigned long int __pad1;
+ unsigned long int __pad2;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned int __flags;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+ long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+ long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type. */
+typedef volatile int pthread_spinlock_t;
+
+/* POSIX barriers data type. The structure of the type is
+ deliberately not exposed. */
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIER_T];
+ long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+ int __align;
+} pthread_barrierattr_t;
+#endif
+
+
+#endif /* bits/pthreadtypes.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/semaphore.h
new file mode 100644
index 000000000..be4469c69
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/bits/semaphore.h
@@ -0,0 +1,34 @@
+/* Machine-specific POSIX semaphore type layouts. Alpha version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+# define __SIZEOF_SEM_T 32
+
+/* Value returned if `sem_open' failed. */
+#define SEM_FAILED ((sem_t *) 0)
+
+
+typedef union
+{
+ char __size[__SIZEOF_SEM_T];
+ long int __align;
+} sem_t;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/clone.S
new file mode 100644
index 000000000..eea1cbeed
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/clone.S
@@ -0,0 +1,2 @@
+#define RESET_PID
+#include <sysdeps/unix/sysv/linux/alpha/clone.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/createthread.c
new file mode 100644
index 000000000..6a51e73da
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/createthread.c
@@ -0,0 +1,23 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Value passed to 'clone' for initialization of the thread register. */
+#define TLS_VALUE (pd + 1)
+
+/* Get the real implementation. */
+#include <nptl/sysdeps/pthread/createthread.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/fork.c
new file mode 100644
index 000000000..ca85fc008
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/fork.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sched.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+
+
+#define ARCH_FORK() \
+ INLINE_SYSCALL (clone, 5, \
+ CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \
+ NULL, NULL, &THREAD_SELF->tid, NULL)
+
+#include "../fork.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
new file mode 100644
index 000000000..b7f4de338
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
@@ -0,0 +1,284 @@
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Libr \ary; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H 1
+
+#include <time.h>
+#include <sys/param.h>
+#include <bits/pthreadtypes.h>
+#include <atomic.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+
+
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_REQUEUE 3
+#define FUTEX_CMP_REQUEUE 4
+#define FUTEX_WAKE_OP 5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_WAIT_BITSET 9
+#define FUTEX_WAKE_BITSET 10
+#define FUTEX_PRIVATE_FLAG 128
+#define FUTEX_CLOCK_REALTIME 256
+
+#define FUTEX_BITSET_MATCH_ANY 0xffffffff
+
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
+ & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
+
+#define lll_futex_wait(futexp, val, private) \
+ lll_futex_timed_wait (futexp, val, NULL, private)
+
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAIT, private), \
+ (val), (timespec)); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __ret; \
+ })
+
+#define lll_futex_wake(futexp, nr, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAKE, private), \
+ (nr), 0); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __ret; \
+ })
+
+#define lll_robust_dead(futexv, private) \
+ do \
+ { \
+ int *__futexp = &(futexv); \
+ atomic_or (__futexp, FUTEX_OWNER_DIED); \
+ lll_futex_wake (__futexp, 1, private); \
+ } \
+ while (0)
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+ (nr_wake), (nr_move), (mutex), (val)); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_WAKE_OP, private), \
+ (nr_wake), (nr_wake2), (futexp2), \
+ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+
+
+
+static inline int __attribute__((always_inline))
+__lll_trylock(int *futex)
+{
+ return atomic_compare_and_exchange_val_acq (futex, 1, 0) != 0;
+}
+#define lll_trylock(lock) __lll_trylock (&(lock))
+
+
+static inline int __attribute__((always_inline))
+__lll_cond_trylock(int *futex)
+{
+ return atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0;
+}
+#define lll_cond_trylock(lock) __lll_cond_trylock (&(lock))
+
+
+static inline int __attribute__((always_inline))
+__lll_robust_trylock(int *futex, int id)
+{
+ return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0;
+}
+#define lll_robust_trylock(lock, id) \
+ __lll_robust_trylock (&(lock), id)
+
+extern void __lll_lock_wait_private (int *futex) attribute_hidden;
+extern void __lll_lock_wait (int *futex, int private) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden;
+
+static inline void __attribute__((always_inline))
+__lll_lock(int *futex, int private)
+{
+ if (atomic_compare_and_exchange_bool_acq (futex, 1, 0) != 0)
+ {
+ if (__builtin_constant_p (private) && private == LLL_PRIVATE)
+ __lll_lock_wait_private (futex);
+ else
+ __lll_lock_wait (futex, private);
+ }
+}
+#define lll_lock(futex, private) __lll_lock (&(futex), private)
+
+
+static inline int __attribute__ ((always_inline))
+__lll_robust_lock (int *futex, int id, int private)
+{
+ int result = 0;
+ if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+ result = __lll_robust_lock_wait (futex, private);
+ return result;
+}
+#define lll_robust_lock(futex, id, private) \
+ __lll_robust_lock (&(futex), id, private)
+
+
+static inline void __attribute__ ((always_inline))
+__lll_cond_lock (int *futex, int private)
+{
+ if (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0)
+ __lll_lock_wait (futex, private);
+}
+#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
+
+
+#define lll_robust_cond_lock(futex, id, private) \
+ __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS, private)
+
+
+extern int __lll_timedlock_wait (int *futex, const struct timespec *,
+ int private) attribute_hidden;
+extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
+ int private) attribute_hidden;
+
+static inline int __attribute__ ((always_inline))
+__lll_timedlock (int *futex, const struct timespec *abstime, int private)
+{
+ int result = 0;
+ if (atomic_compare_and_exchange_bool_acq (futex, 1, 0) != 0)
+ result = __lll_timedlock_wait (futex, abstime, private);
+ return result;
+}
+#define lll_timedlock(futex, abstime, private) \
+ __lll_timedlock (&(futex), abstime, private)
+
+
+static inline int __attribute__ ((always_inline))
+__lll_robust_timedlock (int *futex, const struct timespec *abstime,
+ int id, int private)
+{
+ int result = 0;
+ if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+ result = __lll_robust_timedlock_wait (futex, abstime, private);
+ return result;
+}
+#define lll_robust_timedlock(futex, abstime, id, private) \
+ __lll_robust_timedlock (&(futex), abstime, id, private)
+
+
+#define __lll_unlock(futex, private) \
+ (void) \
+ ({ int *__futex = (futex); \
+ int __oldval = atomic_exchange_rel (__futex, 0); \
+ if (__builtin_expect (__oldval > 1, 0)) \
+ lll_futex_wake (__futex, 1, private); \
+ })
+#define lll_unlock(futex, private) __lll_unlock(&(futex), private)
+
+
+#define __lll_robust_unlock(futex, private) \
+ (void) \
+ ({ int *__futex = (futex); \
+ int __oldval = atomic_exchange_rel (__futex, 0); \
+ if (__builtin_expect (__oldval & FUTEX_WAITERS, 0)) \
+ lll_futex_wake (__futex, 1, private); \
+ })
+#define lll_robust_unlock(futex, private) \
+ __lll_robust_unlock(&(futex), private)
+
+
+#define lll_islocked(futex) \
+ (futex != 0)
+
+/* Initializers for lock. */
+#define LLL_LOCK_INITIALIZER (0)
+#define LLL_LOCK_INITIALIZER_LOCKED (1)
+
+
+/* The kernel notifies a process which uses CLONE_CLEARTID via futex
+ wakeup when the clone terminates. The memory location contains the
+ thread ID while the clone is running and is reset to zero
+ afterwards. */
+#define lll_wait_tid(tid) \
+ do { \
+ __typeof (tid) __tid; \
+ while ((__tid = (tid)) != 0) \
+ lll_futex_wait (&(tid), __tid, LLL_SHARED); \
+ } while (0)
+
+extern int __lll_timedwait_tid (int *, const struct timespec *)
+ attribute_hidden;
+
+#define lll_timedwait_tid(tid, abstime) \
+ ({ \
+ int __res = 0; \
+ if ((tid) != 0) \
+ __res = __lll_timedwait_tid (&(tid), (abstime)); \
+ __res; \
+ })
+
+#endif /* lowlevellock.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/pt-vfork.S
new file mode 100644
index 000000000..ec5d175be
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/pt-vfork.S
@@ -0,0 +1,43 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tcb-offsets.h>
+
+#undef PSEUDO_PREPARE_ARGS
+#define PSEUDO_PREPARE_ARGS \
+ /* Load the current cached pid value across the vfork. */ \
+ rduniq; \
+ ldl a2, PID_OFFSET(v0); \
+ mov v0, a1; \
+ /* Write back its negation, to indicate that the pid value is \
+ uninitialized in the the child, and in the window between \
+ here and the point at which we restore the value. */ \
+ negl a2, t0; \
+ stl t0, PID_OFFSET(v0);
+
+PSEUDO (__vfork, vfork, 0)
+
+ /* If we're back in the parent, restore the saved pid. */
+ beq v0, 1f
+ stl a2, PID_OFFSET(a1)
+1: ret
+
+PSEUDO_END (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c
new file mode 100644
index 000000000..8adf8b44e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c
@@ -0,0 +1,97 @@
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+unsigned long int __fork_generation attribute_hidden;
+
+static void
+clear_once_control (void *arg)
+{
+ pthread_once_t *once_control = (pthread_once_t *) arg;
+
+ *once_control = 0;
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+}
+
+int
+attribute_protected
+__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+{
+ for (;;)
+ {
+ int oldval;
+ int newval;
+ int tmp;
+
+ /* Pseudo code:
+ newval = __fork_generation | 1;
+ oldval = *once_control;
+ if ((oldval & 2) == 0)
+ *once_control = newval;
+ Do this atomically.
+ */
+ newval = __fork_generation | 1;
+ __asm __volatile (
+ "1: ldl_l %0, %2\n"
+ " and %0, 2, %1\n"
+ " bne %1, 2f\n"
+ " mov %3, %1\n"
+ " stl_c %1, %2\n"
+ " beq %1, 1b\n"
+ "2: mb"
+ : "=&r" (oldval), "=&r" (tmp), "=m" (*once_control)
+ : "r" (newval), "m" (*once_control));
+
+ /* Check if the initializer has already been done. */
+ if ((oldval & 2) != 0)
+ return 0;
+
+ /* Check if another thread already runs the initializer. */
+ if ((oldval & 1) == 0)
+ break;
+
+ /* Check whether the initializer execution was interrupted by a fork. */
+ if (oldval != newval)
+ break;
+
+ /* Same generation, some other thread was faster. Wait. */
+ lll_futex_wait (once_control, oldval, LLL_PRIVATE);
+ }
+
+ /* This thread is the first here. Do the initialization.
+ Register a cleanup handler so that in case the thread gets
+ interrupted the initialization can be restarted. */
+ pthread_cleanup_push (clear_once_control, once_control);
+
+ init_routine ();
+
+ pthread_cleanup_pop (0);
+
+ /* Add one to *once_control to take the bottom 2 bits from 01 to 10. */
+ atomic_increment (once_control);
+
+ /* Wake up all other threads. */
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+
+ return 0;
+}
+weak_alias (__pthread_once, pthread_once)
+strong_alias (__pthread_once, __pthread_once_internal)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/sem_post.c b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/sem_post.c
new file mode 100644
index 000000000..27fd817e6
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/sem_post.c
@@ -0,0 +1,5 @@
+/* ??? This is an ass-backwards way to do this. We should simply define
+ the acquire/release semantics of atomic_exchange_and_add. And even if
+ we don't do this, we should be using atomic_full_barrier or otherwise. */
+#define __lll_rel_instr "mb"
+#include "../sem_post.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h
new file mode 100644
index 000000000..7049b3607
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h
@@ -0,0 +1,177 @@
+/* Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <nptl/pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# ifdef PROF
+# define PSEUDO_PROF \
+ .set noat; \
+ lda AT, _mcount; \
+ jsr AT, (AT), _mcount; \
+ .set at
+# else
+# define PSEUDO_PROF
+# endif
+
+/* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END
+ besides "ret". */
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .globl name; \
+ .align 4; \
+ .type name, @function; \
+ .usepv name, std; \
+ cfi_startproc; \
+__LABEL(name) \
+ ldgp gp, 0(pv); \
+ PSEUDO_PROF; \
+ PSEUDO_PREPARE_ARGS \
+ SINGLE_THREAD_P(t0); \
+ bne t0, $pseudo_cancel; \
+ lda v0, SYS_ify(syscall_name); \
+ call_pal PAL_callsys; \
+ bne a3, SYSCALL_ERROR_LABEL; \
+__LABEL($pseudo_ret) \
+ .subsection 2; \
+ cfi_startproc; \
+__LABEL($pseudo_cancel) \
+ subq sp, 64, sp; \
+ cfi_def_cfa_offset(64); \
+ stq ra, 0(sp); \
+ cfi_offset(ra, -64); \
+ SAVE_ARGS_##args; \
+ CENABLE; \
+ LOAD_ARGS_##args; \
+ /* Save the CENABLE return value in RA. That register \
+ is preserved across syscall and the real return \
+ address is saved on the stack. */ \
+ mov v0, ra; \
+ lda v0, SYS_ify(syscall_name); \
+ call_pal PAL_callsys; \
+ stq v0, 8(sp); \
+ mov ra, a0; \
+ bne a3, $multi_error; \
+ CDISABLE; \
+ ldq ra, 0(sp); \
+ ldq v0, 8(sp); \
+ addq sp, 64, sp; \
+ cfi_remember_state; \
+ cfi_restore(ra); \
+ cfi_def_cfa_offset(0); \
+ ret; \
+ cfi_restore_state; \
+__LABEL($multi_error) \
+ CDISABLE; \
+ ldq ra, 0(sp); \
+ ldq v0, 8(sp); \
+ addq sp, 64, sp; \
+ cfi_restore(ra); \
+ cfi_def_cfa_offset(0); \
+__LABEL($syscall_error) \
+ SYSCALL_ERROR_HANDLER; \
+ cfi_endproc; \
+ .previous
+
+# undef PSEUDO_END
+# define PSEUDO_END(sym) \
+ cfi_endproc; \
+ .subsection 2; \
+ .size sym, .-sym
+
+# define SAVE_ARGS_0 /* Nothing. */
+# define SAVE_ARGS_1 SAVE_ARGS_0; stq a0, 8(sp)
+# define SAVE_ARGS_2 SAVE_ARGS_1; stq a1, 16(sp)
+# define SAVE_ARGS_3 SAVE_ARGS_2; stq a2, 24(sp)
+# define SAVE_ARGS_4 SAVE_ARGS_3; stq a3, 32(sp)
+# define SAVE_ARGS_5 SAVE_ARGS_4; stq a4, 40(sp)
+# define SAVE_ARGS_6 SAVE_ARGS_5; stq a5, 48(sp)
+
+# define LOAD_ARGS_0 /* Nothing. */
+# define LOAD_ARGS_1 LOAD_ARGS_0; ldq a0, 8(sp)
+# define LOAD_ARGS_2 LOAD_ARGS_1; ldq a1, 16(sp)
+# define LOAD_ARGS_3 LOAD_ARGS_2; ldq a2, 24(sp)
+# define LOAD_ARGS_4 LOAD_ARGS_3; ldq a3, 32(sp)
+# define LOAD_ARGS_5 LOAD_ARGS_4; ldq a4, 40(sp)
+# define LOAD_ARGS_6 LOAD_ARGS_5; ldq a5, 48(sp)
+
+# ifdef IS_IN_libpthread
+# define __local_enable_asynccancel __pthread_enable_asynccancel
+# define __local_disable_asynccancel __pthread_disable_asynccancel
+# define __local_multiple_threads __pthread_multiple_threads
+# elif !defined NOT_IN_libc
+# define __local_enable_asynccancel __libc_enable_asynccancel
+# define __local_disable_asynccancel __libc_disable_asynccancel
+# define __local_multiple_threads __libc_multiple_threads
+# elif defined IS_IN_librt
+# define __local_enable_asynccancel __librt_enable_asynccancel
+# define __local_disable_asynccancel __librt_disable_asynccancel
+# else
+# error Unsupported library
+# endif
+
+# ifdef __PIC__
+# define CENABLE bsr ra, __local_enable_asynccancel !samegp
+# define CDISABLE bsr ra, __local_disable_asynccancel !samegp
+# else
+# define CENABLE jsr ra, __local_enable_asynccancel; ldgp ra, 0(gp)
+# define CDISABLE jsr ra, __local_disable_asynccancel; ldgp ra, 0(gp)
+# endif
+
+# if defined IS_IN_libpthread || !defined NOT_IN_libc
+# ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+# define SINGLE_THREAD_P \
+ __builtin_expect (__local_multiple_threads == 0, 1)
+# elif defined(__PIC__)
+# define SINGLE_THREAD_P(reg) ldl reg, __local_multiple_threads(gp) !gprel
+# else
+# define SINGLE_THREAD_P(reg) \
+ ldah reg, __local_multiple_threads(gp) !gprelhigh; \
+ ldl reg, __local_multiple_threads(reg) !gprellow
+# endif
+# else
+# ifndef __ASSEMBLER__
+# define SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+# else
+# define SINGLE_THREAD_P(reg) \
+ call_pal PAL_rduniq; \
+ ldl reg, MULTIPLE_THREADS_OFFSET($0)
+# endif
+# endif
+
+#else
+
+# define SINGLE_THREAD_P (1)
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_create.c b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_create.c
new file mode 100644
index 000000000..172223af3
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_create.c
@@ -0,0 +1 @@
+#include "../x86_64/timer_create.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_delete.c b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_delete.c
new file mode 100644
index 000000000..537516e0a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_delete.c
@@ -0,0 +1 @@
+#include "../x86_64/timer_delete.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_getoverr.c b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_getoverr.c
new file mode 100644
index 000000000..3f21a73c9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_getoverr.c
@@ -0,0 +1 @@
+#include "../x86_64/timer_getoverr.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_gettime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_gettime.c
new file mode 100644
index 000000000..a50143adc
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_gettime.c
@@ -0,0 +1 @@
+#include "../x86_64/timer_gettime.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_settime.c
new file mode 100644
index 000000000..37baeffac
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/timer_settime.c
@@ -0,0 +1 @@
+#include "../x86_64/timer_settime.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/vfork.S
new file mode 100644
index 000000000..f4ed9311b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/vfork.S
@@ -0,0 +1,46 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tcb-offsets.h>
+
+#undef PSEUDO_PREPARE_ARGS
+#define PSEUDO_PREPARE_ARGS \
+ /* Load the current cached pid value across the vfork. */ \
+ rduniq; \
+ ldl a2, PID_OFFSET(v0); \
+ mov v0, a1; \
+ /* If the cached value is initialized (nonzero), then write \
+ back its negation, or INT_MIN, to indicate that the pid \
+ value is uninitialized in the the child, and in the window \
+ between here and the point at which we restore the value. */ \
+ ldah t0, -0x8000; \
+ negl a2, t1; \
+ cmovne a2, t1, t0; \
+ stl t0, PID_OFFSET(v0);
+
+PSEUDO (__vfork, vfork, 0)
+
+ /* If we're back in the parent, restore the saved pid. */
+ beq v0, 1f
+ stl a2, PID_OFFSET(a1)
+1: ret
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+weak_alias (__vfork, vfork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/Makefile
new file mode 100644
index 000000000..43a6fad84
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/Makefile
@@ -0,0 +1,13 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../../../../../
+top_builddir=../../../../../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.arch
+include $(top_srcdir)Makerules
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/Makefile.arch
new file mode 100644
index 000000000..c5852818d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/Makefile.arch
@@ -0,0 +1,58 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+libpthread_SSRC = pt-vfork.S
+libpthread_CSRC = pthread_once.c lowlevellock.c \
+ pt-__syscall_rt_sigaction.c pt-__syscall_error.c
+
+libc_a_CSRC = fork.c lowlevellock.c
+libc_a_SSRC = clone.S vfork.S
+
+ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y)
+CFLAGS-fork.c = -D__USE_STDIO_FUTEXES__
+endif
+CFLAGS-pthread_once.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-pt-__syscall_rt_sigaction.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-lowlevellock.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-pt-__syscall_error.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
+ASFLAGS-pt-vfork.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -marm
+# We always compile it in arm mode because of SAVE_PID macro
+# This macro should be alternatively implemented in THUMB
+# assembly.
+ASFLAGS-vfork.S = -marm
+
+CFLAGS += $(SSP_ALL_CFLAGS)
+#CFLAGS:=$(CFLAGS:-O1=-O2)
+
+LINUX_ARCH_DIR:=$(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/arm
+LINUX_ARCH_OUT:=$(top_builddir)libpthread/nptl/sysdeps/unix/sysv/linux/arm
+
+LINUX_ARCH_OBJ:=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libpthread_SSRC))
+LINUX_ARCH_OBJ+=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libpthread_CSRC))
+
+ifeq ($(DOPIC),y)
+libpthread-a-y += $(LINUX_ARCH_OBJ:.o=.os)
+else
+libpthread-a-y += $(LINUX_ARCH_OBJ)
+endif
+libpthread-so-y += $(LINUX_ARCH_OBJ:.o=.oS)
+
+libpthread-nomulti-y+=$(LINUX_ARCH_OBJ)
+
+LIBC_LINUX_ARCH_OBJ:=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libc_a_CSRC))
+LIBC_LINUX_ARCH_OBJ+=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libc_a_SSRC))
+
+libc-static-y+=$(LIBC_LINUX_ARCH_OBJ)
+libc-shared-y+=$(LIBC_LINUX_ARCH_OBJ:.o=.oS)
+
+libc-nomulti-y+=$(LIBC_LINUX_ARCH_OBJ)
+
+objclean-y+=pthread_linux_arch_objclean
+
+pthread_linux_arch_objclean:
+ $(RM) $(LINUX_ARCH_OUT)/*.{o,os,oS}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/atomic.h b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/atomic.h
new file mode 100644
index 000000000..b0586ea1e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/atomic.h
@@ -0,0 +1,122 @@
+/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdint.h>
+#include <sysdep.h>
+
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+void __arm_link_error (void);
+
+#ifdef __thumb2__
+#define atomic_full_barrier() \
+ __asm__ __volatile__ \
+ ("movw\tip, #0x0fa0\n\t" \
+ "movt\tip, #0xffff\n\t" \
+ "blx\tip" \
+ : : : "ip", "lr", "cc", "memory");
+#else
+#define atomic_full_barrier() \
+ __asm__ __volatile__ \
+ ("mov\tip, #0xffff0fff\n\t" \
+ "mov\tlr, pc\n\t" \
+ "add\tpc, ip, #(0xffff0fa0 - 0xffff0fff)" \
+ : : : "ip", "lr", "cc", "memory");
+#endif
+
+/* Atomic compare and exchange. This sequence relies on the kernel to
+ provide a compare and exchange operation which is atomic on the
+ current architecture, either via cleverness on pre-ARMv6 or via
+ ldrex / strex on ARMv6. */
+
+#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+ ({ __arm_link_error (); oldval; })
+
+#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+ ({ __arm_link_error (); oldval; })
+
+/* It doesn't matter what register is used for a_oldval2, but we must
+ specify one to work around GCC PR rtl-optimization/21223. Otherwise
+ it may cause a_oldval or a_tmp to be moved to a different register. */
+
+#ifdef __thumb2__
+/* Thumb-2 has ldrex/strex. However it does not have barrier instructions,
+ so we still need to use the kernel helper. */
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+ ({ register __typeof (oldval) a_oldval asm ("r0"); \
+ register __typeof (oldval) a_newval asm ("r1") = (newval); \
+ register __typeof (mem) a_ptr asm ("r2") = (mem); \
+ register __typeof (oldval) a_tmp asm ("r3"); \
+ register __typeof (oldval) a_oldval2 asm ("r4") = (oldval); \
+ __asm__ __volatile__ \
+ ("0:\tldr\t%[tmp],[%[ptr]]\n\t" \
+ "cmp\t%[tmp], %[old2]\n\t" \
+ "bne\t1f\n\t" \
+ "mov\t%[old], %[old2]\n\t" \
+ "movw\t%[tmp], #0x0fc0\n\t" \
+ "movt\t%[tmp], #0xffff\n\t" \
+ "blx\t%[tmp]\n\t" \
+ "bcc\t0b\n\t" \
+ "mov\t%[tmp], %[old2]\n\t" \
+ "1:" \
+ : [old] "=&r" (a_oldval), [tmp] "=&r" (a_tmp) \
+ : [new] "r" (a_newval), [ptr] "r" (a_ptr), \
+ [old2] "r" (a_oldval2) \
+ : "ip", "lr", "cc", "memory"); \
+ a_tmp; })
+#else
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+ ({ register __typeof (oldval) a_oldval asm ("r0"); \
+ register __typeof (oldval) a_newval asm ("r1") = (newval); \
+ register __typeof (mem) a_ptr asm ("r2") = (mem); \
+ register __typeof (oldval) a_tmp asm ("r3"); \
+ register __typeof (oldval) a_oldval2 asm ("r4") = (oldval); \
+ __asm__ __volatile__ \
+ ("0:\tldr\t%[tmp],[%[ptr]]\n\t" \
+ "cmp\t%[tmp], %[old2]\n\t" \
+ "bne\t1f\n\t" \
+ "mov\t%[old], %[old2]\n\t" \
+ "mov\t%[tmp], #0xffff0fff\n\t" \
+ "mov\tlr, pc\n\t" \
+ "add\tpc, %[tmp], #(0xffff0fc0 - 0xffff0fff)\n\t" \
+ "bcc\t0b\n\t" \
+ "mov\t%[tmp], %[old2]\n\t" \
+ "1:" \
+ : [old] "=&r" (a_oldval), [tmp] "=&r" (a_tmp) \
+ : [new] "r" (a_newval), [ptr] "r" (a_ptr), \
+ [old2] "r" (a_oldval2) \
+ : "ip", "lr", "cc", "memory"); \
+ a_tmp; })
+#endif
+
+#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ ({ __arm_link_error (); oldval; })
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/pthreadtypes.h
new file mode 100644
index 000000000..e1b115c8c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/pthreadtypes.h
@@ -0,0 +1,181 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H 1
+
+#include <endian.h>
+
+#define __SIZEOF_PTHREAD_ATTR_T 36
+#define __SIZEOF_PTHREAD_MUTEX_T 24
+#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+#define __SIZEOF_PTHREAD_COND_T 48
+#define __SIZEOF_PTHREAD_COND_COMPAT_T 12
+#define __SIZEOF_PTHREAD_CONDATTR_T 4
+#define __SIZEOF_PTHREAD_RWLOCK_T 32
+#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+#define __SIZEOF_PTHREAD_BARRIER_T 20
+#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+
+
+/* Thread identifiers. The structure of the attribute type is not
+ exposed on purpose. */
+typedef unsigned long int pthread_t;
+
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_ATTR_T];
+ long int __align;
+} pthread_attr_t;
+
+
+typedef struct __pthread_internal_slist
+{
+ struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+
+
+/* Data structures for mutex handling. The structure of the attribute
+ type is not exposed on purpose. */
+typedef union
+{
+ struct __pthread_mutex_s
+ {
+ int __lock;
+ unsigned int __count;
+ int __owner;
+ /* KIND must stay at this position in the structure to maintain
+ binary compatibility. */
+ int __kind;
+ unsigned int __nusers;
+ __extension__ union
+ {
+ int __spins;
+ __pthread_slist_t __list;
+ };
+ } __data;
+ char __size[__SIZEOF_PTHREAD_MUTEX_T];
+ long int __align;
+} pthread_mutex_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+ long int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling. The structure of
+ the attribute type is not exposed on purpose. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned int __futex;
+ __extension__ unsigned long long int __total_seq;
+ __extension__ unsigned long long int __wakeup_seq;
+ __extension__ unsigned long long int __woken_seq;
+ void *__mutex;
+ unsigned int __nwaiters;
+ unsigned int __broadcast_seq;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_COND_T];
+ __extension__ long long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+ long int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Data structure for read-write lock variable handling. The
+ structure of the attribute type is not exposed on purpose. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned int __nr_readers;
+ unsigned int __readers_wakeup;
+ unsigned int __writer_wakeup;
+ unsigned int __nr_readers_queued;
+ unsigned int __nr_writers_queued;
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned char __pad1;
+ unsigned char __pad2;
+ unsigned char __shared;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned char __flags;
+#else
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned char __flags;
+ unsigned char __shared;
+ unsigned char __pad1;
+ unsigned char __pad2;
+#endif
+ int __writer;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+ long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+ long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type. */
+typedef volatile int pthread_spinlock_t;
+
+
+/* POSIX barriers data type. The structure of the type is
+ deliberately not exposed. */
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIER_T];
+ long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+ int __align;
+} pthread_barrierattr_t;
+#endif
+
+
+#endif /* bits/pthreadtypes.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h
new file mode 100644
index 000000000..dadfac2af
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/bits/semaphore.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 2002, 2005, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+
+#define __SIZEOF_SEM_T 16
+
+
+/* Value returned if `sem_open' failed. */
+#define SEM_FAILED ((sem_t *) 0)
+
+
+typedef union
+{
+ char __size[__SIZEOF_SEM_T];
+ long int __align;
+} sem_t;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/clone.S
new file mode 100644
index 000000000..23227eb24
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/clone.S
@@ -0,0 +1,3 @@
+#define RESET_PID
+#include <tcb-offsets.h>
+#include "../../../../../../../libc/sysdeps/linux/arm/clone.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/createthread.c
new file mode 100644
index 000000000..2d4355980
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/createthread.c
@@ -0,0 +1,23 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Value passed to 'clone' for initialization of the thread register. */
+#define TLS_VALUE (pd + 1)
+
+/* Get the real implementation. */
+#include <sysdeps/pthread/createthread.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/fork.c
new file mode 100644
index 000000000..1c8f4c43a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/fork.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Phil Blundell <pb@nexus.co.uk>, 2005
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sched.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+
+
+#define ARCH_FORK() \
+ INLINE_SYSCALL (clone, 5, \
+ CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \
+ NULL, NULL, NULL, &THREAD_SELF->tid)
+
+#include "../fork.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.c
new file mode 100644
index 000000000..8c8955e05
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.c
@@ -0,0 +1,134 @@
+/* low level locking for pthread library. Generic futex-using version.
+ Copyright (C) 2003, 2005, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <sys/time.h>
+#include <tls.h>
+
+void
+__lll_lock_wait_private (int *futex)
+{
+ do
+ {
+ int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1);
+ if (oldval != 0)
+ lll_futex_wait (futex, 2, LLL_PRIVATE);
+ }
+ while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0);
+}
+
+
+/* These functions don't get included in libc.so */
+#ifdef IS_IN_libpthread
+void
+__lll_lock_wait (int *futex, int private)
+{
+ do
+ {
+ int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1);
+ if (oldval != 0)
+ lll_futex_wait (futex, 2, private);
+ }
+ while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0);
+}
+
+
+int
+__lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
+{
+ struct timespec rt;
+
+ /* Reject invalid timeouts. */
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+ return EINVAL;
+
+ /* Upgrade the lock. */
+ if (atomic_exchange_acq (futex, 2) == 0)
+ return 0;
+
+ do
+ {
+ struct timeval tv;
+
+ /* Get the current time. */
+ (void) gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+ rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+ if (rt.tv_nsec < 0)
+ {
+ rt.tv_nsec += 1000000000;
+ --rt.tv_sec;
+ }
+
+ /* Already timed out? */
+ if (rt.tv_sec < 0)
+ return ETIMEDOUT;
+
+ // XYZ: Lost the lock to check whether it was private.
+ lll_futex_timed_wait (futex, 2, &rt, private);
+ }
+ while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0);
+
+ return 0;
+}
+
+
+int
+__lll_timedwait_tid (int *tidp, const struct timespec *abstime)
+{
+ int tid;
+
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+ return EINVAL;
+
+ /* Repeat until thread terminated. */
+ while ((tid = *tidp) != 0)
+ {
+ struct timeval tv;
+ struct timespec rt;
+
+ /* Get the current time. */
+ (void) gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+ rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+ if (rt.tv_nsec < 0)
+ {
+ rt.tv_nsec += 1000000000;
+ --rt.tv_sec;
+ }
+
+ /* Already timed out? */
+ if (rt.tv_sec < 0)
+ return ETIMEDOUT;
+
+ /* Wait until thread terminates. */
+ // XYZ: Lost the lock to check whether it was private.
+ if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT)
+ return ETIMEDOUT;
+ }
+
+ return 0;
+}
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.h
new file mode 100644
index 000000000..4c7d08c92
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/lowlevellock.h
@@ -0,0 +1,282 @@
+/* Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H 1
+
+#include <time.h>
+#include <sys/param.h>
+#include <bits/pthreadtypes.h>
+#include <atomic.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_REQUEUE 3
+#define FUTEX_CMP_REQUEUE 4
+#define FUTEX_WAKE_OP 5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_WAIT_BITSET 9
+#define FUTEX_WAKE_BITSET 10
+#define FUTEX_PRIVATE_FLAG 128
+#define FUTEX_CLOCK_REALTIME 256
+
+#define FUTEX_BITSET_MATCH_ANY 0xffffffff
+
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
+ & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
+
+#define lll_futex_wait(futexp, val, private) \
+ lll_futex_timed_wait(futexp, val, NULL, private)
+
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAIT, private), \
+ (val), (timespec)); \
+ __ret; \
+ })
+
+#define lll_futex_wake(futexp, nr, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAKE, private), \
+ (nr), 0); \
+ __ret; \
+ })
+
+#define lll_robust_dead(futexv, private) \
+ do \
+ { \
+ int *__futexp = &(futexv); \
+ atomic_or (__futexp, FUTEX_OWNER_DIED); \
+ lll_futex_wake (__futexp, 1, private); \
+ } \
+ while (0)
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+ (nr_wake), (nr_move), (mutex), (val)); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_WAKE_OP, private), \
+ (nr_wake), (nr_wake2), (futexp2), \
+ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+
+#define lll_trylock(lock) \
+ atomic_compare_and_exchange_val_acq(&(lock), 1, 0)
+
+#define lll_cond_trylock(lock) \
+ atomic_compare_and_exchange_val_acq(&(lock), 2, 0)
+
+#define __lll_robust_trylock(futex, id) \
+ (atomic_compare_and_exchange_val_acq (futex, id, 0) != 0)
+#define lll_robust_trylock(lock, id) \
+ __lll_robust_trylock (&(lock), id)
+
+extern void __lll_lock_wait_private (int *futex) attribute_hidden;
+extern void __lll_lock_wait (int *futex, int private) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden;
+
+#define __lll_lock(futex, private) \
+ ((void) ({ \
+ int *__futex = (futex); \
+ if (__builtin_expect (atomic_compare_and_exchange_val_acq (__futex, \
+ 1, 0), 0)) \
+ { \
+ if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \
+ __lll_lock_wait_private (__futex); \
+ else \
+ __lll_lock_wait (__futex, private); \
+ } \
+ }))
+#define lll_lock(futex, private) __lll_lock (&(futex), private)
+
+
+#define __lll_robust_lock(futex, id, private) \
+ ({ \
+ int *__futex = (futex); \
+ int __val = 0; \
+ \
+ if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id, \
+ 0), 0)) \
+ __val = __lll_robust_lock_wait (__futex, private); \
+ __val; \
+ })
+#define lll_robust_lock(futex, id, private) \
+ __lll_robust_lock (&(futex), id, private)
+
+
+#define __lll_cond_lock(futex, private) \
+ ((void) ({ \
+ int *__futex = (futex); \
+ if (__builtin_expect (atomic_exchange_acq (__futex, 2), 0)) \
+ __lll_lock_wait (__futex, private); \
+ }))
+#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
+
+
+#define lll_robust_cond_lock(futex, id, private) \
+ __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS, private)
+
+
+extern int __lll_timedlock_wait (int *futex, const struct timespec *,
+ int private) attribute_hidden;
+extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
+ int private) attribute_hidden;
+
+#define __lll_timedlock(futex, abstime, private) \
+ ({ \
+ int *__futex = (futex); \
+ int __val = 0; \
+ \
+ if (__builtin_expect (atomic_exchange_acq (__futex, 1), 0)) \
+ __val = __lll_timedlock_wait (__futex, abstime, private); \
+ __val; \
+ })
+#define lll_timedlock(futex, abstime, private) \
+ __lll_timedlock (&(futex), abstime, private)
+
+
+#define __lll_robust_timedlock(futex, abstime, id, private) \
+ ({ \
+ int *__futex = (futex); \
+ int __val = 0; \
+ \
+ if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id, \
+ 0), 0)) \
+ __val = __lll_robust_timedlock_wait (__futex, abstime, private); \
+ __val; \
+ })
+#define lll_robust_timedlock(futex, abstime, id, private) \
+ __lll_robust_timedlock (&(futex), abstime, id, private)
+
+
+#define __lll_unlock(futex, private) \
+ (void) \
+ ({ int *__futex = (futex); \
+ int __oldval = atomic_exchange_rel (__futex, 0); \
+ if (__builtin_expect (__oldval > 1, 0)) \
+ lll_futex_wake (__futex, 1, private); \
+ })
+#define lll_unlock(futex, private) __lll_unlock(&(futex), private)
+
+
+#define __lll_robust_unlock(futex, private) \
+ (void) \
+ ({ int *__futex = (futex); \
+ int __oldval = atomic_exchange_rel (__futex, 0); \
+ if (__builtin_expect (__oldval & FUTEX_WAITERS, 0)) \
+ lll_futex_wake (__futex, 1, private); \
+ })
+#define lll_robust_unlock(futex, private) \
+ __lll_robust_unlock(&(futex), private)
+
+
+#define lll_islocked(futex) \
+ (futex != 0)
+
+
+/* Our internal lock implementation is identical to the binary-compatible
+ mutex implementation. */
+
+/* Initializers for lock. */
+#define LLL_LOCK_INITIALIZER (0)
+#define LLL_LOCK_INITIALIZER_LOCKED (1)
+
+/* The states of a lock are:
+ 0 - untaken
+ 1 - taken by one user
+ >1 - taken by more users */
+
+/* The kernel notifies a process which uses CLONE_CLEARTID via futex
+ wakeup when the clone terminates. The memory location contains the
+ thread ID while the clone is running and is reset to zero
+ afterwards. */
+#define lll_wait_tid(tid) \
+ do { \
+ __typeof (tid) __tid; \
+ while ((__tid = (tid)) != 0) \
+ lll_futex_wait (&(tid), __tid, LLL_SHARED);\
+ } while (0)
+
+extern int __lll_timedwait_tid (int *, const struct timespec *)
+ attribute_hidden;
+
+#define lll_timedwait_tid(tid, abstime) \
+ ({ \
+ int __res = 0; \
+ if ((tid) != 0) \
+ __res = __lll_timedwait_tid (&(tid), (abstime)); \
+ __res; \
+ })
+
+#endif /* lowlevellock.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/nptl-aeabi_unwind_cpp_pr1.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/nptl-aeabi_unwind_cpp_pr1.c
new file mode 100644
index 000000000..7b8352243
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/nptl-aeabi_unwind_cpp_pr1.c
@@ -0,0 +1 @@
+#include <aeabi_unwind_cpp_pr1.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-__syscall_error.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-__syscall_error.c
new file mode 100644
index 000000000..5a48a9b2e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-__syscall_error.c
@@ -0,0 +1 @@
+#include <../../../../../../../libc/sysdeps/linux/arm/__syscall_error.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-__syscall_rt_sigaction.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-__syscall_rt_sigaction.c
new file mode 100644
index 000000000..50137c84a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-__syscall_rt_sigaction.c
@@ -0,0 +1 @@
+#include <../../../../../../../libc/sysdeps/linux/common/__syscall_rt_sigaction.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-gettimeofday.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-gettimeofday.c
new file mode 100644
index 000000000..08710f1c8
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-gettimeofday.c
@@ -0,0 +1,5 @@
+#include <sys/syscall.h>
+#include <sys/time.h>
+
+int gettimeofday (struct timeval *, struct timezone *) attribute_hidden;
+_syscall2(int, gettimeofday, struct timeval *, tv, struct timezone *, tz);
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-vfork.S
new file mode 100644
index 000000000..9764e9ee2
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-vfork.S
@@ -0,0 +1,38 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <tcb-offsets.h>
+
+/* Save the PID value. */
+#define SAVE_PID \
+ str lr, [sp, #-4]!; /* Save LR. */ \
+ mov r0, #0xffff0fff; /* Point to the high page. */ \
+ mov lr, pc; /* Save our return address. */ \
+ sub pc, r0, #31; /* Jump to the TLS entry. */ \
+ ldr lr, [sp], #4; /* Restore LR. */ \
+ mov r2, r0; /* Save the TLS addr in r2. */ \
+ ldr r3, [r2, #PID_OFFSET]; /* Load the saved PID. */ \
+ rsb r0, r3, #0; /* Negate it. */ \
+ str r0, [r2, #PID_OFFSET] /* Store the temporary PID. */
+
+/* Restore the old PID value in the parent. */
+#define RESTORE_PID \
+ cmp r0, #0; /* If we are the parent... */ \
+ strne r3, [r2, #PID_OFFSET] /* ... restore the saved PID. */
+
+#INCLUDE <../../../../../../../LIBC/SYSDEPS/LINUX/ARM/VFORK.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pthread_once.c
new file mode 100644
index 000000000..e977a7d0c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/pthread_once.c
@@ -0,0 +1,100 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+unsigned long int __fork_generation attribute_hidden;
+
+static void
+clear_once_control (void *arg)
+{
+ pthread_once_t *once_control = (pthread_once_t *) arg;
+
+ *once_control = 0;
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+}
+
+int
+attribute_protected
+__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+{
+ for (;;)
+ {
+ int oldval;
+ int newval;
+
+ /* Pseudo code:
+ newval = __fork_generation | 1;
+ oldval = *once_control;
+ if ((oldval & 2) == 0)
+ *once_control = newval;
+ Do this atomically.
+ */
+ do
+ {
+ newval = __fork_generation | 1;
+ oldval = *once_control;
+ if (oldval & 2)
+ break;
+ } while (atomic_compare_and_exchange_val_acq (once_control, newval, oldval) != oldval);
+
+ /* Check if the initializer has already been done. */
+ if ((oldval & 2) != 0)
+ return 0;
+
+ /* Check if another thread already runs the initializer. */
+ if ((oldval & 1) == 0)
+ break;
+
+ /* Check whether the initializer execution was interrupted by a fork. */
+ if (oldval != newval)
+ break;
+
+ /* Same generation, some other thread was faster. Wait. */
+ lll_futex_wait (once_control, oldval, LLL_PRIVATE);
+ }
+
+ /* This thread is the first here. Do the initialization.
+ Register a cleanup handler so that in case the thread gets
+ interrupted the initialization can be restarted. */
+ pthread_cleanup_push (clear_once_control, once_control);
+
+ init_routine ();
+
+ pthread_cleanup_pop (0);
+
+ /* Say that the initialisation is done. */
+ *once_control = __fork_generation | 2;
+
+ /* Wake up all other threads. */
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+
+ return 0;
+}
+weak_alias (__pthread_once, pthread_once)
+strong_alias (__pthread_once, __pthread_once_internal)
+
+#if defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__PIC__)
+/* When statically linked, if pthread_create is used, this file
+ will be brought in. The exception handling code in GCC assumes
+ that if pthread_create is available, so are these. */
+const void *include_pthread_getspecific attribute_hidden = pthread_getspecific;
+const void *include_pthread_setspecific attribute_hidden = pthread_setspecific;
+const void *include_pthread_key_create attribute_hidden = pthread_key_create;
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h
new file mode 100644
index 000000000..423c23195
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h
@@ -0,0 +1,137 @@
+/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tcb-offsets.h>
+#ifndef __ASSEMBLER__
+# include <pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .section ".text"; \
+ PSEUDO_PROLOGUE; \
+ .type __##syscall_name##_nocancel,%function; \
+ .globl __##syscall_name##_nocancel; \
+ __##syscall_name##_nocancel: \
+ DO_CALL (syscall_name, args); \
+ PSEUDO_RET; \
+ .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
+ ENTRY (name); \
+ SINGLE_THREAD_P; \
+ DOARGS_##args; \
+ bne .Lpseudo_cancel; \
+ DO_CALL (syscall_name, 0); \
+ UNDOARGS_##args; \
+ cmn r0, $4096; \
+ PSEUDO_RET; \
+ .Lpseudo_cancel: \
+ DOCARGS_##args; /* save syscall args etc. around CENABLE. */ \
+ CENABLE; \
+ mov ip, r0; /* put mask in safe place. */ \
+ UNDOCARGS_##args; /* restore syscall args. */ \
+ swi SYS_ify (syscall_name); /* do the call. */ \
+ str r0, [sp, $-4]!; /* save syscall return value. */ \
+ mov r0, ip; /* get mask back. */ \
+ CDISABLE; \
+ ldmfd sp!, {r0, lr}; /* retrieve return value and address. */ \
+ UNDOARGS_##args; \
+ cmn r0, $4096;
+
+# define DOCARGS_0 str lr, [sp, #-4]!;
+# define UNDOCARGS_0
+
+# define DOCARGS_1 stmfd sp!, {r0, lr};
+# define UNDOCARGS_1 ldr r0, [sp], #4;
+
+# define DOCARGS_2 stmfd sp!, {r0, r1, lr};
+# define UNDOCARGS_2 ldmfd sp!, {r0, r1};
+
+# define DOCARGS_3 stmfd sp!, {r0, r1, r2, lr};
+# define UNDOCARGS_3 ldmfd sp!, {r0, r1, r2};
+
+# define DOCARGS_4 stmfd sp!, {r0, r1, r2, r3, lr};
+# define UNDOCARGS_4 ldmfd sp!, {r0, r1, r2, r3};
+
+# define DOCARGS_5 DOCARGS_4
+# define UNDOCARGS_5 UNDOCARGS_4
+
+# define DOCARGS_6 DOCARGS_5
+# define UNDOCARGS_6 UNDOCARGS_5
+
+# ifdef IS_IN_libpthread
+# define CENABLE bl PLTJMP(__pthread_enable_asynccancel)
+# define CDISABLE bl PLTJMP(__pthread_disable_asynccancel)
+# define __local_multiple_threads __pthread_multiple_threads
+# elif !defined NOT_IN_libc
+# define CENABLE bl PLTJMP(__libc_enable_asynccancel)
+# define CDISABLE bl PLTJMP(__libc_disable_asynccancel)
+# define __local_multiple_threads __libc_multiple_threads
+# elif defined IS_IN_librt
+# define CENABLE bl PLTJMP(__librt_enable_asynccancel)
+# define CDISABLE bl PLTJMP(__librt_disable_asynccancel)
+# else
+# error Unsupported library
+# endif
+
+# if defined IS_IN_libpthread || !defined NOT_IN_libc
+# ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+# else
+# define SINGLE_THREAD_P \
+ ldr ip, 1b; \
+2: \
+ ldr ip, [pc, ip]; \
+ teq ip, #0;
+# define PSEUDO_PROLOGUE \
+ 1: .word __local_multiple_threads - 2f - 8;
+# endif
+# else
+/* There is no __local_multiple_threads for librt, so use the TCB. */
+# ifndef __ASSEMBLER__
+# define SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+# else
+# define PSEUDO_PROLOGUE
+# define SINGLE_THREAD_P \
+ stmfd sp!, {r0, lr}; \
+ bl __aeabi_read_tp; \
+ ldr ip, [r0, #MULTIPLE_THREADS_OFFSET]; \
+ ldmfd sp!, {r0, lr}; \
+ teq ip, #0
+# define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P
+# endif
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* For rtld, et cetera. */
+# define SINGLE_THREAD_P 1
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c
new file mode 100644
index 000000000..d095d3083
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c
@@ -0,0 +1,149 @@
+/* Copyright (C) 2003, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <unwind.h>
+#include <pthreadP.h>
+#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY))
+#define __libc_dlsym dlsym
+#define __libc_dlclose dlclose
+
+static void *libgcc_s_handle;
+static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
+static _Unwind_Reason_Code (*libgcc_s_personality)
+ (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
+ struct _Unwind_Context *);
+static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
+ (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
+static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *);
+static void (*libgcc_s_sjlj_register) (struct SjLj_Function_Context *);
+static void (*libgcc_s_sjlj_unregister) (struct SjLj_Function_Context *);
+
+void
+__attribute_noinline__
+pthread_cancel_init (void)
+{
+ void *resume, *personality, *forcedunwind, *getcfa;
+ void *handle;
+ void *sjlj_register, *sjlj_unregister;
+
+ if (__builtin_expect (libgcc_s_handle != NULL, 1))
+ {
+ /* Force gcc to reload all values. */
+ asm volatile ("" ::: "memory");
+ return;
+ }
+
+ handle = __libc_dlopen ("libgcc_s.so.1");
+
+ if (handle == NULL
+ || (sjlj_register = __libc_dlsym (handle, "_Unwind_SjLj_Register")) == NULL
+ || (sjlj_unregister = __libc_dlsym (handle, "_Unwind_SjLj_Unregister")) == NULL
+ || (resume = __libc_dlsym (handle, "_Unwind_SjLj_Resume")) == NULL
+ || (personality = __libc_dlsym (handle, "__gcc_personality_sj0")) == NULL
+ || (forcedunwind = __libc_dlsym (handle, "_Unwind_SjLj_ForcedUnwind"))
+ == NULL
+ || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL
+ )
+ fprintf(stderr, "libgcc_s.so.1 must be installed for pthread_cancel to work\n");
+
+ libgcc_s_resume = resume;
+ libgcc_s_personality = personality;
+ libgcc_s_forcedunwind = forcedunwind;
+ libgcc_s_sjlj_register = sjlj_register;
+ libgcc_s_sjlj_unregister = sjlj_unregister;
+ libgcc_s_getcfa = getcfa;
+ /* Make sure libgcc_s_getcfa is written last. Otherwise,
+ pthread_cancel_init might return early even when the pointer the
+ caller is interested in is not initialized yet. */
+ atomic_write_barrier ();
+ libgcc_s_handle = handle;
+}
+
+void
+__libc_freeres_fn_section
+__unwind_freeres (void)
+{
+ void *handle = libgcc_s_handle;
+ if (handle != NULL)
+ {
+ libgcc_s_handle = NULL;
+ __libc_dlclose (handle);
+ }
+}
+
+void
+_Unwind_Resume (struct _Unwind_Exception *exc)
+{
+ if (__builtin_expect (libgcc_s_resume == NULL, 0))
+ pthread_cancel_init ();
+
+ libgcc_s_resume (exc);
+}
+
+_Unwind_Reason_Code
+__gcc_personality_v0 (int version, _Unwind_Action actions,
+ _Unwind_Exception_Class exception_class,
+ struct _Unwind_Exception *ue_header,
+ struct _Unwind_Context *context)
+{
+ if (__builtin_expect (libgcc_s_personality == NULL, 0))
+ pthread_cancel_init ();
+
+ return libgcc_s_personality (version, actions, exception_class,
+ ue_header, context);
+}
+
+_Unwind_Reason_Code
+_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
+ void *stop_argument)
+{
+ if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0))
+ pthread_cancel_init ();
+
+ return libgcc_s_forcedunwind (exc, stop, stop_argument);
+}
+
+_Unwind_Word
+_Unwind_GetCFA (struct _Unwind_Context *context)
+{
+ if (__builtin_expect (libgcc_s_getcfa == NULL, 0))
+ pthread_cancel_init ();
+
+ return libgcc_s_getcfa (context);
+}
+
+void
+_Unwind_SjLj_Register (struct SjLj_Function_Context *fc)
+{
+ if (__builtin_expect (libgcc_s_sjlj_register == NULL, 0))
+ pthread_cancel_init ();
+
+ libgcc_s_sjlj_register (fc);
+}
+
+void
+_Unwind_SjLj_Unregister (struct SjLj_Function_Context *fc)
+{
+ if (__builtin_expect (libgcc_s_sjlj_unregister == NULL, 0))
+ pthread_cancel_init ();
+
+ libgcc_s_sjlj_unregister (fc);
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c
new file mode 100644
index 000000000..bf0348ac2
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c
@@ -0,0 +1,90 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <unwind.h>
+#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY))
+#define __libc_dlsym dlsym
+#define __libc_dlclose dlclose
+
+static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
+static _Unwind_Reason_Code (*libgcc_s_personality)
+ (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
+ struct _Unwind_Context *);
+static void (*libgcc_s_sjlj_register) (struct SjLj_Function_Context *);
+static void (*libgcc_s_sjlj_unregister) (struct SjLj_Function_Context *);
+
+static void
+init (void)
+{
+ void *resume, *personality;
+ void *handle;
+ void *sjlj_register, *sjlj_unregister;
+
+ handle = __libc_dlopen ("libgcc_s.so.1");
+
+ if (handle == NULL
+ || (sjlj_register = __libc_dlsym (handle, "_Unwind_SjLj_Register")) == NULL
+ || (sjlj_unregister = __libc_dlsym (handle, "_Unwind_SjLj_Unregister")) == NULL
+ || (resume = __libc_dlsym (handle, "_Unwind_SjLj_Resume")) == NULL
+ || (personality = __libc_dlsym (handle, "__gcc_personality_sj0")) == NULL)
+ fprintf(stderr, "libgcc_s.so.1 must be installed for pthread_cancel to work\n");
+
+ libgcc_s_resume = resume;
+ libgcc_s_personality = personality;
+ libgcc_s_sjlj_register = sjlj_register;
+ libgcc_s_sjlj_unregister = sjlj_unregister;
+}
+
+void
+_Unwind_Resume (struct _Unwind_Exception *exc)
+{
+ if (__builtin_expect (libgcc_s_resume == NULL, 0))
+ init ();
+ libgcc_s_resume (exc);
+}
+
+_Unwind_Reason_Code
+__gcc_personality_v0 (int version, _Unwind_Action actions,
+ _Unwind_Exception_Class exception_class,
+ struct _Unwind_Exception *ue_header,
+ struct _Unwind_Context *context)
+{
+ if (__builtin_expect (libgcc_s_personality == NULL, 0))
+ init ();
+ return libgcc_s_personality (version, actions, exception_class,
+ ue_header, context);
+}
+
+void
+_Unwind_SjLj_Register (struct SjLj_Function_Context *fc)
+{
+ if (__builtin_expect (libgcc_s_sjlj_register == NULL, 0))
+ init ();
+ libgcc_s_sjlj_register (fc);
+}
+
+void
+_Unwind_SjLj_Unregister (struct SjLj_Function_Context *fc)
+{
+ if (__builtin_expect (libgcc_s_sjlj_unregister == NULL, 0))
+ init ();
+ libgcc_s_sjlj_unregister (fc);
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind.h b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind.h
new file mode 100644
index 000000000..eeb9cf8b6
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind.h
@@ -0,0 +1,279 @@
+/* Header file for the ARM EABI unwinder
+ Copyright (C) 2003, 2004, 2005, 2009 Free Software Foundation, Inc.
+ Contributed by Paul Brook
+
+ This file is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ In addition to the permissions in the GNU General Public License, the
+ Free Software Foundation gives you unlimited permission to link the
+ compiled version of this file into combinations with other programs,
+ and to distribute those combinations without any restriction coming
+ from the use of this file. (The General Public License restrictions
+ do apply in other respects; for example, they cover modification of
+ the file, and distribution when not linked into a combine
+ executable.)
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* Language-independent unwinder header public defines. This contains both
+ ABI defined objects, and GNU support routines. */
+
+#ifndef UNWIND_ARM_H
+#define UNWIND_ARM_H
+
+#define __ARM_EABI_UNWINDER__ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ typedef unsigned _Unwind_Word __attribute__((__mode__(__word__)));
+ typedef signed _Unwind_Sword __attribute__((__mode__(__word__)));
+ typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
+ typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__)));
+ typedef _Unwind_Word _uw;
+ typedef unsigned _uw64 __attribute__((mode(__DI__)));
+ typedef unsigned _uw16 __attribute__((mode(__HI__)));
+ typedef unsigned _uw8 __attribute__((mode(__QI__)));
+
+ typedef enum
+ {
+ _URC_OK = 0, /* operation completed successfully */
+ _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+ _URC_END_OF_STACK = 5,
+ _URC_HANDLER_FOUND = 6,
+ _URC_INSTALL_CONTEXT = 7,
+ _URC_CONTINUE_UNWIND = 8,
+ _URC_FAILURE = 9 /* unspecified failure of some kind */
+ }
+ _Unwind_Reason_Code;
+
+ typedef enum
+ {
+ _US_VIRTUAL_UNWIND_FRAME = 0,
+ _US_UNWIND_FRAME_STARTING = 1,
+ _US_UNWIND_FRAME_RESUME = 2,
+ _US_ACTION_MASK = 3,
+ _US_FORCE_UNWIND = 8,
+ _US_END_OF_STACK = 16
+ }
+ _Unwind_State;
+
+ /* Provided only for for compatibility with existing code. */
+ typedef int _Unwind_Action;
+#define _UA_SEARCH_PHASE 1
+#define _UA_CLEANUP_PHASE 2
+#define _UA_HANDLER_FRAME 4
+#define _UA_FORCE_UNWIND 8
+#define _UA_END_OF_STACK 16
+#define _URC_NO_REASON _URC_OK
+
+ typedef struct _Unwind_Control_Block _Unwind_Control_Block;
+ typedef struct _Unwind_Context _Unwind_Context;
+ typedef _uw _Unwind_EHT_Header;
+
+
+ /* UCB: */
+
+ struct _Unwind_Control_Block
+ {
+#ifdef _LIBC
+ /* For the benefit of code which assumes this is a scalar. All
+ glibc ever does is clear it. */
+ _uw64 exception_class;
+#else
+ char exception_class[8];
+#endif
+ void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block *);
+ /* Unwinder cache, private fields for the unwinder's use */
+ struct
+ {
+ _uw reserved1; /* Forced unwind stop fn, 0 if not forced */
+ _uw reserved2; /* Personality routine address */
+ _uw reserved3; /* Saved callsite address */
+ _uw reserved4; /* Forced unwind stop arg */
+ _uw reserved5;
+ }
+ unwinder_cache;
+ /* Propagation barrier cache (valid after phase 1): */
+ struct
+ {
+ _uw sp;
+ _uw bitpattern[5];
+ }
+ barrier_cache;
+ /* Cleanup cache (preserved over cleanup): */
+ struct
+ {
+ _uw bitpattern[4];
+ }
+ cleanup_cache;
+ /* Pr cache (for pr's benefit): */
+ struct
+ {
+ _uw fnstart; /* function start address */
+ _Unwind_EHT_Header *ehtp; /* pointer to EHT entry header word */
+ _uw additional; /* additional data */
+ _uw reserved1;
+ }
+ pr_cache;
+ long long int :0; /* Force alignment to 8-byte boundary */
+ };
+
+ /* Virtual Register Set*/
+
+ typedef enum
+ {
+ _UVRSC_CORE = 0, /* integer register */
+ _UVRSC_VFP = 1, /* vfp */
+ _UVRSC_FPA = 2, /* fpa */
+ _UVRSC_WMMXD = 3, /* Intel WMMX data register */
+ _UVRSC_WMMXC = 4 /* Intel WMMX control register */
+ }
+ _Unwind_VRS_RegClass;
+
+ typedef enum
+ {
+ _UVRSD_UINT32 = 0,
+ _UVRSD_VFPX = 1,
+ _UVRSD_FPAX = 2,
+ _UVRSD_UINT64 = 3,
+ _UVRSD_FLOAT = 4,
+ _UVRSD_DOUBLE = 5
+ }
+ _Unwind_VRS_DataRepresentation;
+
+ typedef enum
+ {
+ _UVRSR_OK = 0,
+ _UVRSR_NOT_IMPLEMENTED = 1,
+ _UVRSR_FAILED = 2
+ }
+ _Unwind_VRS_Result;
+
+ /* Frame unwinding state. */
+ typedef struct
+ {
+ /* The current word (bytes packed msb first). */
+ _uw data;
+ /* Pointer to the next word of data. */
+ _uw *next;
+ /* The number of bytes left in this word. */
+ _uw8 bytes_left;
+ /* The number of words pointed to by ptr. */
+ _uw8 words_left;
+ }
+ __gnu_unwind_state;
+
+ typedef _Unwind_Reason_Code (*personality_routine) (_Unwind_State,
+ _Unwind_Control_Block *, _Unwind_Context *);
+
+ _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *, _Unwind_VRS_RegClass,
+ _uw, _Unwind_VRS_DataRepresentation,
+ void *);
+
+ _Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context *, _Unwind_VRS_RegClass,
+ _uw, _Unwind_VRS_DataRepresentation,
+ void *);
+
+ _Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context *, _Unwind_VRS_RegClass,
+ _uw, _Unwind_VRS_DataRepresentation);
+
+
+ /* Support functions for the PR. */
+#define _Unwind_Exception _Unwind_Control_Block
+ typedef char _Unwind_Exception_Class[8];
+
+ void * _Unwind_GetLanguageSpecificData (_Unwind_Context *);
+ _Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *);
+
+ /* These two should never be used. */
+ _Unwind_Ptr _Unwind_GetDataRelBase (_Unwind_Context *);
+ _Unwind_Ptr _Unwind_GetTextRelBase (_Unwind_Context *);
+
+ /* Interface functions: */
+ _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Control_Block *ucbp);
+ void __attribute__((noreturn)) _Unwind_Resume(_Unwind_Control_Block *ucbp);
+ _Unwind_Reason_Code _Unwind_Resume_or_Rethrow (_Unwind_Control_Block *ucbp);
+
+ typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
+ (int, _Unwind_Action, _Unwind_Exception_Class,
+ _Unwind_Control_Block *, struct _Unwind_Context *, void *);
+ _Unwind_Reason_Code _Unwind_ForcedUnwind (_Unwind_Control_Block *,
+ _Unwind_Stop_Fn, void *);
+ _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *);
+ void _Unwind_Complete(_Unwind_Control_Block *ucbp);
+ void _Unwind_DeleteException (_Unwind_Exception *);
+
+ _Unwind_Reason_Code __gnu_unwind_frame (_Unwind_Control_Block *,
+ _Unwind_Context *);
+ _Unwind_Reason_Code __gnu_unwind_execute (_Unwind_Context *,
+ __gnu_unwind_state *);
+
+ /* Decode an R_ARM_TARGET2 relocation. */
+ static inline _Unwind_Word
+ _Unwind_decode_target2 (_Unwind_Word ptr)
+ {
+ _Unwind_Word tmp;
+
+ tmp = *(_Unwind_Word *) ptr;
+ /* Zero values are always NULL. */
+ if (!tmp)
+ return 0;
+
+#if defined(linux) || defined(__NetBSD__)
+ /* Pc-relative indirect. */
+ tmp += ptr;
+ tmp = *(_Unwind_Word *) tmp;
+#elif defined(__symbian__)
+ /* Absolute pointer. Nothing more to do. */
+#else
+ /* Pc-relative pointer. */
+ tmp += ptr;
+#endif
+ return tmp;
+ }
+
+ static inline _Unwind_Word
+ _Unwind_GetGR (_Unwind_Context *context, int regno)
+ {
+ _uw val;
+ _Unwind_VRS_Get (context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val);
+ return val;
+ }
+
+ /* Return the address of the instruction, not the actual IP value. */
+#define _Unwind_GetIP(context) \
+ (_Unwind_GetGR (context, 15) & ~(_Unwind_Word)1)
+
+ static inline void
+ _Unwind_SetGR (_Unwind_Context *context, int regno, _Unwind_Word val)
+ {
+ _Unwind_VRS_Set (context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val);
+ }
+
+ /* The dwarf unwinder doesn't understand arm/thumb state. We assume the
+ landing pad uses the same instruction set as the call site. */
+#define _Unwind_SetIP(context, val) \
+ _Unwind_SetGR (context, 15, val | (_Unwind_GetGR (context, 15) & 1))
+
+typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)
+ (struct _Unwind_Context *, void *);
+
+extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* defined UNWIND_ARM_H */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/vfork.S
new file mode 100644
index 000000000..935a4e904
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/vfork.S
@@ -0,0 +1,39 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <tcb-offsets.h>
+
+/* Save the PID value. */
+#define SAVE_PID \
+ str lr, [sp, #-4]!; /* Save LR. */ \
+ mov r0, #0xffff0fff; /* Point to the high page. */ \
+ mov lr, pc; /* Save our return address. */ \
+ sub pc, r0, #31; /* Jump to the TLS entry. */ \
+ ldr lr, [sp], #4; /* Restore LR. */ \
+ mov r2, r0; /* Save the TLS addr in r2. */ \
+ ldr r3, [r2, #PID_OFFSET]; /* Load the saved PID. */ \
+ rsbs r0, r3, #0; /* Negate it. */ \
+ moveq r0, #0x80000000; /* Use 0x80000000 if it was 0. */ \
+ str r0, [r2, #PID_OFFSET] /* Store the temporary PID. */
+
+/* Restore the old PID value in the parent. */
+#define RESTORE_PID \
+ cmp r0, #0; /* If we are the parent... */ \
+ strne r3, [r2, #PID_OFFSET] /* ... restore the saved PID. */
+
+#include "../../../../../../../libc/sysdeps/linux/arm/vfork.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h b/libpthread/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h
new file mode 100644
index 000000000..8f0df4f92
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/bits/local_lim.h
@@ -0,0 +1,100 @@
+/* Minimum guaranteed maximum values for system limits. Linux version.
+ Copyright (C) 1993-1998,2000,2002-2004,2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* The kernel header pollutes the namespace with the NR_OPEN symbol
+ and defines LINK_MAX although filesystems have different maxima. A
+ similar thing is true for OPEN_MAX: the limit can be changed at
+ runtime and therefore the macro must not be defined. Remove this
+ after including the header if necessary. */
+#ifndef NR_OPEN
+# define __undef_NR_OPEN
+#endif
+#ifndef LINK_MAX
+# define __undef_LINK_MAX
+#endif
+#ifndef OPEN_MAX
+# define __undef_OPEN_MAX
+#endif
+#ifndef ARG_MAX
+# define __undef_ARG_MAX
+#endif
+
+/* The kernel sources contain a file with all the needed information. */
+#include <linux/limits.h>
+
+/* Have to remove NR_OPEN? */
+#ifdef __undef_NR_OPEN
+# undef NR_OPEN
+# undef __undef_NR_OPEN
+#endif
+/* Have to remove LINK_MAX? */
+#ifdef __undef_LINK_MAX
+# undef LINK_MAX
+# undef __undef_LINK_MAX
+#endif
+/* Have to remove OPEN_MAX? */
+#ifdef __undef_OPEN_MAX
+# undef OPEN_MAX
+# undef __undef_OPEN_MAX
+#endif
+/* Have to remove ARG_MAX? */
+#ifdef __undef_ARG_MAX
+# undef ARG_MAX
+# undef __undef_ARG_MAX
+#endif
+
+/* The number of data keys per process. */
+#define _POSIX_THREAD_KEYS_MAX 128
+/* This is the value this implementation supports. */
+#define PTHREAD_KEYS_MAX 1024
+
+/* Controlling the iterations of destructors for thread-specific data. */
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+/* Number of iterations this implementation does. */
+#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+
+/* The number of threads per process. */
+#define _POSIX_THREAD_THREADS_MAX 64
+/* We have no predefined limit on the number of threads. */
+#undef PTHREAD_THREADS_MAX
+
+/* Maximum amount by which a process can descrease its asynchronous I/O
+ priority level. */
+#define AIO_PRIO_DELTA_MAX 20
+
+/* Minimum size for a thread. We are free to choose a reasonable value. */
+#define PTHREAD_STACK_MIN 16384
+
+/* Maximum number of timer expiration overruns. */
+#define DELAYTIMER_MAX 2147483647
+
+/* Maximum tty name length. */
+#define TTY_NAME_MAX 32
+
+/* Maximum login name length. This is arbitrary. */
+#define LOGIN_NAME_MAX 256
+
+/* Maximum host name length. */
+#define HOST_NAME_MAX 64
+
+/* Maximum message queue priority level. */
+#define MQ_PRIO_MAX 32768
+
+/* Maximum value the semaphore can have. */
+#define SEM_VALUE_MAX (2147483647)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h b/libpthread/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
new file mode 100644
index 000000000..2550355cd
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
@@ -0,0 +1,192 @@
+/* Define POSIX options for Linux.
+ Copyright (C) 1996-2004, 2006, 2008, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef _BITS_POSIX_OPT_H
+#define _BITS_POSIX_OPT_H 1
+
+/* Job control is supported. */
+#define _POSIX_JOB_CONTROL 1
+
+/* Processes have a saved set-user-ID and a saved set-group-ID. */
+#define _POSIX_SAVED_IDS 1
+
+/* Priority scheduling is supported. */
+#define _POSIX_PRIORITY_SCHEDULING 200809L
+
+/* Synchronizing file data is supported. */
+#define _POSIX_SYNCHRONIZED_IO 200809L
+
+/* The fsync function is present. */
+#define _POSIX_FSYNC 200809L
+
+/* Mapping of files to memory is supported. */
+#define _POSIX_MAPPED_FILES 200809L
+
+/* Locking of all memory is supported. */
+#define _POSIX_MEMLOCK 200809L
+
+/* Locking of ranges of memory is supported. */
+#define _POSIX_MEMLOCK_RANGE 200809L
+
+/* Setting of memory protections is supported. */
+#define _POSIX_MEMORY_PROTECTION 200809L
+
+/* Some filesystems allow all users to change file ownership. */
+#define _POSIX_CHOWN_RESTRICTED 0
+
+/* `c_cc' member of 'struct termios' structure can be disabled by
+ using the value _POSIX_VDISABLE. */
+#define _POSIX_VDISABLE '\0'
+
+/* Filenames are not silently truncated. */
+#define _POSIX_NO_TRUNC 1
+
+/* X/Open realtime support is available. */
+#define _XOPEN_REALTIME 1
+
+/* X/Open thread realtime support is available. */
+#define _XOPEN_REALTIME_THREADS 1
+
+/* XPG4.2 shared memory is supported. */
+#define _XOPEN_SHM 1
+
+/* Tell we have POSIX threads. */
+#define _POSIX_THREADS 200809L
+
+/* We have the reentrant functions described in POSIX. */
+#define _POSIX_REENTRANT_FUNCTIONS 1
+#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L
+
+/* We provide priority scheduling for threads. */
+#define _POSIX_THREAD_PRIORITY_SCHEDULING 200809L
+
+/* We support user-defined stack sizes. */
+#define _POSIX_THREAD_ATTR_STACKSIZE 200809L
+
+/* We support user-defined stacks. */
+#define _POSIX_THREAD_ATTR_STACKADDR 200809L
+
+/* We support priority inheritence. */
+#define _POSIX_THREAD_PRIO_INHERIT 200809L
+
+/* We support priority protection, though only for non-robust
+ mutexes. */
+#define _POSIX_THREAD_PRIO_PROTECT 200809L
+
+#ifdef __USE_XOPEN2K8
+/* We support priority inheritence for robust mutexes. */
+# define _POSIX_THREAD_ROBUST_PRIO_INHERIT 200809L
+
+/* We do not support priority protection for robust mutexes. */
+# define _POSIX_THREAD_ROBUST_PRIO_PROTECT -1
+#endif
+
+/* We support POSIX.1b semaphores. */
+#define _POSIX_SEMAPHORES 200809L
+
+/* Real-time signals are supported. */
+#define _POSIX_REALTIME_SIGNALS 200809L
+
+/* We support asynchronous I/O. */
+#define _POSIX_ASYNCHRONOUS_IO 200809L
+#define _POSIX_ASYNC_IO 1
+/* Alternative name for Unix98. */
+#define _LFS_ASYNCHRONOUS_IO 1
+/* Support for prioritization is also available. */
+#define _POSIX_PRIORITIZED_IO 200809L
+
+/* The LFS support in asynchronous I/O is also available. */
+#define _LFS64_ASYNCHRONOUS_IO 1
+
+/* The rest of the LFS is also available. */
+#define _LFS_LARGEFILE 1
+#define _LFS64_LARGEFILE 1
+#define _LFS64_STDIO 1
+
+/* POSIX shared memory objects are implemented. */
+#define _POSIX_SHARED_MEMORY_OBJECTS 200809L
+
+/* CPU-time clocks support needs to be checked at runtime. */
+#define _POSIX_CPUTIME 0
+
+/* Clock support in threads must be also checked at runtime. */
+#define _POSIX_THREAD_CPUTIME 0
+
+/* GNU libc provides regular expression handling. */
+#define _POSIX_REGEXP 1
+
+/* Reader/Writer locks are available. */
+#define _POSIX_READER_WRITER_LOCKS 200809L
+
+/* We have a POSIX shell. */
+#define _POSIX_SHELL 1
+
+/* We support the Timeouts option. */
+#define _POSIX_TIMEOUTS 200809L
+
+/* We support spinlocks. */
+#define _POSIX_SPIN_LOCKS 200809L
+
+/* The `spawn' function family is supported. */
+#define _POSIX_SPAWN 200809L
+
+/* We have POSIX timers. */
+#define _POSIX_TIMERS 200809L
+
+/* The barrier functions are available. */
+#define _POSIX_BARRIERS 200809L
+
+/* POSIX message queues are available. */
+#define _POSIX_MESSAGE_PASSING 200809L
+
+/* Thread process-shared synchronization is supported. */
+#define _POSIX_THREAD_PROCESS_SHARED 200809L
+
+/* The monotonic clock might be available. */
+#define _POSIX_MONOTONIC_CLOCK 0
+
+/* The clock selection interfaces are available. */
+#define _POSIX_CLOCK_SELECTION 200809L
+
+/* Advisory information interfaces are available. */
+#define _POSIX_ADVISORY_INFO 200809L
+
+/* IPv6 support is available. */
+#define _POSIX_IPV6 200809L
+
+/* Raw socket support is available. */
+#define _POSIX_RAW_SOCKETS 200809L
+
+/* We have at least one terminal. */
+#define _POSIX2_CHAR_TERM 200809L
+
+/* Neither process nor thread sporadic server interfaces is available. */
+#define _POSIX_SPORADIC_SERVER -1
+#define _POSIX_THREAD_SPORADIC_SERVER -1
+
+/* trace.h is not available. */
+#define _POSIX_TRACE -1
+#define _POSIX_TRACE_EVENT_FILTER -1
+#define _POSIX_TRACE_INHERIT -1
+#define _POSIX_TRACE_LOG -1
+
+/* Typed memory objects are not available. */
+#define _POSIX_TYPED_MEMORY_OBJECTS -1
+
+#endif /* bits/posix_opt.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/close.S b/libpthread/nptl/sysdeps/unix/sysv/linux/close.S
new file mode 100644
index 000000000..cf50a1eae
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/close.S
@@ -0,0 +1,21 @@
+#include <sysdep-cancel.h>
+
+/*
+extern int __close_nocancel (int) attribute_hidden;
+*/
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+
+PSEUDO (__libc_close, close, 1)
+ret
+PSEUDO_END(__libc_close)
+
+libc_hidden_def (__close_nocancel)
+libc_hidden_def (__libc_close)
+weak_alias (__libc_close, __close)
+libc_hidden_weak (__close)
+weak_alias (__libc_close, close)
+libc_hidden_weak (close)
+
+
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/connect.S b/libpthread/nptl/sysdeps/unix/sysv/linux/connect.S
new file mode 100644
index 000000000..441843fa0
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/connect.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_connect
+#error Missing definition of NR_connect needed for cancellation.
+#endif
+PSEUDO (__libc_connect, connect, 3)
+ret
+PSEUDO_END(__libc_connect)
+libc_hidden_def (__libc_connect)
+weak_alias (__libc_connect, __connect)
+libc_hidden_weak (__connect)
+weak_alias (__libc_connect, connect)
+libc_hidden_weak (connect)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/creat.S b/libpthread/nptl/sysdeps/unix/sysv/linux/creat.S
new file mode 100644
index 000000000..cd0e1b879
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/creat.S
@@ -0,0 +1,7 @@
+#include <sysdep-cancel.h>
+PSEUDO (__libc_creat, creat, 2)
+ret
+PSEUDO_END(__libc_creat)
+libc_hidden_def (__libc_creat)
+weak_alias (__libc_creat, creat)
+libc_hidden_weak (creat)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/createthread.c
new file mode 100644
index 000000000..9149efe58
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/createthread.c
@@ -0,0 +1,24 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Value passed to 'clone' for initialization of the thread register. */
+#define TLS_VALUE pd
+
+/* Get the real implementation. */
+#include <sysdeps/pthread/createthread.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/exit-thread.S b/libpthread/nptl/sysdeps/unix/sysv/linux/exit-thread.S
new file mode 100644
index 000000000..bb996fecf
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/exit-thread.S
@@ -0,0 +1,23 @@
+/* Copyright (C) 1991,92,97,99,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+PSEUDO (__exit_thread, exit, 1)
+ /* Shouldn't get here. */
+PSEUDO_END(__exit_thread)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/fork.c
new file mode 100644
index 000000000..2d4cae224
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/fork.c
@@ -0,0 +1,229 @@
+/* Copyright (C) 2002, 2003, 2007, 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sysdep.h>
+#include <tls.h>
+#include "fork.h"
+#include <hp-timing.h>
+#include <ldsodefs.h>
+#include <atomic.h>
+#include <errno.h>
+
+unsigned long int *__fork_generation_pointer;
+
+
+
+/* The single linked list of all currently registered for handlers. */
+struct fork_handler *__fork_handlers;
+
+
+static void
+fresetlockfiles (void)
+{
+ FILE *fp;
+#ifdef __USE_STDIO_FUTEXES__
+ for (fp = _stdio_openlist; fp != NULL; fp = fp->__nextopen)
+ STDIO_INIT_MUTEX(fp->__lock);
+#else
+ pthread_mutexattr_t attr;
+
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
+
+ for (fp = _stdio_openlist; fp != NULL; fp = fp->__nextopen)
+ pthread_mutex_init(&fp->__lock, &attr);
+
+ pthread_mutexattr_destroy(&attr);
+#endif
+}
+
+
+pid_t
+__libc_fork (void)
+{
+ pid_t pid;
+ struct used_handler
+ {
+ struct fork_handler *handler;
+ struct used_handler *next;
+ } *allp = NULL;
+
+ /* Run all the registered preparation handlers. In reverse order.
+ While doing this we build up a list of all the entries. */
+ struct fork_handler *runp;
+ while ((runp = __fork_handlers) != NULL)
+ {
+ /* Make sure we read from the current RUNP pointer. */
+ atomic_full_barrier ();
+
+ unsigned int oldval = runp->refcntr;
+
+ if (oldval == 0)
+ /* This means some other thread removed the list just after
+ the pointer has been loaded. Try again. Either the list
+ is empty or we can retry it. */
+ continue;
+
+ /* Bump the reference counter. */
+ if (atomic_compare_and_exchange_bool_acq (&__fork_handlers->refcntr,
+ oldval + 1, oldval))
+ /* The value changed, try again. */
+ continue;
+
+ /* We bumped the reference counter for the first entry in the
+ list. That means that none of the following entries will
+ just go away. The unloading code works in the order of the
+ list.
+
+ While executing the registered handlers we are building a
+ list of all the entries so that we can go backward later on. */
+ while (1)
+ {
+ /* Execute the handler if there is one. */
+ if (runp->prepare_handler != NULL)
+ runp->prepare_handler ();
+
+ /* Create a new element for the list. */
+ struct used_handler *newp
+ = (struct used_handler *) alloca (sizeof (*newp));
+ newp->handler = runp;
+ newp->next = allp;
+ allp = newp;
+
+ /* Advance to the next handler. */
+ runp = runp->next;
+ if (runp == NULL)
+ break;
+
+ /* Bump the reference counter for the next entry. */
+ atomic_increment (&runp->refcntr);
+ }
+
+ /* We are done. */
+ break;
+ }
+
+ __UCLIBC_IO_MUTEX_LOCK_CANCEL_UNSAFE(_stdio_openlist_add_lock);
+
+#ifndef NDEBUG
+ pid_t ppid = THREAD_GETMEM (THREAD_SELF, tid);
+#endif
+
+ /* We need to prevent the getpid() code to update the PID field so
+ that, if a signal arrives in the child very early and the signal
+ handler uses getpid(), the value returned is correct. */
+ pid_t parentpid = THREAD_GETMEM (THREAD_SELF, pid);
+ THREAD_SETMEM (THREAD_SELF, pid, -parentpid);
+
+#ifdef ARCH_FORK
+ pid = ARCH_FORK ();
+#else
+# error "ARCH_FORK must be defined so that the CLONE_SETTID flag is used"
+ pid = INLINE_SYSCALL (fork, 0);
+#endif
+
+
+ if (pid == 0)
+ {
+ struct pthread *self = THREAD_SELF;
+
+ assert (THREAD_GETMEM (self, tid) != ppid);
+
+ if (__fork_generation_pointer != NULL)
+ *__fork_generation_pointer += 4;
+
+ /* Adjust the PID field for the new process. */
+ THREAD_SETMEM (self, pid, THREAD_GETMEM (self, tid));
+
+#if HP_TIMING_AVAIL
+ /* The CPU clock of the thread and process have to be set to zero. */
+ hp_timing_t now;
+ HP_TIMING_NOW (now);
+ THREAD_SETMEM (self, cpuclock_offset, now);
+ GL(dl_cpuclock_offset) = now;
+#endif
+
+ /* Reset the file list. These are recursive mutexes. */
+ fresetlockfiles ();
+
+ /* Reset locks in the I/O code. */
+ STDIO_INIT_MUTEX(_stdio_openlist_add_lock);
+
+ /* XXX reset any locks in dynamic loader */
+
+ /* Run the handlers registered for the child. */
+ while (allp != NULL)
+ {
+ if (allp->handler->child_handler != NULL)
+ allp->handler->child_handler ();
+
+ /* Note that we do not have to wake any possible waiter.
+ This is the only thread in the new process. The count
+ may have been bumped up by other threads doing a fork.
+ We reset it to 1, to avoid waiting for non-existing
+ thread(s) to release the count. */
+ allp->handler->refcntr = 1;
+
+ /* XXX We could at this point look through the object pool
+ and mark all objects not on the __fork_handlers list as
+ unused. This is necessary in case the fork() happened
+ while another thread called dlclose() and that call had
+ to create a new list. */
+
+ allp = allp->next;
+ }
+
+ /* Initialize the fork lock. */
+ __fork_lock = LLL_LOCK_INITIALIZER;
+ }
+ else
+ {
+ assert (THREAD_GETMEM (THREAD_SELF, tid) == ppid);
+
+ /* Restore the PID value. */
+ THREAD_SETMEM (THREAD_SELF, pid, parentpid);
+
+ /* We execute this even if the 'fork' call failed. */
+ __UCLIBC_IO_MUTEX_UNLOCK_CANCEL_UNSAFE(_stdio_openlist_add_lock);
+
+ /* Run the handlers registered for the parent. */
+ while (allp != NULL)
+ {
+ if (allp->handler->parent_handler != NULL)
+ allp->handler->parent_handler ();
+
+ if (atomic_decrement_and_test (&allp->handler->refcntr)
+ && allp->handler->need_signal)
+ lll_futex_wake (allp->handler->refcntr, 1, LLL_PRIVATE);
+
+ allp = allp->next;
+ }
+ }
+
+ return pid;
+}
+weak_alias(__libc_fork,__fork)
+libc_hidden_proto(fork)
+weak_alias(__libc_fork,fork)
+libc_hidden_weak(fork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/fork.h b/libpthread/nptl/sysdeps/unix/sysv/linux/fork.h
new file mode 100644
index 000000000..a00cfabe2
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/fork.h
@@ -0,0 +1,60 @@
+/* Copyright (C) 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <lowlevellock.h>
+
+/* The fork generation counter, defined in libpthread. */
+extern unsigned long int __fork_generation attribute_hidden;
+
+/* Pointer to the fork generation counter in the thread library. */
+extern unsigned long int *__fork_generation_pointer attribute_hidden;
+
+/* Lock to protect allocation and deallocation of fork handlers. */
+extern int __fork_lock attribute_hidden;
+
+/* Elements of the fork handler lists. */
+struct fork_handler
+{
+ struct fork_handler *next;
+ void (*prepare_handler) (void);
+ void (*parent_handler) (void);
+ void (*child_handler) (void);
+ void *dso_handle;
+ unsigned int refcntr;
+ int need_signal;
+};
+
+/* The single linked list of all currently registered for handlers. */
+extern struct fork_handler *__fork_handlers attribute_hidden;
+
+
+/* Function to call to unregister fork handlers. */
+extern void __unregister_atfork (void *dso_handle) attribute_hidden;
+#define UNREGISTER_ATFORK(dso_handle) __unregister_atfork (dso_handle)
+
+
+/* C library side function to register new fork handlers. */
+extern int __register_atfork (void (*__prepare) (void),
+ void (*__parent) (void),
+ void (*__child) (void),
+ void *dso_handle);
+libc_hidden_proto (__register_atfork)
+
+/* Add a new element to the fork list. */
+extern void __linkin_atfork (struct fork_handler *newp) attribute_hidden;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/getpid.c b/libpthread/nptl/sysdeps/unix/sysv/linux/getpid.c
new file mode 100644
index 000000000..96e2bf439
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/getpid.c
@@ -0,0 +1,64 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <tls.h>
+#include <sysdep.h>
+
+
+#ifndef NOT_IN_libc
+static inline __attribute__((always_inline)) pid_t really_getpid (pid_t oldval);
+
+static inline __attribute__((always_inline)) pid_t
+really_getpid (pid_t oldval)
+{
+ if (__builtin_expect (oldval == 0, 1))
+ {
+ pid_t selftid = THREAD_GETMEM (THREAD_SELF, tid);
+ if (__builtin_expect (selftid != 0, 1))
+ return selftid;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+ pid_t result = INTERNAL_SYSCALL (getpid, err, 0);
+
+ /* We do not set the PID field in the TID here since we might be
+ called from a signal handler while the thread executes fork. */
+ if (oldval == 0)
+ THREAD_SETMEM (THREAD_SELF, tid, result);
+ return result;
+}
+#endif
+
+pid_t
+__getpid (void)
+{
+#ifdef NOT_IN_libc
+ INTERNAL_SYSCALL_DECL (err);
+ pid_t result = INTERNAL_SYSCALL (getpid, err, 0);
+#else
+ pid_t result = THREAD_GETMEM (THREAD_SELF, pid);
+ if (__builtin_expect (result <= 0, 0))
+ result = really_getpid (result);
+#endif
+ return result;
+}
+libc_hidden_proto(getpid)
+weak_alias(__getpid, getpid)
+libc_hidden_weak(getpid)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile
new file mode 100644
index 000000000..43a6fad84
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile
@@ -0,0 +1,13 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../../../../../
+top_builddir=../../../../../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.arch
+include $(top_srcdir)Makerules
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile.arch
new file mode 100644
index 000000000..570aa560e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile.arch
@@ -0,0 +1,71 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+LINUX_ARCH_DIR:=$(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/i386
+LINUX_ARCH_OUT:=$(top_builddir)libpthread/nptl/sysdeps/unix/sysv/linux/i386
+
+ASFLAGS += -DUSE___THREAD
+
+libpthread_SSRC = pt-vfork.S clone.S pthread_spin_unlock.S pthread_once.S
+libpthread_CSRC = pthread_spin_init.c pt-__syscall_error.c
+
+libc_a_CSRC = fork.c
+libc_a_SSRC = clone.S vfork.S
+
+libpthread_SSRC += i486/lowlevellock.S i486/pthread_barrier_wait.S i486/pthread_cond_signal.S i486/pthread_cond_broadcast.S \
+ i486/lowlevelrobustlock.S i486/sem_post.S i486/sem_timedwait.S \
+ i486/sem_trywait.S i486/sem_wait.S i486/pthread_rwlock_rdlock.S i486/pthread_rwlock_wrlock.S \
+ i486/pthread_rwlock_timedrdlock.S i486/pthread_rwlock_timedwrlock.S i486/pthread_rwlock_unlock.S
+#i486/pthread_cond_timedwait.S i486/pthread_cond_wait.S
+
+libc_a_SSRC += i486/libc-lowlevellock.S
+
+
+CFLAGS-OMIT-fork.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-pt-__syscall_error.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
+ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y)
+CFLAGS-fork.c = -D__USE_STDIO_FUTEXES__
+endif
+
+ASFLAGS-pt-vfork.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT
+ASFLAGS-lowlevellock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT
+ASFLAGS-lowlevelrobustlock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT
+ASFLAGS-pthread_once.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT
+ASFLAGS-pthread_spin_unlock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT
+
+
+ASFLAGS-clone.S = -D_LIBC_REENTRANT
+ASFLAGS-vfork.S = -D_LIBC_REENTRANT
+ASFLAGS-libc-lowlevellock.S = -D_LIBC_REENTRANT
+
+CFLAGS += $(SSP_ALL_CFLAGS)
+#CFLAGS:=$(CFLAGS:-O1=-O2)
+
+LINUX_ARCH_OBJ:=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libpthread_SSRC))
+LINUX_ARCH_OBJ+=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libpthread_CSRC))
+
+ifeq ($(DOPIC),y)
+libpthread-a-y += $(LINUX_ARCH_OBJ:.o=.os)
+else
+libpthread-a-y += $(LINUX_ARCH_OBJ)
+endif
+libpthread-so-y += $(LINUX_ARCH_OBJ:.o=.oS)
+
+libpthread-nomulti-y+=$(LINUX_ARCH_OBJS)
+
+LIBC_LINUX_ARCH_OBJ:=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libc_a_CSRC))
+LIBC_LINUX_ARCH_OBJ+=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libc_a_SSRC))
+
+libc-static-y+=$(LIBC_LINUX_ARCH_OBJ)
+libc-shared-y+=$(LIBC_LINUX_ARCH_OBJ:.o=.oS)
+
+libc-nomulti-y+=$(LIBC_LINUX_ARCH_OBJ)
+
+objclean-y+=nptl_linux_arch_clean
+
+nptl_linux_arch_clean:
+ $(do_rm) $(addprefix $(LINUX_ARCH_OUT)/*., o os oS)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h
new file mode 100644
index 000000000..9e3e016fb
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h
@@ -0,0 +1,173 @@
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H 1
+
+#define __SIZEOF_PTHREAD_ATTR_T 36
+#define __SIZEOF_PTHREAD_MUTEX_T 24
+#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+#define __SIZEOF_PTHREAD_COND_T 48
+#define __SIZEOF_PTHREAD_COND_COMPAT_T 12
+#define __SIZEOF_PTHREAD_CONDATTR_T 4
+#define __SIZEOF_PTHREAD_RWLOCK_T 32
+#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+#define __SIZEOF_PTHREAD_BARRIER_T 20
+#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+
+
+/* Thread identifiers. The structure of the attribute type is not
+ exposed on purpose. */
+typedef unsigned long int pthread_t;
+
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_ATTR_T];
+ long int __align;
+} pthread_attr_t;
+
+
+typedef struct __pthread_internal_slist
+{
+ struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+
+
+/* Data structures for mutex handling. The structure of the attribute
+ type is not exposed on purpose. */
+typedef union
+{
+ struct __pthread_mutex_s
+ {
+ int __lock;
+ unsigned int __count;
+ int __owner;
+ /* KIND must stay at this position in the structure to maintain
+ binary compatibility. */
+ int __kind;
+ unsigned int __nusers;
+ __extension__ union
+ {
+ int __spins;
+ __pthread_slist_t __list;
+ };
+ } __data;
+ char __size[__SIZEOF_PTHREAD_MUTEX_T];
+ long int __align;
+} pthread_mutex_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+ long int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling. The structure of
+ the attribute type is not exposed on purpose. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned int __futex;
+ __extension__ unsigned long long int __total_seq;
+ __extension__ unsigned long long int __wakeup_seq;
+ __extension__ unsigned long long int __woken_seq;
+ void *__mutex;
+ unsigned int __nwaiters;
+ unsigned int __broadcast_seq;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_COND_T];
+ __extension__ long long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+ long int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Data structure for read-write lock variable handling. The
+ structure of the attribute type is not exposed on purpose. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned int __nr_readers;
+ unsigned int __readers_wakeup;
+ unsigned int __writer_wakeup;
+ unsigned int __nr_readers_queued;
+ unsigned int __nr_writers_queued;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned char __flags;
+ unsigned char __shared;
+ unsigned char __pad1;
+ unsigned char __pad2;
+ int __writer;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+ long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+ long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type. */
+typedef volatile int pthread_spinlock_t;
+
+
+/* POSIX barriers data type. The structure of the type is
+ deliberately not exposed. */
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIER_T];
+ long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+ int __align;
+} pthread_barrierattr_t;
+#endif
+
+
+/* Extra attributes for the cleanup functions. */
+#define __cleanup_fct_attribute __attribute__ ((__regparm__ (1)))
+
+#endif /* bits/pthreadtypes.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h
new file mode 100644
index 000000000..934493c30
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+
+#define __SIZEOF_SEM_T 16
+
+
+/* Value returned if `sem_open' failed. */
+#define SEM_FAILED ((sem_t *) 0)
+
+
+typedef union
+{
+ char __size[__SIZEOF_SEM_T];
+ long int __align;
+} sem_t;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/clone.S
new file mode 100644
index 000000000..9c7c46467
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/clone.S
@@ -0,0 +1,2 @@
+#define RESET_PID
+#include <libc/sysdeps/linux/i386/clone.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/createthread.c
new file mode 100644
index 000000000..35719be96
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/createthread.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The "thread register" gets initialized from a segment descriptor.
+ Initialize such a descriptor first. */
+#define PREPARE_CREATE \
+ union user_desc_init desc; \
+ \
+ /* Describe the thread-local storage segment. */ \
+ \
+ /* The 'entry_number' field. The first three bits of the segment \
+ register value select the GDT, ignore them. We get the index \
+ from the value of the %gs register in the current thread. */ \
+ desc.vals[0] = TLS_GET_GS () >> 3; \
+ /* The 'base_addr' field. Pointer to the TCB. */ \
+ desc.vals[1] = (unsigned long int) pd; \
+ /* The 'limit' field. We use 4GB which is 0xfffff pages. */ \
+ desc.vals[2] = 0xfffff; \
+ /* Collapsed value of the bitfield: \
+ .seg_32bit = 1 \
+ .contents = 0 \
+ .read_exec_only = 0 \
+ .limit_in_pages = 1 \
+ .seg_not_present = 0 \
+ .useable = 1 */ \
+ desc.vals[3] = 0x51
+
+/* Value passed to 'clone' for initialization of the thread register. */
+#define TLS_VALUE &desc.desc
+
+
+/* Get the real implementation. */
+#include <sysdeps/pthread/createthread.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/fork.c
new file mode 100644
index 000000000..813e5299a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/fork.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sched.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+
+
+#define ARCH_FORK() \
+ INLINE_SYSCALL (clone, 5, \
+ CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0, \
+ NULL, NULL, &THREAD_SELF->tid)
+
+#include "../fork.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S
new file mode 100644
index 000000000..ce8ad27aa
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "lowlevellock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
new file mode 100644
index 000000000..00f8b56f9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
@@ -0,0 +1,459 @@
+/* Copyright (C) 2002-2004, 2006, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <lowlevellock.h>
+#include <tcb-offsets.h>
+
+ .text
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+ movl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
+# define LOAD_PRIVATE_FUTEX_WAKE(reg) \
+ movl $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
+# define LOAD_FUTEX_WAIT_ABS(reg) \
+ xorl $(FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME), reg
+# define LOAD_FUTEX_WAKE(reg) \
+ xorl $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg
+#else
+# if FUTEX_WAIT == 0
+# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+ movl %gs:PRIVATE_FUTEX, reg
+# else
+# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+ movl %gs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAIT, reg
+# endif
+# define LOAD_PRIVATE_FUTEX_WAKE(reg) \
+ movl %gs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAKE, reg
+# if FUTEX_WAIT == 0
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %gs:PRIVATE_FUTEX, reg
+# else
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %gs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAIT, reg
+# endif
+# define LOAD_FUTEX_WAIT_ABS(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %gs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME, reg
+# define LOAD_FUTEX_WAKE(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %gs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAKE, reg
+#endif
+
+ .globl __lll_lock_wait_private
+ .type __lll_lock_wait_private,@function
+ .hidden __lll_lock_wait_private
+ .align 16
+__lll_lock_wait_private:
+ cfi_startproc
+ pushl %edx
+ cfi_adjust_cfa_offset(4)
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%edx, -8)
+ cfi_offset(%ebx, -12)
+ cfi_offset(%esi, -16)
+
+ movl $2, %edx
+ movl %ecx, %ebx
+ xorl %esi, %esi /* No timeout. */
+ LOAD_PRIVATE_FUTEX_WAIT (%ecx)
+
+ cmpl %edx, %eax /* NB: %edx == 2 */
+ jne 2f
+
+1: movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+2: movl %edx, %eax
+ xchgl %eax, (%ebx) /* NB: lock is implied */
+
+ testl %eax, %eax
+ jnz 1b
+
+ popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ popl %edx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edx)
+ ret
+ cfi_endproc
+ .size __lll_lock_wait_private,.-__lll_lock_wait_private
+
+#ifdef NOT_IN_libc
+ .globl __lll_lock_wait
+ .type __lll_lock_wait,@function
+ .hidden __lll_lock_wait
+ .align 16
+__lll_lock_wait:
+ cfi_startproc
+ pushl %edx
+ cfi_adjust_cfa_offset(4)
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%edx, -8)
+ cfi_offset(%ebx, -12)
+ cfi_offset(%esi, -16)
+
+ movl %edx, %ebx
+ movl $2, %edx
+ xorl %esi, %esi /* No timeout. */
+ LOAD_FUTEX_WAIT (%ecx)
+
+ cmpl %edx, %eax /* NB: %edx == 2 */
+ jne 2f
+
+1: movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+2: movl %edx, %eax
+ xchgl %eax, (%ebx) /* NB: lock is implied */
+
+ testl %eax, %eax
+ jnz 1b
+
+ popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ popl %edx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edx)
+ ret
+ cfi_endproc
+ .size __lll_lock_wait,.-__lll_lock_wait
+
+ /* %ecx: futex
+ %esi: flags
+ %edx: timeout
+ %eax: futex value
+ */
+ .globl __lll_timedlock_wait
+ .type __lll_timedlock_wait,@function
+ .hidden __lll_timedlock_wait
+ .align 16
+__lll_timedlock_wait:
+ cfi_startproc
+ pushl %ebp
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%ebp, 0)
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%ebx, 0)
+
+# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+# ifdef __PIC__
+ LOAD_PIC_REG (bx)
+ cmpl $0, __have_futex_clock_realtime@GOTOFF(%ebx)
+# else
+ cmpl $0, __have_futex_clock_realtime
+# endif
+ je .Lreltmo
+# endif
+
+ movl %ecx, %ebx
+ movl %esi, %ecx
+ movl %edx, %esi
+ movl $0xffffffff, %ebp
+ LOAD_FUTEX_WAIT_ABS (%ecx)
+
+ movl $2, %edx
+ cmpl %edx, %eax
+ jne 2f
+
+1: movl $SYS_futex, %eax
+ movl $2, %edx
+ ENTER_KERNEL
+
+2: xchgl %edx, (%ebx) /* NB: lock is implied */
+
+ testl %edx, %edx
+ jz 3f
+
+ cmpl $-ETIMEDOUT, %eax
+ je 4f
+ cmpl $-EINVAL, %eax
+ jne 1b
+4: movl %eax, %edx
+ negl %edx
+
+3: movl %edx, %eax
+7: popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
+ ret
+
+# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+.Lreltmo:
+ /* Check for a valid timeout value. */
+ cmpl $1000000000, 4(%edx)
+ jae 3f
+
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%esi, 0)
+ pushl %edi
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%edi, 0)
+
+ /* Stack frame for the timespec and timeval structs. */
+ subl $8, %esp
+ cfi_adjust_cfa_offset(8)
+
+ movl %ecx, %ebp
+ movl %edx, %edi
+
+ movl $2, %edx
+ xchgl %edx, (%ebp)
+
+ test %edx, %edx
+ je 6f
+
+1:
+ /* Get current time. */
+ movl %esp, %ebx
+ xorl %ecx, %ecx
+ movl $__NR_gettimeofday, %eax
+ ENTER_KERNEL
+
+ /* Compute relative timeout. */
+ movl 4(%esp), %eax
+ movl $1000, %edx
+ mul %edx /* Milli seconds to nano seconds. */
+ movl (%edi), %ecx
+ movl 4(%edi), %edx
+ subl (%esp), %ecx
+ subl %eax, %edx
+ jns 4f
+ addl $1000000000, %edx
+ subl $1, %ecx
+4: testl %ecx, %ecx
+ js 2f /* Time is already up. */
+
+ /* Store relative timeout. */
+ movl %ecx, (%esp)
+ movl %edx, 4(%esp)
+
+ /* Futex call. */
+ movl %ebp, %ebx
+ movl $2, %edx
+ movl %esp, %esi
+ movl 16(%esp), %ecx
+ LOAD_FUTEX_WAIT (%ecx)
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+ /* NB: %edx == 2 */
+ xchgl %edx, (%ebp)
+
+ testl %edx, %edx
+ je 6f
+
+ cmpl $-ETIMEDOUT, %eax
+ jne 1b
+2: movl $ETIMEDOUT, %edx
+
+6: addl $8, %esp
+ cfi_adjust_cfa_offset(-8)
+ popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
+ popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+7: popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
+ movl %edx, %eax
+ ret
+
+3: movl $EINVAL, %edx
+ jmp 7b
+# endif
+ cfi_endproc
+ .size __lll_timedlock_wait,.-__lll_timedlock_wait
+#endif
+
+ .globl __lll_unlock_wake_private
+ .type __lll_unlock_wake_private,@function
+ .hidden __lll_unlock_wake_private
+ .align 16
+__lll_unlock_wake_private:
+ cfi_startproc
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ pushl %ecx
+ cfi_adjust_cfa_offset(4)
+ pushl %edx
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
+ cfi_offset(%ecx, -12)
+ cfi_offset(%edx, -16)
+
+ movl %eax, %ebx
+ movl $0, (%eax)
+ LOAD_PRIVATE_FUTEX_WAKE (%ecx)
+ movl $1, %edx /* Wake one thread. */
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+ popl %edx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edx)
+ popl %ecx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ecx)
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ ret
+ cfi_endproc
+ .size __lll_unlock_wake_private,.-__lll_unlock_wake_private
+
+#ifdef NOT_IN_libc
+ .globl __lll_unlock_wake
+ .type __lll_unlock_wake,@function
+ .hidden __lll_unlock_wake
+ .align 16
+__lll_unlock_wake:
+ cfi_startproc
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ pushl %ecx
+ cfi_adjust_cfa_offset(4)
+ pushl %edx
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
+ cfi_offset(%ecx, -12)
+ cfi_offset(%edx, -16)
+
+ movl %eax, %ebx
+ movl $0, (%eax)
+ LOAD_FUTEX_WAKE (%ecx)
+ movl $1, %edx /* Wake one thread. */
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+ popl %edx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edx)
+ popl %ecx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ecx)
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ ret
+ cfi_endproc
+ .size __lll_unlock_wake,.-__lll_unlock_wake
+
+ .globl __lll_timedwait_tid
+ .type __lll_timedwait_tid,@function
+ .hidden __lll_timedwait_tid
+ .align 16
+__lll_timedwait_tid:
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl %eax, %ebp
+ movl %edx, %edi
+ subl $8, %esp
+
+ /* Get current time. */
+2: movl %esp, %ebx
+ xorl %ecx, %ecx
+ movl $__NR_gettimeofday, %eax
+ ENTER_KERNEL
+
+ /* Compute relative timeout. */
+ movl 4(%esp), %eax
+ movl $1000, %edx
+ mul %edx /* Milli seconds to nano seconds. */
+ movl (%edi), %ecx
+ movl 4(%edi), %edx
+ subl (%esp), %ecx
+ subl %eax, %edx
+ jns 5f
+ addl $1000000000, %edx
+ subl $1, %ecx
+5: testl %ecx, %ecx
+ js 6f /* Time is already up. */
+
+ movl %ecx, (%esp) /* Store relative timeout. */
+ movl %edx, 4(%esp)
+
+ movl (%ebp), %edx
+ testl %edx, %edx
+ jz 4f
+
+ movl %esp, %esi
+ /* XXX The kernel so far uses global futex for the wakeup at
+ all times. */
+ xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */
+ movl %ebp, %ebx
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+ cmpl $0, (%ebx)
+ jne 1f
+4: xorl %eax, %eax
+
+3: addl $8, %esp
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+1: cmpl $-ETIMEDOUT, %eax
+ jne 2b
+6: movl $ETIMEDOUT, %eax
+ jmp 3b
+ .size __lll_timedwait_tid,.-__lll_timedwait_tid
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S
new file mode 100644
index 000000000..1d038001c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevelrobustlock.S
@@ -0,0 +1,234 @@
+/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <lowlevellock.h>
+#include <lowlevelrobustlock.h>
+#include <bits/kernel-features.h>
+#include <tls.h>
+
+ .text
+
+#define FUTEX_WAITERS 0x80000000
+#define FUTEX_OWNER_DIED 0x40000000
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
+#else
+# if FUTEX_WAIT == 0
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %gs:PRIVATE_FUTEX, reg
+# else
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %gs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAIT, reg
+# endif
+#endif
+
+ .globl __lll_robust_lock_wait
+ .type __lll_robust_lock_wait,@function
+ .hidden __lll_robust_lock_wait
+ .align 16
+__lll_robust_lock_wait:
+ cfi_startproc
+ pushl %edx
+ cfi_adjust_cfa_offset(4)
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%edx, -8)
+ cfi_offset(%ebx, -12)
+ cfi_offset(%esi, -16)
+
+ movl %edx, %ebx
+ xorl %esi, %esi /* No timeout. */
+ LOAD_FUTEX_WAIT (%ecx)
+
+4: movl %eax, %edx
+ orl $FUTEX_WAITERS, %edx
+
+ testl $FUTEX_OWNER_DIED, %eax
+ jnz 3f
+
+ cmpl %edx, %eax /* NB: %edx == 2 */
+ je 1f
+
+ LOCK
+ cmpxchgl %edx, (%ebx)
+ jnz 2f
+
+1: movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+ movl (%ebx), %eax
+
+2: test %eax, %eax
+ jne 4b
+
+ movl %gs:TID, %edx
+ orl $FUTEX_WAITERS, %edx
+ LOCK
+ cmpxchgl %edx, (%ebx)
+ jnz 4b
+ /* NB: %eax == 0 */
+
+3: popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ popl %edx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edx)
+ ret
+ cfi_endproc
+ .size __lll_robust_lock_wait,.-__lll_robust_lock_wait
+
+
+ .globl __lll_robust_timedlock_wait
+ .type __lll_robust_timedlock_wait,@function
+ .hidden __lll_robust_timedlock_wait
+ .align 16
+__lll_robust_timedlock_wait:
+ cfi_startproc
+ /* Check for a valid timeout value. */
+ cmpl $1000000000, 4(%edx)
+ jae 3f
+
+ pushl %edi
+ cfi_adjust_cfa_offset(4)
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ pushl %ebp
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%edi, -8)
+ cfi_offset(%esi, -12)
+ cfi_offset(%ebx, -16)
+ cfi_offset(%ebp, -20)
+
+ /* Stack frame for the timespec and timeval structs. */
+ subl $12, %esp
+ cfi_adjust_cfa_offset(12)
+
+ movl %ecx, %ebp
+ movl %edx, %edi
+
+1: movl %eax, 8(%esp)
+
+ /* Get current time. */
+ movl %esp, %ebx
+ xorl %ecx, %ecx
+ movl $__NR_gettimeofday, %eax
+ ENTER_KERNEL
+
+ /* Compute relative timeout. */
+ movl 4(%esp), %eax
+ movl $1000, %edx
+ mul %edx /* Milli seconds to nano seconds. */
+ movl (%edi), %ecx
+ movl 4(%edi), %edx
+ subl (%esp), %ecx
+ subl %eax, %edx
+ jns 4f
+ addl $1000000000, %edx
+ subl $1, %ecx
+4: testl %ecx, %ecx
+ js 8f /* Time is already up. */
+
+ /* Store relative timeout. */
+ movl %ecx, (%esp)
+ movl %edx, 4(%esp)
+
+ movl %ebp, %ebx
+
+ movl 8(%esp), %edx
+ movl %edx, %eax
+ orl $FUTEX_WAITERS, %edx
+
+ testl $FUTEX_OWNER_DIED, %eax
+ jnz 6f
+
+ cmpl %eax, %edx
+ je 2f
+
+ LOCK
+ cmpxchgl %edx, (%ebx)
+ movl $0, %ecx /* Must use mov to avoid changing cc. */
+ jnz 5f
+
+2:
+ /* Futex call. */
+ movl %esp, %esi
+ movl 20(%esp), %ecx
+ LOAD_FUTEX_WAIT (%ecx)
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+ movl %eax, %ecx
+
+ movl (%ebx), %eax
+
+5: testl %eax, %eax
+ jne 7f
+
+ movl %gs:TID, %edx
+ orl $FUTEX_WAITERS, %edx
+ LOCK
+ cmpxchgl %edx, (%ebx)
+ jnz 7f
+
+6: addl $12, %esp
+ cfi_adjust_cfa_offset(-12)
+ popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+ popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
+ ret
+
+3: movl $EINVAL, %eax
+ ret
+
+ cfi_adjust_cfa_offset(28)
+ cfi_offset(%edi, -8)
+ cfi_offset(%esi, -12)
+ cfi_offset(%ebx, -16)
+ cfi_offset(%ebp, -20)
+ /* Check whether the time expired. */
+7: cmpl $-ETIMEDOUT, %ecx
+ jne 1b
+
+8: movl $ETIMEDOUT, %eax
+ jmp 6b
+ cfi_endproc
+ .size __lll_robust_timedlock_wait,.-__lll_robust_timedlock_wait
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S
new file mode 100644
index 000000000..040d7f8c3
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S
@@ -0,0 +1,187 @@
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelbarrier.h>
+
+ .text
+
+ .globl pthread_barrier_wait
+ .type pthread_barrier_wait,@function
+ .align 16
+pthread_barrier_wait:
+ cfi_startproc
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
+
+ movl 8(%esp), %ebx
+
+ /* Get the mutex. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+ cmpxchgl %edx, MUTEX(%ebx)
+ jnz 1f
+
+ /* One less waiter. If this was the last one needed wake
+ everybody. */
+2: subl $1, LEFT(%ebx)
+ je 3f
+
+ /* There are more threads to come. */
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%esi, -12)
+
+#if CURR_EVENT == 0
+ movl (%ebx), %edx
+#else
+ movl CURR_EVENT(%ebx), %edx
+#endif
+
+ /* Release the mutex. */
+ LOCK
+ subl $1, MUTEX(%ebx)
+ jne 6f
+
+ /* Wait for the remaining threads. The call will return immediately
+ if the CURR_EVENT memory has meanwhile been changed. */
+7:
+#if FUTEX_WAIT == 0
+ movl PRIVATE(%ebx), %ecx
+#else
+ movl $FUTEX_WAIT, %ecx
+ orl PRIVATE(%ebx), %ecx
+#endif
+ xorl %esi, %esi
+8: movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+ /* Don't return on spurious wakeups. The syscall does not change
+ any register except %eax so there is no need to reload any of
+ them. */
+#if CURR_EVENT == 0
+ cmpl %edx, (%ebx)
+#else
+ cmpl %edx, CURR_EVENT(%ebx)
+#endif
+ je 8b
+
+ /* Increment LEFT. If this brings the count back to the
+ initial count unlock the object. */
+ movl $1, %edx
+ movl INIT_COUNT(%ebx), %ecx
+ LOCK
+ xaddl %edx, LEFT(%ebx)
+ subl $1, %ecx
+ cmpl %ecx, %edx
+ jne 10f
+
+ /* Release the mutex. We cannot release the lock before
+ waking the waiting threads since otherwise a new thread might
+ arrive and gets waken up, too. */
+ LOCK
+ subl $1, MUTEX(%ebx)
+ jne 9f
+
+ /* Note: %esi is still zero. */
+10: movl %esi, %eax /* != PTHREAD_BARRIER_SERIAL_THREAD */
+
+ popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ ret
+
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
+
+ /* The necessary number of threads arrived. */
+3:
+#if CURR_EVENT == 0
+ addl $1, (%ebx)
+#else
+ addl $1, CURR_EVENT(%ebx)
+#endif
+
+ /* Wake up all waiters. The count is a signed number in the kernel
+ so 0x7fffffff is the highest value. */
+ movl $0x7fffffff, %edx
+ movl $FUTEX_WAKE, %ecx
+ orl PRIVATE(%ebx), %ecx
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+ /* Increment LEFT. If this brings the count back to the
+ initial count unlock the object. */
+ movl $1, %edx
+ movl INIT_COUNT(%ebx), %ecx
+ LOCK
+ xaddl %edx, LEFT(%ebx)
+ subl $1, %ecx
+ cmpl %ecx, %edx
+ jne 5f
+
+ /* Release the mutex. We cannot release the lock before
+ waking the waiting threads since otherwise a new thread might
+ arrive and gets waken up, too. */
+ LOCK
+ subl $1, MUTEX(%ebx)
+ jne 4f
+
+5: orl $-1, %eax /* == PTHREAD_BARRIER_SERIAL_THREAD */
+
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ ret
+
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
+1: movl PRIVATE(%ebx), %ecx
+ leal MUTEX(%ebx), %edx
+ xorl $LLL_SHARED, %ecx
+ call __lll_lock_wait
+ jmp 2b
+
+4: movl PRIVATE(%ebx), %ecx
+ leal MUTEX(%ebx), %eax
+ xorl $LLL_SHARED, %ecx
+ call __lll_unlock_wake
+ jmp 5b
+
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%esi, -12)
+6: movl PRIVATE(%ebx), %ecx
+ leal MUTEX(%ebx), %eax
+ xorl $LLL_SHARED, %ecx
+ call __lll_unlock_wake
+ jmp 7b
+
+9: movl PRIVATE(%ebx), %ecx
+ leal MUTEX(%ebx), %eax
+ xorl $LLL_SHARED, %ecx
+ call __lll_unlock_wake
+ jmp 10b
+ cfi_endproc
+ .size pthread_barrier_wait,.-pthread_barrier_wait
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
new file mode 100644
index 000000000..ca9ceca00
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
@@ -0,0 +1,239 @@
+/* Copyright (C) 2002,2003,2004,2006,2007,2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelcond.h>
+#include <bits/kernel-features.h>
+#include <pthread-pi-defines.h>
+#include <pthread-errnos.h>
+#include <tls.h>
+
+ .text
+
+ /* int pthread_cond_broadcast (pthread_cond_t *cond) */
+ .globl __pthread_cond_broadcast
+ .type __pthread_cond_broadcast, @function
+ .protected __pthread_cond_broadcast
+ .align 16
+__pthread_cond_broadcast:
+ cfi_startproc
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%ebx, 0)
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%esi, 0)
+ pushl %edi
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%edi, 0)
+ pushl %ebp
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%ebp, 0)
+ cfi_remember_state
+
+ movl 20(%esp), %ebx
+
+ /* Get internal lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %edx, (%ebx)
+#else
+ cmpxchgl %edx, cond_lock(%ebx)
+#endif
+ jnz 1f
+
+2: addl $cond_futex, %ebx
+ movl total_seq+4-cond_futex(%ebx), %eax
+ movl total_seq-cond_futex(%ebx), %ebp
+ cmpl wakeup_seq+4-cond_futex(%ebx), %eax
+ ja 3f
+ jb 4f
+ cmpl wakeup_seq-cond_futex(%ebx), %ebp
+ jna 4f
+
+ /* Cause all currently waiting threads to recognize they are
+ woken up. */
+3: movl %ebp, wakeup_seq-cond_futex(%ebx)
+ movl %eax, wakeup_seq-cond_futex+4(%ebx)
+ movl %ebp, woken_seq-cond_futex(%ebx)
+ movl %eax, woken_seq-cond_futex+4(%ebx)
+ addl %ebp, %ebp
+ addl $1, broadcast_seq-cond_futex(%ebx)
+ movl %ebp, (%ebx)
+
+ /* Get the address of the mutex used. */
+ movl dep_mutex-cond_futex(%ebx), %edi
+
+ /* Unlock. */
+ LOCK
+ subl $1, cond_lock-cond_futex(%ebx)
+ jne 7f
+
+ /* Don't use requeue for pshared condvars. */
+8: cmpl $-1, %edi
+ je 9f
+
+ /* Do not use requeue for pshared condvars. */
+ testl $PS_BIT, MUTEX_KIND(%edi)
+ jne 9f
+
+ /* Requeue to a non-robust PI mutex if the PI bit is set and
+ the robust bit is not set. */
+ movl MUTEX_KIND(%edi), %eax
+ andl $(ROBUST_BIT|PI_BIT), %eax
+ cmpl $PI_BIT, %eax
+ je 81f
+
+ /* Wake up all threads. */
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), %ecx
+#else
+ movl %gs:PRIVATE_FUTEX, %ecx
+ orl $FUTEX_CMP_REQUEUE, %ecx
+#endif
+ movl $SYS_futex, %eax
+ movl $0x7fffffff, %esi
+ movl $1, %edx
+ /* Get the address of the futex involved. */
+# if MUTEX_FUTEX != 0
+ addl $MUTEX_FUTEX, %edi
+# endif
+/* FIXME: Until Ingo fixes 4G/4G vDSO, 6 arg syscalls are broken for sysenter.
+ ENTER_KERNEL */
+ int $0x80
+
+ /* For any kind of error, which mainly is EAGAIN, we try again
+ with WAKE. The general test also covers running on old
+ kernels. */
+ cmpl $0xfffff001, %eax
+ jae 9f
+
+6: xorl %eax, %eax
+ popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
+ popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
+ popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ ret
+
+ cfi_restore_state
+
+81: movl $(FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx
+ movl $SYS_futex, %eax
+ movl $0x7fffffff, %esi
+ movl $1, %edx
+ /* Get the address of the futex involved. */
+# if MUTEX_FUTEX != 0
+ addl $MUTEX_FUTEX, %edi
+# endif
+ int $0x80
+
+ /* For any kind of error, which mainly is EAGAIN, we try again
+ with WAKE. The general test also covers running on old
+ kernels. */
+ cmpl $0xfffff001, %eax
+ jb 6b
+ jmp 9f
+
+ /* Initial locking failed. */
+1:
+#if cond_lock == 0
+ movl %ebx, %edx
+#else
+ leal cond_lock(%ebx), %edx
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_lock_wait
+ jmp 2b
+
+ .align 16
+ /* Unlock. */
+4: LOCK
+ subl $1, cond_lock-cond_futex(%ebx)
+ je 6b
+
+ /* Unlock in loop requires wakeup. */
+5: leal cond_lock-cond_futex(%ebx), %eax
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_unlock_wake
+ jmp 6b
+
+ /* Unlock in loop requires wakeup. */
+7: leal cond_lock-cond_futex(%ebx), %eax
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_unlock_wake
+ jmp 8b
+
+9: /* The futex requeue functionality is not available. */
+ movl $0x7fffffff, %edx
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+ jmp 6b
+ cfi_endproc
+ .size __pthread_cond_broadcast, .-__pthread_cond_broadcast
+weak_alias(__pthread_cond_broadcast, pthread_cond_broadcast)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
new file mode 100644
index 000000000..118bc073b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
@@ -0,0 +1,216 @@
+/* Copyright (C) 2002,2003,2004,2005,2007,2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelcond.h>
+#include <bits/kernel-features.h>
+#include <pthread-pi-defines.h>
+#include <pthread-errnos.h>
+#include <tls.h>
+
+
+ .text
+
+ /* int pthread_cond_signal (pthread_cond_t *cond) */
+ .globl __pthread_cond_signal
+ .type __pthread_cond_signal, @function
+ .protected __pthread_cond_signal
+ .align 16
+__pthread_cond_signal:
+
+ cfi_startproc
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%ebx, 0)
+ pushl %edi
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%edi, 0)
+ cfi_remember_state
+
+ movl 12(%esp), %edi
+
+ /* Get internal lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %edx, (%edi)
+#else
+ cmpxchgl %edx, cond_lock(%edi)
+#endif
+ jnz 1f
+
+2: leal cond_futex(%edi), %ebx
+ movl total_seq+4(%edi), %eax
+ movl total_seq(%edi), %ecx
+ cmpl wakeup_seq+4(%edi), %eax
+#if cond_lock != 0
+ /* Must use leal to preserve the flags. */
+ leal cond_lock(%edi), %edi
+#endif
+ ja 3f
+ jb 4f
+ cmpl wakeup_seq-cond_futex(%ebx), %ecx
+ jbe 4f
+
+ /* Bump the wakeup number. */
+3: addl $1, wakeup_seq-cond_futex(%ebx)
+ adcl $0, wakeup_seq-cond_futex+4(%ebx)
+ addl $1, (%ebx)
+
+ /* Wake up one thread. */
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%esi, 0)
+ pushl %ebp
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%ebp, 0)
+
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ sete %cl
+ je 8f
+
+ movl dep_mutex-cond_futex(%ebx), %edx
+ /* Requeue to a non-robust PI mutex if the PI bit is set and
+ the robust bit is not set. */
+ movl MUTEX_KIND(%edx), %eax
+ andl $(ROBUST_BIT|PI_BIT), %eax
+ cmpl $PI_BIT, %eax
+ je 9f
+
+8: subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE_OP, %ecx
+ movl $SYS_futex, %eax
+ movl $1, %edx
+ movl $1, %esi
+ movl $FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, %ebp
+ /* FIXME: Until Ingo fixes 4G/4G vDSO, 6 arg syscalls are broken for
+ sysenter.
+ ENTER_KERNEL */
+ int $0x80
+ popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
+ popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+
+ /* For any kind of error, we try again with WAKE.
+ The general test also covers running on old kernels. */
+ cmpl $-4095, %eax
+ jae 7f
+
+6: xorl %eax, %eax
+ popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ ret
+
+ cfi_restore_state
+
+9: movl $(FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx
+ movl $SYS_futex, %eax
+ movl $1, %edx
+ xorl %esi, %esi
+ movl dep_mutex-cond_futex(%ebx), %edi
+ movl (%ebx), %ebp
+ /* FIXME: Until Ingo fixes 4G/4G vDSO, 6 arg syscalls are broken for
+ sysenter.
+ ENTER_KERNEL */
+ int $0x80
+ popl %ebp
+ popl %esi
+
+ leal -cond_futex(%ebx), %edi
+
+ /* For any kind of error, we try again with WAKE.
+ The general test also covers running on old kernels. */
+ cmpl $-4095, %eax
+ jb 4f
+
+7:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ orl $FUTEX_WAKE, %ecx
+
+ xorl $(FUTEX_WAKE ^ FUTEX_WAKE_OP), %ecx
+ movl $SYS_futex, %eax
+ /* %edx should be 1 already from $FUTEX_WAKE_OP syscall.
+ movl $1, %edx */
+ ENTER_KERNEL
+
+ /* Unlock. Note that at this point %edi always points to
+ cond_lock. */
+4: LOCK
+ subl $1, (%edi)
+ je 6b
+
+ /* Unlock in loop requires wakeup. */
+5: movl %edi, %eax
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_unlock_wake
+ jmp 6b
+
+ /* Initial locking failed. */
+1:
+#if cond_lock == 0
+ movl %edi, %edx
+#else
+ leal cond_lock(%edi), %edx
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%edi)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_lock_wait
+ jmp 2b
+
+ cfi_endproc
+ .size __pthread_cond_signal, .-__pthread_cond_signal
+weak_alias(__pthread_cond_signal, pthread_cond_signal)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
new file mode 100644
index 000000000..8a0c3fbf6
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
@@ -0,0 +1,694 @@
+/* Copyright (C) 2002-2004,2006-2007,2009,2010 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelcond.h>
+#include <pthread-errnos.h>
+#include <pthread-pi-defines.h>
+#include <bits/kernel-features.h>
+
+
+ .text
+
+/* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
+ const struct timespec *abstime) */
+ .globl __pthread_cond_timedwait
+ .type __pthread_cond_timedwait, @function
+ .protected __pthread_cond_timedwait
+ .align 16
+__pthread_cond_timedwait:
+.LSTARTCODE:
+ cfi_startproc
+#ifdef SHARED
+ cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect,
+ DW.ref.__gcc_personality_v0)
+ cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART)
+#else
+ cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0)
+ cfi_lsda(DW_EH_PE_udata4, .LexceptSTART)
+#endif
+
+ pushl %ebp
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%ebp, 0)
+ pushl %edi
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%edi, 0)
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%esi, 0)
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%ebx, 0)
+
+ movl 20(%esp), %ebx
+ movl 28(%esp), %ebp
+
+ cmpl $1000000000, 4(%ebp)
+ movl $EINVAL, %eax
+ jae 18f
+
+ /* Get internal lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %edx, (%ebx)
+#else
+ cmpxchgl %edx, cond_lock(%ebx)
+#endif
+ jnz 1f
+
+ /* Store the reference to the mutex. If there is already a
+ different value in there this is a bad user bug. */
+2: cmpl $-1, dep_mutex(%ebx)
+ movl 24(%esp), %eax
+ je 17f
+ movl %eax, dep_mutex(%ebx)
+
+ /* Unlock the mutex. */
+17: xorl %edx, %edx
+ call __pthread_mutex_unlock_usercnt
+
+ testl %eax, %eax
+ jne 16f
+
+ addl $1, total_seq(%ebx)
+ adcl $0, total_seq+4(%ebx)
+ addl $1, cond_futex(%ebx)
+ addl $(1 << nwaiters_shift), cond_nwaiters(%ebx)
+
+#define FRAME_SIZE 32
+ subl $FRAME_SIZE, %esp
+ cfi_adjust_cfa_offset(FRAME_SIZE)
+ cfi_remember_state
+
+ /* Get and store current wakeup_seq value. */
+ movl wakeup_seq(%ebx), %edi
+ movl wakeup_seq+4(%ebx), %edx
+ movl broadcast_seq(%ebx), %eax
+ movl %edi, 12(%esp)
+ movl %edx, 16(%esp)
+ movl %eax, 20(%esp)
+
+ /* Reset the pi-requeued flag. */
+8: movl $0, 24(%esp)
+ /* Get the current time. */
+ movl %ebx, %edx
+#ifdef __NR_clock_gettime
+ /* Get the clock number. */
+ movl cond_nwaiters(%ebx), %ebx
+ andl $((1 << nwaiters_shift) - 1), %ebx
+ /* Only clocks 0 and 1 are allowed so far. Both are handled in the
+ kernel. */
+ leal 4(%esp), %ecx
+ movl $__NR_clock_gettime, %eax
+ ENTER_KERNEL
+# ifndef __ASSUME_POSIX_TIMERS
+ cmpl $-ENOSYS, %eax
+ je 19f
+# endif
+ movl %edx, %ebx
+
+ /* Compute relative timeout. */
+ movl (%ebp), %ecx
+ movl 4(%ebp), %edx
+ subl 4(%esp), %ecx
+ subl 8(%esp), %edx
+#else
+ /* Get the current time. */
+ leal 4(%esp), %ebx
+ xorl %ecx, %ecx
+ movl $__NR_gettimeofday, %eax
+ ENTER_KERNEL
+ movl %edx, %ebx
+
+ /* Compute relative timeout. */
+ movl 8(%esp), %eax
+ movl $1000, %edx
+ mul %edx /* Milli seconds to nano seconds. */
+ movl (%ebp), %ecx
+ movl 4(%ebp), %edx
+ subl 4(%esp), %ecx
+ subl %eax, %edx
+#endif
+ jns 12f
+ addl $1000000000, %edx
+ subl $1, %ecx
+12: testl %ecx, %ecx
+ movl $-ETIMEDOUT, %esi
+ js 6f
+
+ /* Store relative timeout. */
+21: movl %ecx, 4(%esp)
+ movl %edx, 8(%esp)
+
+ movl cond_futex(%ebx), %edi
+ movl %edi, 28(%esp)
+
+ /* Unlock. */
+ LOCK
+#if cond_lock == 0
+ subl $1, (%ebx)
+#else
+ subl $1, cond_lock(%ebx)
+#endif
+ jne 3f
+
+.LcleanupSTART:
+4: call __pthread_enable_asynccancel
+ movl %eax, (%esp)
+
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ sete %cl
+ je 40f
+
+ movl dep_mutex(%ebx), %edi
+ /* Requeue to a non-robust PI mutex if the PI bit is set and
+ the robust bit is not set. */
+ movl MUTEX_KIND(%edi), %eax
+ andl $(ROBUST_BIT|PI_BIT), %eax
+ cmpl $PI_BIT, %eax
+ jne 40f
+
+ movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx
+ /* The following only works like this because we only support
+ two clocks, represented using a single bit. */
+ testl $1, cond_nwaiters(%ebx)
+ /* XXX Need to implement using sete instead of a jump. */
+ jne 42f
+ orl $FUTEX_CLOCK_REALTIME, %ecx
+
+ /* Requeue-PI uses absolute timeout */
+42: leal (%ebp), %esi
+ movl 28(%esp), %edx
+ addl $cond_futex, %ebx
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+ subl $cond_futex, %ebx
+ movl %eax, %esi
+ /* Set the pi-requeued flag only if the kernel has returned 0. The
+ kernel does not hold the mutex on ETIMEDOUT or any other error. */
+ cmpl $0, %eax
+ sete 24(%esp)
+ je 41f
+
+ /* Normal and PI futexes dont mix. Use normal futex functions only
+ if the kernel does not support the PI futex functions. */
+ cmpl $-ENOSYS, %eax
+ jne 41f
+ xorl %ecx, %ecx
+
+40: subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+#if FUTEX_WAIT != 0
+ addl $FUTEX_WAIT, %ecx
+#endif
+ leal 4(%esp), %esi
+ movl 28(%esp), %edx
+ addl $cond_futex, %ebx
+.Ladd_cond_futex:
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+ subl $cond_futex, %ebx
+.Lsub_cond_futex:
+ movl %eax, %esi
+
+41: movl (%esp), %eax
+ call __pthread_disable_asynccancel
+.LcleanupEND:
+
+ /* Lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %edx, (%ebx)
+#else
+ cmpxchgl %edx, cond_lock(%ebx)
+#endif
+ jnz 5f
+
+6: movl broadcast_seq(%ebx), %eax
+ cmpl 20(%esp), %eax
+ jne 23f
+
+ movl woken_seq(%ebx), %eax
+ movl woken_seq+4(%ebx), %ecx
+
+ movl wakeup_seq(%ebx), %edi
+ movl wakeup_seq+4(%ebx), %edx
+
+ cmpl 16(%esp), %edx
+ jne 7f
+ cmpl 12(%esp), %edi
+ je 15f
+
+7: cmpl %ecx, %edx
+ jne 9f
+ cmp %eax, %edi
+ jne 9f
+
+15: cmpl $-ETIMEDOUT, %esi
+ jne 8b
+
+ addl $1, wakeup_seq(%ebx)
+ adcl $0, wakeup_seq+4(%ebx)
+ addl $1, cond_futex(%ebx)
+ movl $ETIMEDOUT, %esi
+ jmp 14f
+
+23: xorl %esi, %esi
+ jmp 24f
+
+9: xorl %esi, %esi
+14: addl $1, woken_seq(%ebx)
+ adcl $0, woken_seq+4(%ebx)
+
+24: subl $(1 << nwaiters_shift), cond_nwaiters(%ebx)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ movl total_seq(%ebx), %eax
+ andl total_seq+4(%ebx), %eax
+ cmpl $0xffffffff, %eax
+ jne 25f
+ movl cond_nwaiters(%ebx), %eax
+ andl $~((1 << nwaiters_shift) - 1), %eax
+ jne 25f
+
+ addl $cond_nwaiters, %ebx
+ movl $SYS_futex, %eax
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_nwaiters(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
+ movl $1, %edx
+ ENTER_KERNEL
+ subl $cond_nwaiters, %ebx
+
+25: LOCK
+#if cond_lock == 0
+ subl $1, (%ebx)
+#else
+ subl $1, cond_lock(%ebx)
+#endif
+ jne 10f
+
+11: movl 24+FRAME_SIZE(%esp), %eax
+ /* With requeue_pi, the mutex lock is held in the kernel. */
+ movl 24(%esp), %ecx
+ testl %ecx, %ecx
+ jnz 27f
+
+ call __pthread_mutex_cond_lock
+26: addl $FRAME_SIZE, %esp
+ cfi_adjust_cfa_offset(-FRAME_SIZE);
+
+ /* We return the result of the mutex_lock operation if it failed. */
+ testl %eax, %eax
+#ifdef HAVE_CMOV
+ cmovel %esi, %eax
+#else
+ jne 22f
+ movl %esi, %eax
+22:
+#endif
+
+18: popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+ popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
+ popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
+
+ ret
+
+ cfi_restore_state
+
+27: call __pthread_mutex_cond_lock_adjust
+ xorl %eax, %eax
+ jmp 26b
+
+ cfi_adjust_cfa_offset(-FRAME_SIZE);
+ /* Initial locking failed. */
+1:
+#if cond_lock == 0
+ movl %ebx, %edx
+#else
+ leal cond_lock(%ebx), %edx
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_lock_wait
+ jmp 2b
+
+ /* The initial unlocking of the mutex failed. */
+16:
+ LOCK
+#if cond_lock == 0
+ subl $1, (%ebx)
+#else
+ subl $1, cond_lock(%ebx)
+#endif
+ jne 18b
+
+ movl %eax, %esi
+#if cond_lock == 0
+ movl %ebx, %eax
+#else
+ leal cond_lock(%ebx), %eax
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_unlock_wake
+
+ movl %esi, %eax
+ jmp 18b
+
+ cfi_adjust_cfa_offset(FRAME_SIZE)
+
+ /* Unlock in loop requires wakeup. */
+3:
+#if cond_lock == 0
+ movl %ebx, %eax
+#else
+ leal cond_lock(%ebx), %eax
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_unlock_wake
+ jmp 4b
+
+ /* Locking in loop failed. */
+5:
+#if cond_lock == 0
+ movl %ebx, %edx
+#else
+ leal cond_lock(%ebx), %edx
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_lock_wait
+ jmp 6b
+
+ /* Unlock after loop requires wakeup. */
+10:
+#if cond_lock == 0
+ movl %ebx, %eax
+#else
+ leal cond_lock(%ebx), %eax
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_unlock_wake
+ jmp 11b
+
+#if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS
+ /* clock_gettime not available. */
+19: leal 4(%esp), %ebx
+ xorl %ecx, %ecx
+ movl $__NR_gettimeofday, %eax
+ ENTER_KERNEL
+ movl %edx, %ebx
+
+ /* Compute relative timeout. */
+ movl 8(%esp), %eax
+ movl $1000, %edx
+ mul %edx /* Milli seconds to nano seconds. */
+ movl (%ebp), %ecx
+ movl 4(%ebp), %edx
+ subl 4(%esp), %ecx
+ subl %eax, %edx
+ jns 20f
+ addl $1000000000, %edx
+ subl $1, %ecx
+20: testl %ecx, %ecx
+ movl $-ETIMEDOUT, %esi
+ js 6b
+ jmp 21b
+#endif
+ .size __pthread_cond_timedwait, .-__pthread_cond_timedwait
+weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait)
+
+
+ .type __condvar_tw_cleanup2, @function
+__condvar_tw_cleanup2:
+ subl $cond_futex, %ebx
+ .size __condvar_tw_cleanup2, .-__condvar_tw_cleanup2
+ .type __condvar_tw_cleanup, @function
+__condvar_tw_cleanup:
+ movl %eax, %esi
+
+ /* Get internal lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %edx, (%ebx)
+#else
+ cmpxchgl %edx, cond_lock(%ebx)
+#endif
+ jz 1f
+
+#if cond_lock == 0
+ movl %ebx, %edx
+#else
+ leal cond_lock(%ebx), %edx
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_lock_wait
+
+1: movl broadcast_seq(%ebx), %eax
+ cmpl 20(%esp), %eax
+ jne 3f
+
+ /* We increment the wakeup_seq counter only if it is lower than
+ total_seq. If this is not the case the thread was woken and
+ then canceled. In this case we ignore the signal. */
+ movl total_seq(%ebx), %eax
+ movl total_seq+4(%ebx), %edi
+ cmpl wakeup_seq+4(%ebx), %edi
+ jb 6f
+ ja 7f
+ cmpl wakeup_seq(%ebx), %eax
+ jbe 7f
+
+6: addl $1, wakeup_seq(%ebx)
+ adcl $0, wakeup_seq+4(%ebx)
+ addl $1, cond_futex(%ebx)
+
+7: addl $1, woken_seq(%ebx)
+ adcl $0, woken_seq+4(%ebx)
+
+3: subl $(1 << nwaiters_shift), cond_nwaiters(%ebx)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ xorl %edi, %edi
+ movl total_seq(%ebx), %eax
+ andl total_seq+4(%ebx), %eax
+ cmpl $0xffffffff, %eax
+ jne 4f
+ movl cond_nwaiters(%ebx), %eax
+ andl $~((1 << nwaiters_shift) - 1), %eax
+ jne 4f
+
+ addl $cond_nwaiters, %ebx
+ movl $SYS_futex, %eax
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_nwaiters(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
+ movl $1, %edx
+ ENTER_KERNEL
+ subl $cond_nwaiters, %ebx
+ movl $1, %edi
+
+4: LOCK
+#if cond_lock == 0
+ subl $1, (%ebx)
+#else
+ subl $1, cond_lock(%ebx)
+#endif
+ je 2f
+
+#if cond_lock == 0
+ movl %ebx, %eax
+#else
+ leal cond_lock(%ebx), %eax
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_unlock_wake
+
+ /* Wake up all waiters to make sure no signal gets lost. */
+2: testl %edi, %edi
+ jnz 5f
+ addl $cond_futex, %ebx
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
+ movl $SYS_futex, %eax
+ movl $0x7fffffff, %edx
+ ENTER_KERNEL
+
+5: movl 24+FRAME_SIZE(%esp), %eax
+ call __pthread_mutex_cond_lock
+
+ movl %esi, (%esp)
+.LcallUR:
+ call _Unwind_Resume
+ hlt
+.LENDCODE:
+ cfi_endproc
+ .size __condvar_tw_cleanup, .-__condvar_tw_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte DW_EH_PE_omit # @LPStart format (omit)
+ .byte DW_EH_PE_omit # @TType format (omit)
+ .byte DW_EH_PE_sdata4 # call-site format
+ # DW_EH_PE_sdata4
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .long .LcleanupSTART-.LSTARTCODE
+ .long .Ladd_cond_futex-.LcleanupSTART
+ .long __condvar_tw_cleanup-.LSTARTCODE
+ .uleb128 0
+ .long .Ladd_cond_futex-.LSTARTCODE
+ .long .Lsub_cond_futex-.Ladd_cond_futex
+ .long __condvar_tw_cleanup2-.LSTARTCODE
+ .uleb128 0
+ .long .Lsub_cond_futex-.LSTARTCODE
+ .long .LcleanupEND-.Lsub_cond_futex
+ .long __condvar_tw_cleanup-.LSTARTCODE
+ .uleb128 0
+ .long .LcallUR-.LSTARTCODE
+ .long .LENDCODE-.LcallUR
+ .long 0
+ .uleb128 0
+.Lcstend:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
new file mode 100644
index 000000000..006fc510c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
@@ -0,0 +1,591 @@
+/* Copyright (C) 2002-2004,2006-2007,2009,2010 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelcond.h>
+#include <tcb-offsets.h>
+#include <pthread-errnos.h>
+#include <pthread-pi-defines.h>
+#include <bits/kernel-features.h>
+
+
+ .text
+
+/* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
+ .globl __pthread_cond_wait
+ .type __pthread_cond_wait, @function
+ .protected __pthread_cond_wait
+ .align 16
+__pthread_cond_wait:
+.LSTARTCODE:
+ cfi_startproc
+#ifdef SHARED
+ cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect,
+ DW.ref.__gcc_personality_v0)
+ cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART)
+#else
+ cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0)
+ cfi_lsda(DW_EH_PE_udata4, .LexceptSTART)
+#endif
+
+ pushl %ebp
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%ebp, 0)
+ pushl %edi
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%edi, 0)
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%esi, 0)
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset(%ebx, 0)
+
+ xorl %esi, %esi
+ movl 20(%esp), %ebx
+
+ /* Get internal lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %edx, (%ebx)
+#else
+ cmpxchgl %edx, cond_lock(%ebx)
+#endif
+ jnz 1f
+
+ /* Store the reference to the mutex. If there is already a
+ different value in there this is a bad user bug. */
+2: cmpl $-1, dep_mutex(%ebx)
+ movl 24(%esp), %eax
+ je 15f
+ movl %eax, dep_mutex(%ebx)
+
+ /* Unlock the mutex. */
+15: xorl %edx, %edx
+ call __pthread_mutex_unlock_usercnt
+
+ testl %eax, %eax
+ jne 12f
+
+ addl $1, total_seq(%ebx)
+ adcl $0, total_seq+4(%ebx)
+ addl $1, cond_futex(%ebx)
+ addl $(1 << nwaiters_shift), cond_nwaiters(%ebx)
+
+#define FRAME_SIZE 20
+ subl $FRAME_SIZE, %esp
+ cfi_adjust_cfa_offset(FRAME_SIZE)
+ cfi_remember_state
+
+ /* Get and store current wakeup_seq value. */
+ movl wakeup_seq(%ebx), %edi
+ movl wakeup_seq+4(%ebx), %edx
+ movl broadcast_seq(%ebx), %eax
+ movl %edi, 4(%esp)
+ movl %edx, 8(%esp)
+ movl %eax, 12(%esp)
+
+ /* Reset the pi-requeued flag. */
+8: movl $0, 16(%esp)
+ movl cond_futex(%ebx), %ebp
+
+ /* Unlock. */
+ LOCK
+#if cond_lock == 0
+ subl $1, (%ebx)
+#else
+ subl $1, cond_lock(%ebx)
+#endif
+ jne 3f
+
+.LcleanupSTART:
+4: call __pthread_enable_asynccancel
+ movl %eax, (%esp)
+
+ xorl %ecx, %ecx
+ cmpl $-1, dep_mutex(%ebx)
+ sete %cl
+ je 18f
+
+ movl dep_mutex(%ebx), %edi
+ /* Requeue to a non-robust PI mutex if the PI bit is set and
+ the robust bit is not set. */
+ movl MUTEX_KIND(%edi), %eax
+ andl $(ROBUST_BIT|PI_BIT), %eax
+ cmpl $PI_BIT, %eax
+ jne 18f
+
+ movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx
+ movl %ebp, %edx
+ xorl %esi, %esi
+ addl $cond_futex, %ebx
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+ subl $cond_futex, %ebx
+ /* Set the pi-requeued flag only if the kernel has returned 0. The
+ kernel does not hold the mutex on error. */
+ cmpl $0, %eax
+ sete 16(%esp)
+ je 19f
+
+ /* Normal and PI futexes dont mix. Use normal futex functions only
+ if the kernel does not support the PI futex functions. */
+ cmpl $-ENOSYS, %eax
+ jne 19f
+ xorl %ecx, %ecx
+
+18: subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+#if FUTEX_WAIT != 0
+ addl $FUTEX_WAIT, %ecx
+#endif
+ movl %ebp, %edx
+ addl $cond_futex, %ebx
+.Ladd_cond_futex:
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+ subl $cond_futex, %ebx
+.Lsub_cond_futex:
+
+19: movl (%esp), %eax
+ call __pthread_disable_asynccancel
+.LcleanupEND:
+
+ /* Lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %edx, (%ebx)
+#else
+ cmpxchgl %edx, cond_lock(%ebx)
+#endif
+ jnz 5f
+
+6: movl broadcast_seq(%ebx), %eax
+ cmpl 12(%esp), %eax
+ jne 16f
+
+ movl woken_seq(%ebx), %eax
+ movl woken_seq+4(%ebx), %ecx
+
+ movl wakeup_seq(%ebx), %edi
+ movl wakeup_seq+4(%ebx), %edx
+
+ cmpl 8(%esp), %edx
+ jne 7f
+ cmpl 4(%esp), %edi
+ je 8b
+
+7: cmpl %ecx, %edx
+ jne 9f
+ cmp %eax, %edi
+ je 8b
+
+9: addl $1, woken_seq(%ebx)
+ adcl $0, woken_seq+4(%ebx)
+
+ /* Unlock */
+16: subl $(1 << nwaiters_shift), cond_nwaiters(%ebx)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ movl total_seq(%ebx), %eax
+ andl total_seq+4(%ebx), %eax
+ cmpl $0xffffffff, %eax
+ jne 17f
+ movl cond_nwaiters(%ebx), %eax
+ andl $~((1 << nwaiters_shift) - 1), %eax
+ jne 17f
+
+ addl $cond_nwaiters, %ebx
+ movl $SYS_futex, %eax
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_nwaiters(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
+ movl $1, %edx
+ ENTER_KERNEL
+ subl $cond_nwaiters, %ebx
+
+17: LOCK
+#if cond_lock == 0
+ subl $1, (%ebx)
+#else
+ subl $1, cond_lock(%ebx)
+#endif
+ jne 10f
+
+ /* With requeue_pi, the mutex lock is held in the kernel. */
+11: movl 24+FRAME_SIZE(%esp), %eax
+ movl 16(%esp), %ecx
+ testl %ecx, %ecx
+ jnz 21f
+
+ call __pthread_mutex_cond_lock
+20: addl $FRAME_SIZE, %esp
+ cfi_adjust_cfa_offset(-FRAME_SIZE);
+
+14: popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+ popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
+ popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
+
+ /* We return the result of the mutex_lock operation. */
+ ret
+
+ cfi_restore_state
+
+21: call __pthread_mutex_cond_lock_adjust
+ xorl %eax, %eax
+ jmp 20b
+
+ cfi_adjust_cfa_offset(-FRAME_SIZE);
+ /* Initial locking failed. */
+1:
+#if cond_lock == 0
+ movl %ebx, %edx
+#else
+ leal cond_lock(%ebx), %edx
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_lock_wait
+ jmp 2b
+
+ /* The initial unlocking of the mutex failed. */
+12:
+ LOCK
+#if cond_lock == 0
+ subl $1, (%ebx)
+#else
+ subl $1, cond_lock(%ebx)
+#endif
+ jne 14b
+
+ movl %eax, %esi
+#if cond_lock == 0
+ movl %ebx, %eax
+#else
+ leal cond_lock(%ebx), %eax
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_unlock_wake
+
+ movl %esi, %eax
+ jmp 14b
+
+ cfi_adjust_cfa_offset(FRAME_SIZE)
+
+ /* Unlock in loop requires wakeup. */
+3:
+#if cond_lock == 0
+ movl %ebx, %eax
+#else
+ leal cond_lock(%ebx), %eax
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_unlock_wake
+ jmp 4b
+
+ /* Locking in loop failed. */
+5:
+#if cond_lock == 0
+ movl %ebx, %edx
+#else
+ leal cond_lock(%ebx), %edx
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_lock_wait
+ jmp 6b
+
+ /* Unlock after loop requires wakeup. */
+10:
+#if cond_lock == 0
+ movl %ebx, %eax
+#else
+ leal cond_lock(%ebx), %eax
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_unlock_wake
+ jmp 11b
+ .size __pthread_cond_wait, .-__pthread_cond_wait
+weak_alias(__pthread_cond_wait, pthread_cond_wait)
+
+
+ .type __condvar_w_cleanup2, @function
+__condvar_w_cleanup2:
+ subl $cond_futex, %ebx
+ .size __condvar_w_cleanup2, .-__condvar_w_cleanup2
+.LSbl4:
+ .type __condvar_w_cleanup, @function
+__condvar_w_cleanup:
+ movl %eax, %esi
+
+ /* Get internal lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %edx, (%ebx)
+#else
+ cmpxchgl %edx, cond_lock(%ebx)
+#endif
+ jz 1f
+
+#if cond_lock == 0
+ movl %ebx, %edx
+#else
+ leal cond_lock(%ebx), %edx
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_lock_wait
+
+1: movl broadcast_seq(%ebx), %eax
+ cmpl 12(%esp), %eax
+ jne 3f
+
+ /* We increment the wakeup_seq counter only if it is lower than
+ total_seq. If this is not the case the thread was woken and
+ then canceled. In this case we ignore the signal. */
+ movl total_seq(%ebx), %eax
+ movl total_seq+4(%ebx), %edi
+ cmpl wakeup_seq+4(%ebx), %edi
+ jb 6f
+ ja 7f
+ cmpl wakeup_seq(%ebx), %eax
+ jbe 7f
+
+6: addl $1, wakeup_seq(%ebx)
+ adcl $0, wakeup_seq+4(%ebx)
+ addl $1, cond_futex(%ebx)
+
+7: addl $1, woken_seq(%ebx)
+ adcl $0, woken_seq+4(%ebx)
+
+3: subl $(1 << nwaiters_shift), cond_nwaiters(%ebx)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ xorl %edi, %edi
+ movl total_seq(%ebx), %eax
+ andl total_seq+4(%ebx), %eax
+ cmpl $0xffffffff, %eax
+ jne 4f
+ movl cond_nwaiters(%ebx), %eax
+ andl $~((1 << nwaiters_shift) - 1), %eax
+ jne 4f
+
+ addl $cond_nwaiters, %ebx
+ movl $SYS_futex, %eax
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_nwaiters(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
+ movl $1, %edx
+ ENTER_KERNEL
+ subl $cond_nwaiters, %ebx
+ movl $1, %edi
+
+4: LOCK
+#if cond_lock == 0
+ subl $1, (%ebx)
+#else
+ subl $1, cond_lock(%ebx)
+#endif
+ je 2f
+
+#if cond_lock == 0
+ movl %ebx, %eax
+#else
+ leal cond_lock(%ebx), %eax
+#endif
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
+ call __lll_unlock_wake
+
+ /* Wake up all waiters to make sure no signal gets lost. */
+2: testl %edi, %edi
+ jnz 5f
+ addl $cond_futex, %ebx
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
+ movl $SYS_futex, %eax
+ movl $0x7fffffff, %edx
+ ENTER_KERNEL
+
+5: movl 24+FRAME_SIZE(%esp), %eax
+ call __pthread_mutex_cond_lock
+
+ movl %esi, (%esp)
+.LcallUR:
+ call _Unwind_Resume
+ hlt
+.LENDCODE:
+ cfi_endproc
+ .size __condvar_w_cleanup, .-__condvar_w_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte DW_EH_PE_omit # @LPStart format (omit)
+ .byte DW_EH_PE_omit # @TType format (omit)
+ .byte DW_EH_PE_sdata4 # call-site format
+ # DW_EH_PE_sdata4
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .long .LcleanupSTART-.LSTARTCODE
+ .long .Ladd_cond_futex-.LcleanupSTART
+ .long __condvar_w_cleanup-.LSTARTCODE
+ .uleb128 0
+ .long .Ladd_cond_futex-.LSTARTCODE
+ .long .Lsub_cond_futex-.Ladd_cond_futex
+ .long __condvar_w_cleanup2-.LSTARTCODE
+ .uleb128 0
+ .long .Lsub_cond_futex-.LSTARTCODE
+ .long .LcleanupEND-.Lsub_cond_futex
+ .long __condvar_w_cleanup-.LSTARTCODE
+ .uleb128 0
+ .long .LcallUR-.LSTARTCODE
+ .long .LENDCODE-.LcallUR
+ .long 0
+ .uleb128 0
+.Lcstend:
+
+#ifdef __PIC__
+ .section .gnu.linkonce.t.__i686.get_pc_thunk.cx,"ax",@progbits
+ .globl __i686.get_pc_thunk.cx
+ .hidden __i686.get_pc_thunk.cx
+ .type __i686.get_pc_thunk.cx,@function
+__i686.get_pc_thunk.cx:
+ movl (%esp), %ecx;
+ ret
+ .size __i686.get_pc_thunk.cx,.-__i686.get_pc_thunk.cx
+#endif
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
new file mode 100644
index 000000000..79501bd56
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
@@ -0,0 +1,195 @@
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <tls.h>
+
+
+ .text
+
+ .globl __pthread_rwlock_rdlock
+ .type __pthread_rwlock_rdlock,@function
+ .protected __pthread_rwlock_rdlock
+ .align 16
+__pthread_rwlock_rdlock:
+ cfi_startproc
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%esi, -8)
+ cfi_offset(%ebx, -12)
+
+ xorl %esi, %esi
+ movl 12(%esp), %ebx
+
+ /* Get the lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %edx, (%ebx)
+#else
+ cmpxchgl %edx, MUTEX(%ebx)
+#endif
+ jnz 1f
+
+2: movl WRITER(%ebx), %eax
+ testl %eax, %eax
+ jne 14f
+ cmpl $0, WRITERS_QUEUED(%ebx)
+ je 5f
+ cmpb $0, FLAGS(%ebx)
+ je 5f
+
+3: addl $1, READERS_QUEUED(%ebx)
+ je 4f
+
+ movl READERS_WAKEUP(%ebx), %edx
+
+ LOCK
+#if MUTEX == 0
+ subl $1, (%ebx)
+#else
+ subl $1, MUTEX(%ebx)
+#endif
+ jne 10f
+
+11:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movzbl PSHARED(%ebx), %ecx
+ xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
+#else
+ movzbl PSHARED(%ebx), %ecx
+# if FUTEX_WAIT != 0
+ orl $FUTEX_WAIT, %ecx
+# endif
+ xorl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $READERS_WAKEUP, %ebx
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+ subl $READERS_WAKEUP, %ebx
+
+ /* Reget the lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %edx, (%ebx)
+#else
+ cmpxchgl %edx, MUTEX(%ebx)
+#endif
+ jnz 12f
+
+13: subl $1, READERS_QUEUED(%ebx)
+ jmp 2b
+
+5: xorl %edx, %edx
+ addl $1, NR_READERS(%ebx)
+ je 8f
+9: LOCK
+#if MUTEX == 0
+ subl $1, (%ebx)
+#else
+ subl $1, MUTEX(%ebx)
+#endif
+ jne 6f
+7:
+
+ movl %edx, %eax
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+ ret
+
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%esi, -8)
+ cfi_offset(%ebx, -12)
+1:
+#if MUTEX == 0
+ movl %ebx, %edx
+#else
+ leal MUTEX(%ebx), %edx
+#endif
+ movzbl PSHARED(%ebx), %ecx
+ call __lll_lock_wait
+ jmp 2b
+
+14: cmpl %gs:TID, %eax
+ jne 3b
+ /* Deadlock detected. */
+ movl $EDEADLK, %edx
+ jmp 9b
+
+6:
+#if MUTEX == 0
+ movl %ebx, %eax
+#else
+ leal MUTEX(%ebx), %eax
+#endif
+ movzbl PSHARED(%ebx), %ecx
+ call __lll_unlock_wake
+ jmp 7b
+
+ /* Overflow. */
+8: subl $1, NR_READERS(%ebx)
+ movl $EAGAIN, %edx
+ jmp 9b
+
+ /* Overflow. */
+4: subl $1, READERS_QUEUED(%ebx)
+ movl $EAGAIN, %edx
+ jmp 9b
+
+10:
+#if MUTEX == 0
+ movl %ebx, %eax
+#else
+ leal MUTEX(%ebx), %eax
+#endif
+ movzbl PSHARED(%ebx), %ecx
+ call __lll_unlock_wake
+ jmp 11b
+
+12:
+#if MUTEX == 0
+ movl %ebx, %edx
+#else
+ leal MUTEX(%ebx), %edx
+#endif
+ movzbl PSHARED(%ebx), %ecx
+ call __lll_lock_wait
+ jmp 13b
+ cfi_endproc
+ .size __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
+
+ .globl pthread_rwlock_rdlock
+pthread_rwlock_rdlock = __pthread_rwlock_rdlock
+
+ .globl __pthread_rwlock_rdlock_internal
+__pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
new file mode 100644
index 000000000..be4530e13
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
@@ -0,0 +1,245 @@
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <tls.h>
+
+
+ .text
+
+ .globl pthread_rwlock_timedrdlock
+ .type pthread_rwlock_timedrdlock,@function
+ .align 16
+pthread_rwlock_timedrdlock:
+ cfi_startproc
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ pushl %edi
+ cfi_adjust_cfa_offset(4)
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ pushl %ebp
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%esi, -8)
+ cfi_offset(%edi, -12)
+ cfi_offset(%ebx, -16)
+ cfi_offset(%ebp, -20)
+ subl $8, %esp
+ cfi_adjust_cfa_offset(8)
+
+ movl 28(%esp), %ebp
+ movl 32(%esp), %edi
+
+ /* Get the lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %edx, (%ebp)
+#else
+ cmpxchgl %edx, MUTEX(%ebp)
+#endif
+ jnz 1f
+
+2: movl WRITER(%ebp), %eax
+ testl %eax, %eax
+ jne 14f
+ cmpl $0, WRITERS_QUEUED(%ebp)
+ je 5f
+ cmpb $0, FLAGS(%ebp)
+ je 5f
+
+ /* Check the value of the timeout parameter. */
+3: cmpl $1000000000, 4(%edi)
+ jae 19f
+
+ addl $1, READERS_QUEUED(%ebp)
+ je 4f
+
+ movl READERS_WAKEUP(%ebp), %esi
+
+ LOCK
+#if MUTEX == 0
+ subl $1, (%ebp)
+#else
+ subl $1, MUTEX(%ebp)
+#endif
+ jne 10f
+
+ /* Get current time. */
+11: movl %esp, %ebx
+ xorl %ecx, %ecx
+ movl $__NR_gettimeofday, %eax
+ ENTER_KERNEL
+
+ /* Compute relative timeout. */
+ movl 4(%esp), %eax
+ movl $1000, %edx
+ mul %edx /* Milli seconds to nano seconds. */
+ movl (%edi), %ecx
+ movl 4(%edi), %edx
+ subl (%esp), %ecx
+ subl %eax, %edx
+ jns 15f
+ addl $1000000000, %edx
+ subl $1, %ecx
+15: testl %ecx, %ecx
+ js 16f /* Time is already up. */
+
+ /* Futex call. */
+ movl %ecx, (%esp) /* Store relative timeout. */
+ movl %edx, 4(%esp)
+
+ movl %esi, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movzbl PSHARED(%ebp), %ecx
+ xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
+#else
+ movzbl PSHARED(%ebp), %ecx
+# if FUTEX_WAIT != 0
+ orl $FUTEX_WAIT, %ecx
+# endif
+ xorl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ movl %esp, %esi
+ leal READERS_WAKEUP(%ebp), %ebx
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+ movl %eax, %esi
+17:
+
+ /* Reget the lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %edx, (%ebp)
+#else
+ cmpxchgl %edx, MUTEX(%ebp)
+#endif
+ jnz 12f
+
+13: subl $1, READERS_QUEUED(%ebp)
+ cmpl $-ETIMEDOUT, %esi
+ jne 2b
+
+18: movl $ETIMEDOUT, %edx
+ jmp 9f
+
+
+5: xorl %edx, %edx
+ addl $1, NR_READERS(%ebp)
+ je 8f
+9: LOCK
+#if MUTEX == 0
+ subl $1, (%ebp)
+#else
+ subl $1, MUTEX(%ebp)
+#endif
+ jne 6f
+
+7: movl %edx, %eax
+
+ addl $8, %esp
+ cfi_adjust_cfa_offset(-8)
+ popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
+ popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+ ret
+
+ cfi_adjust_cfa_offset(24)
+ cfi_offset(%esi, -8)
+ cfi_offset(%edi, -12)
+ cfi_offset(%ebx, -16)
+ cfi_offset(%ebp, -20)
+1:
+#if MUTEX == 0
+ movl %ebp, %edx
+#else
+ leal MUTEX(%ebp), %edx
+#endif
+ movzbl PSHARED(%ebp), %ecx
+ call __lll_lock_wait
+ jmp 2b
+
+14: cmpl %gs:TID, %eax
+ jne 3b
+ movl $EDEADLK, %edx
+ jmp 9b
+
+6:
+#if MUTEX == 0
+ movl %ebp, %eax
+#else
+ leal MUTEX(%ebp), %eax
+#endif
+ movzbl PSHARED(%ebp), %ecx
+ call __lll_unlock_wake
+ jmp 7b
+
+ /* Overflow. */
+8: subl $1, NR_READERS(%ebp)
+ movl $EAGAIN, %edx
+ jmp 9b
+
+ /* Overflow. */
+4: subl $1, READERS_QUEUED(%ebp)
+ movl $EAGAIN, %edx
+ jmp 9b
+
+10:
+#if MUTEX == 0
+ movl %ebp, %eax
+#else
+ leal MUTEX(%ebp), %eax
+#endif
+ movzbl PSHARED(%ebp), %ecx
+ call __lll_unlock_wake
+ jmp 11b
+
+12:
+#if MUTEX == 0
+ movl %ebp, %edx
+#else
+ leal MUTEX(%ebp), %edx
+#endif
+ movzbl PSHARED(%ebp), %ecx
+ call __lll_lock_wait
+ jmp 13b
+
+16: movl $-ETIMEDOUT, %esi
+ jmp 17b
+
+19: movl $EINVAL, %edx
+ jmp 9b
+ cfi_endproc
+ .size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
new file mode 100644
index 000000000..61431ab71
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
@@ -0,0 +1,238 @@
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <tls.h>
+
+
+ .text
+
+ .globl pthread_rwlock_timedwrlock
+ .type pthread_rwlock_timedwrlock,@function
+ .align 16
+pthread_rwlock_timedwrlock:
+ cfi_startproc
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ pushl %edi
+ cfi_adjust_cfa_offset(4)
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ pushl %ebp
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%esi, -8)
+ cfi_offset(%edi, -12)
+ cfi_offset(%ebx, -16)
+ cfi_offset(%ebp, -20)
+ subl $8, %esp
+ cfi_adjust_cfa_offset(8)
+
+ movl 28(%esp), %ebp
+ movl 32(%esp), %edi
+
+ /* Get the lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %edx, (%ebp)
+#else
+ cmpxchgl %edx, MUTEX(%ebp)
+#endif
+ jnz 1f
+
+2: movl WRITER(%ebp), %eax
+ testl %eax, %eax
+ jne 14f
+ cmpl $0, NR_READERS(%ebp)
+ je 5f
+
+ /* Check the value of the timeout parameter. */
+3: cmpl $1000000000, 4(%edi)
+ jae 19f
+
+ addl $1, WRITERS_QUEUED(%ebp)
+ je 4f
+
+ movl WRITERS_WAKEUP(%ebp), %esi
+
+ LOCK
+#if MUTEX == 0
+ subl $1, (%ebp)
+#else
+ subl $1, MUTEX(%ebp)
+#endif
+ jne 10f
+
+ /* Get current time. */
+11: movl %esp, %ebx
+ xorl %ecx, %ecx
+ movl $__NR_gettimeofday, %eax
+ ENTER_KERNEL
+
+ /* Compute relative timeout. */
+ movl 4(%esp), %eax
+ movl $1000, %edx
+ mul %edx /* Milli seconds to nano seconds. */
+ movl (%edi), %ecx
+ movl 4(%edi), %edx
+ subl (%esp), %ecx
+ subl %eax, %edx
+ jns 15f
+ addl $1000000000, %edx
+ subl $1, %ecx
+15: testl %ecx, %ecx
+ js 16f /* Time is already up. */
+
+ /* Futex call. */
+ movl %ecx, (%esp) /* Store relative timeout. */
+ movl %edx, 4(%esp)
+
+ movl %esi, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movzbl PSHARED(%ebp), %ecx
+ xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
+#else
+ movzbl PSHARED(%ebp), %ecx
+# if FUTEX_WAIT != 0
+ orl $FUTEX_WAIT, %ecx
+# endif
+ xorl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ movl %esp, %esi
+ leal WRITERS_WAKEUP(%ebp), %ebx
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+ movl %eax, %esi
+17:
+
+ /* Reget the lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %edx, (%ebp)
+#else
+ cmpxchgl %edx, MUTEX(%ebp)
+#endif
+ jnz 12f
+
+13: subl $1, WRITERS_QUEUED(%ebp)
+ cmpl $-ETIMEDOUT, %esi
+ jne 2b
+
+18: movl $ETIMEDOUT, %edx
+ jmp 9f
+
+
+5: xorl %edx, %edx
+ movl %gs:TID, %eax
+ movl %eax, WRITER(%ebp)
+9: LOCK
+#if MUTEX == 0
+ subl $1, (%ebp)
+#else
+ subl $1, MUTEX(%ebp)
+#endif
+ jne 6f
+
+7: movl %edx, %eax
+
+ addl $8, %esp
+ cfi_adjust_cfa_offset(-8)
+ popl %ebp
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebp)
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
+ popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+ ret
+
+ cfi_adjust_cfa_offset(24)
+ cfi_offset(%esi, -8)
+ cfi_offset(%edi, -12)
+ cfi_offset(%ebx, -16)
+ cfi_offset(%ebp, -20)
+1:
+#if MUTEX == 0
+ movl %ebp, %edx
+#else
+ leal MUTEX(%ebp), %edx
+#endif
+ movzbl PSHARED(%ebp), %ecx
+ call __lll_lock_wait
+ jmp 2b
+
+14: cmpl %gs:TID, %eax
+ jne 3b
+20: movl $EDEADLK, %edx
+ jmp 9b
+
+6:
+#if MUTEX == 0
+ movl %ebp, %eax
+#else
+ leal MUTEX(%ebp), %eax
+#endif
+ movzbl PSHARED(%ebp), %ecx
+ call __lll_unlock_wake
+ jmp 7b
+
+ /* Overflow. */
+4: subl $1, WRITERS_QUEUED(%ebp)
+ movl $EAGAIN, %edx
+ jmp 9b
+
+10:
+#if MUTEX == 0
+ movl %ebp, %eax
+#else
+ leal MUTEX(%ebp), %eax
+#endif
+ movzbl PSHARED(%ebp), %ecx
+ call __lll_unlock_wake
+ jmp 11b
+
+12:
+#if MUTEX == 0
+ movl %ebp, %edx
+#else
+ leal MUTEX(%ebp), %edx
+#endif
+ movzbl PSHARED(%ebp), %ecx
+ call __lll_lock_wait
+ jmp 13b
+
+16: movl $-ETIMEDOUT, %esi
+ jmp 17b
+
+19: movl $EINVAL, %edx
+ jmp 9b
+ cfi_endproc
+ .size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
new file mode 100644
index 000000000..cfab60c67
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
@@ -0,0 +1,157 @@
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <bits/kernel-features.h>
+#include <tls.h>
+
+
+ .text
+
+ .globl __pthread_rwlock_unlock
+ .type __pthread_rwlock_unlock,@function
+ .protected __pthread_rwlock_unlock
+ .align 16
+__pthread_rwlock_unlock:
+ cfi_startproc
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ pushl %edi
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
+ cfi_offset(%edi, -12)
+
+ movl 12(%esp), %edi
+
+ /* Get the lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %edx, (%edi)
+#else
+ cmpxchgl %edx, MUTEX(%edi)
+#endif
+ jnz 1f
+
+2: cmpl $0, WRITER(%edi)
+ jne 5f
+ subl $1, NR_READERS(%edi)
+ jnz 6f
+
+5: movl $0, WRITER(%edi)
+
+ movl $1, %edx
+ leal WRITERS_WAKEUP(%edi), %ebx
+ cmpl $0, WRITERS_QUEUED(%edi)
+ jne 0f
+
+ /* If also no readers waiting nothing to do. */
+ cmpl $0, READERS_QUEUED(%edi)
+ je 6f
+
+ movl $0x7fffffff, %edx
+ leal READERS_WAKEUP(%edi), %ebx
+
+0: addl $1, (%ebx)
+ LOCK
+#if MUTEX == 0
+ subl $1, (%edi)
+#else
+ subl $1, MUTEX(%edi)
+#endif
+ jne 7f
+
+8:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movzbl PSHARED(%edi), %ecx
+ xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %ecx
+#else
+ movzbl PSHARED(%edi), %ecx
+ orl $FUTEX_WAKE, %ecx
+ xorl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+ xorl %eax, %eax
+ popl %edi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%edi)
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ ret
+
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%ebx, -8)
+ cfi_offset(%edi, -12)
+ .align 16
+6: LOCK
+#if MUTEX == 0
+ subl $1, (%edi)
+#else
+ subl $1, MUTEX(%edi)
+#endif
+ jne 3f
+
+4: xorl %eax, %eax
+ popl %edi
+ popl %ebx
+ ret
+
+1:
+#if MUTEX == 0
+ movl %edi, %edx
+#else
+ leal MUTEX(%edi), %edx
+#endif
+ movzbl PSHARED(%edi), %ecx
+ call __lll_lock_wait
+ jmp 2b
+
+3:
+#if MUTEX == 0
+ movl %edi, %eax
+#else
+ leal MUTEX(%edi), %eax
+#endif
+ movzbl PSHARED(%edi), %ecx
+ call __lll_unlock_wake
+ jmp 4b
+
+7:
+#if MUTEX == 0
+ movl %edi, %eax
+#else
+ leal MUTEX(%edi), %eax
+#endif
+ movzbl PSHARED(%edi), %ecx
+ call __lll_unlock_wake
+ jmp 8b
+ cfi_endproc
+ .size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
+
+ .globl pthread_rwlock_unlock
+pthread_rwlock_unlock = __pthread_rwlock_unlock
+
+ .globl __pthread_rwlock_unlock_internal
+__pthread_rwlock_unlock_internal = __pthread_rwlock_unlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
new file mode 100644
index 000000000..5c96d900b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
@@ -0,0 +1,186 @@
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <tls.h>
+
+
+ .text
+
+ .globl __pthread_rwlock_wrlock
+ .type __pthread_rwlock_wrlock,@function
+ .protected __pthread_rwlock_wrlock
+ .align 16
+__pthread_rwlock_wrlock:
+ cfi_startproc
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%esi, -8)
+ cfi_offset(%ebx, -12)
+
+ xorl %esi, %esi
+ movl 12(%esp), %ebx
+
+ /* Get the lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %edx, (%ebx)
+#else
+ cmpxchgl %edx, MUTEX(%ebx)
+#endif
+ jnz 1f
+
+2: movl WRITER(%ebx), %eax
+ testl %eax, %eax
+ jne 14f
+ cmpl $0, NR_READERS(%ebx)
+ je 5f
+
+3: addl $1, WRITERS_QUEUED(%ebx)
+ je 4f
+
+ movl WRITERS_WAKEUP(%ebx), %edx
+
+ LOCK
+#if MUTEX == 0
+ subl $1, (%ebx)
+#else
+ subl $1, MUTEX(%ebx)
+#endif
+ jne 10f
+
+11:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movzbl PSHARED(%ebx), %ecx
+ xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
+#else
+ movzbl PSHARED(%ebx), %ecx
+# if FUTEX_WAIT != 0
+ orl $FUTEX_WAIT, %ecx
+# endif
+ xorl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $WRITERS_WAKEUP, %ebx
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+ subl $WRITERS_WAKEUP, %ebx
+
+ /* Reget the lock. */
+ movl $1, %edx
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %edx, (%ebx)
+#else
+ cmpxchgl %edx, MUTEX(%ebx)
+#endif
+ jnz 12f
+
+13: subl $1, WRITERS_QUEUED(%ebx)
+ jmp 2b
+
+5: xorl %edx, %edx
+ movl %gs:TID, %eax
+ movl %eax, WRITER(%ebx)
+9: LOCK
+#if MUTEX == 0
+ subl $1, (%ebx)
+#else
+ subl $1, MUTEX(%ebx)
+#endif
+ jne 6f
+7:
+
+ movl %edx, %eax
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ popl %esi
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%esi)
+ ret
+
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%esi, -8)
+ cfi_offset(%ebx, -12)
+1:
+#if MUTEX == 0
+ movl %ebx, %edx
+#else
+ leal MUTEX(%ebx), %edx
+#endif
+ movzbl PSHARED(%ebx), %ecx
+ call __lll_lock_wait
+ jmp 2b
+
+14: cmpl %gs:TID , %eax
+ jne 3b
+ movl $EDEADLK, %edx
+ jmp 9b
+
+6:
+#if MUTEX == 0
+ movl %ebx, %eax
+#else
+ leal MUTEX(%ebx), %eax
+#endif
+ movzbl PSHARED(%ebx), %ecx
+ call __lll_unlock_wake
+ jmp 7b
+
+4: subl $1, WRITERS_QUEUED(%ebx)
+ movl $EAGAIN, %edx
+ jmp 9b
+
+10:
+#if MUTEX == 0
+ movl %ebx, %eax
+#else
+ leal MUTEX(%ebx), %eax
+#endif
+ movzbl PSHARED(%ebx), %ecx
+ call __lll_unlock_wake
+ jmp 11b
+
+12:
+#if MUTEX == 0
+ movl %ebx, %edx
+#else
+ leal MUTEX(%ebx), %edx
+#endif
+ movzbl PSHARED(%ebx), %ecx
+ call __lll_lock_wait
+ jmp 13b
+ cfi_endproc
+ .size __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock
+
+ .globl pthread_rwlock_wrlock
+pthread_rwlock_wrlock = __pthread_rwlock_wrlock
+
+ .globl __pthread_rwlock_wrlock_internal
+__pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
new file mode 100644
index 000000000..b077a20ca
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
@@ -0,0 +1,142 @@
+/* Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <structsem.h>
+#include <lowlevellock.h>
+
+
+ .text
+
+ .globl __new_sem_post
+ .type __new_sem_post,@function
+ .align 16
+__new_sem_post:
+ cfi_startproc
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
+
+ movl 8(%esp), %ebx
+
+#if VALUE == 0
+ movl (%ebx), %eax
+#else
+ movl VALUE(%ebx), %eax
+#endif
+0: cmpl $SEM_VALUE_MAX, %eax
+ je 3f
+ leal 1(%eax), %edx
+ LOCK
+#if VALUE == 0
+ cmpxchgl %edx, (%ebx)
+#else
+ cmpxchgl %edx, VALUE(%ebx)
+#endif
+ jnz 0b
+
+ cmpl $0, NWAITERS(%ebx)
+ je 2f
+
+ movl $FUTEX_WAKE, %ecx
+ orl PRIVATE(%ebx), %ecx
+ movl $1, %edx
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+ testl %eax, %eax
+ js 1f
+
+2: xorl %eax, %eax
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ ret
+
+ cfi_adjust_cfa_offset(4)
+ cfi_offset(%ebx, -8)
+1:
+#ifdef __PIC__
+ call __x86.get_pc_thunk.bx
+#else
+ movl $4f, %ebx
+4:
+#endif
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+#if USE___THREAD
+# ifdef NO_TLS_DIRECT_SEG_REFS
+ movl errno@gotntpoff(%ebx), %edx
+ addl %gs:0, %edx
+ movl $EINVAL, (%edx)
+# else
+ movl errno@gotntpoff(%ebx), %edx
+ movl $EINVAL, %gs:(%edx)
+# endif
+#else
+ call __errno_location@plt
+ movl $EINVAL, (%eax)
+#endif
+
+ orl $-1, %eax
+ popl %ebx
+ ret
+
+3:
+#ifdef __PIC__
+ call __x86.get_pc_thunk.bx
+#else
+ movl $5f, %ebx
+5:
+#endif
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+#if USE___THREAD
+# ifdef NO_TLS_DIRECT_SEG_REFS
+ movl errno@gotntpoff(%ebx), %edx
+ addl %gs:0, %edx
+ movl $EOVERFLOW, (%edx)
+# else
+ movl errno@gotntpoff(%ebx), %edx
+ movl $EOVERFLOW, %gs:(%edx)
+# endif
+#else
+ call __errno_location@plt
+ movl $EOVERFLOW, (%eax)
+#endif
+
+ orl $-1, %eax
+ popl %ebx
+ cfi_adjust_cfa_offset(-4)
+ cfi_restore(%ebx)
+ ret
+ cfi_endproc
+ .size __new_sem_post,.-__new_sem_post
+weak_alias(__new_sem_post, sem_post)
+
+
+#ifdef __PIC__
+ .section .gnu.linkonce.t.__x86.get_pc_thunk.bx,"ax",@progbits
+ .globl __x86.get_pc_thunk.bx
+ .hidden __x86.get_pc_thunk.bx
+ .type __x86.get_pc_thunk.bx,@function
+__x86.get_pc_thunk.bx:
+ movl (%esp), %ebx;
+ ret
+ .size __x86.get_pc_thunk.bx,.-__x86.get_pc_thunk.bx
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
new file mode 100644
index 000000000..a1e3225cb
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
@@ -0,0 +1,329 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <structsem.h>
+#include <lowlevellock.h>
+
+
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
+
+
+ .text
+
+ .globl sem_timedwait
+ .type sem_timedwait,@function
+ .align 16
+sem_timedwait:
+.LSTARTCODE:
+ movl 4(%esp), %ecx
+
+ movl (%ecx), %eax
+2: testl %eax, %eax
+ je 1f
+
+ leal -1(%eax), %edx
+ LOCK
+ cmpxchgl %edx, (%ecx)
+ jne 2b
+
+ xorl %eax, %eax
+ ret
+
+ /* Check whether the timeout value is valid. */
+1: pushl %esi
+.Lpush_esi:
+ pushl %edi
+.Lpush_edi:
+ pushl %ebx
+.Lpush_ebx:
+ subl $12, %esp
+.Lsub_esp:
+
+ movl 32(%esp), %edi
+
+ /* Check for invalid nanosecond field. */
+ cmpl $1000000000, 4(%edi)
+ movl $EINVAL, %esi
+ jae 6f
+
+ LOCK
+ incl NWAITERS(%ecx)
+
+7: xorl %ecx, %ecx
+ movl %esp, %ebx
+ movl %ecx, %edx
+ movl $__NR_gettimeofday, %eax
+ ENTER_KERNEL
+
+ /* Compute relative timeout. */
+ movl 4(%esp), %eax
+ movl $1000, %edx
+ mul %edx /* Milli seconds to nano seconds. */
+ movl (%edi), %ecx
+ movl 4(%edi), %edx
+ subl (%esp), %ecx
+ subl %eax, %edx
+ jns 5f
+ addl $1000000000, %edx
+ subl $1, %ecx
+5: testl %ecx, %ecx
+ movl $ETIMEDOUT, %esi
+ js 6f /* Time is already up. */
+
+ movl %ecx, (%esp) /* Store relative timeout. */
+ movl %edx, 4(%esp)
+
+.LcleanupSTART:
+ call __pthread_enable_asynccancel
+ movl %eax, 8(%esp)
+
+ movl 28(%esp), %ebx /* Load semaphore address. */
+#if FUTEX_WAIT == 0
+ movl PRIVATE(%ebx), %ecx
+#else
+ movl $FUTEX_WAIT, %ecx
+ orl PRIVATE(%ebx), %ecx
+#endif
+ movl %esp, %esi
+ xorl %edx, %edx
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+ movl %eax, %esi
+
+ movl 8(%esp), %eax
+ call __pthread_disable_asynccancel
+.LcleanupEND:
+
+ testl %esi, %esi
+ je 9f
+ cmpl $-EWOULDBLOCK, %esi
+ jne 3f
+
+9: movl (%ebx), %eax
+8: testl %eax, %eax
+ je 7b
+
+ leal -1(%eax), %ecx
+ LOCK
+ cmpxchgl %ecx, (%ebx)
+ jne 8b
+
+ xorl %eax, %eax
+
+ LOCK
+ decl NWAITERS(%ebx)
+
+10: addl $12, %esp
+.Ladd_esp:
+ popl %ebx
+.Lpop_ebx:
+ popl %edi
+.Lpop_edi:
+ popl %esi
+.Lpop_esi:
+ ret
+
+.Lafter_ret:
+3: negl %esi
+6:
+#ifdef __PIC__
+ call __x86.get_pc_thunk.bx
+#else
+ movl $4f, %ebx
+4:
+#endif
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+#if USE___THREAD
+# ifdef NO_TLS_DIRECT_SEG_REFS
+ movl errno@gotntpoff(%ebx), %edx
+ addl %gs:0, %edx
+ movl %esi, (%edx)
+# else
+ movl errno@gotntpoff(%ebx), %edx
+ movl %esi, %gs:(%edx)
+# endif
+#else
+ call __errno_location@plt
+ movl %esi, (%eax)
+#endif
+
+ movl 28(%esp), %ebx /* Load semaphore address. */
+ orl $-1, %eax
+ jmp 10b
+ .size sem_timedwait,.-sem_timedwait
+
+
+ .type sem_wait_cleanup,@function
+sem_wait_cleanup:
+ LOCK
+ decl NWAITERS(%ebx)
+ movl %eax, (%esp)
+.LcallUR:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE:
+ .size sem_wait_cleanup,.-sem_wait_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff # @LPStart format (omit)
+ .byte 0xff # @TType format (omit)
+ .byte 0x01 # call-site format
+ # DW_EH_PE_uleb128
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 sem_wait_cleanup-.LSTARTCODE
+ .uleb128 0
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+ .long .LENDCIE-.LSTARTCIE # Length of the CIE.
+.LSTARTCIE:
+ .long 0 # CIE ID.
+ .byte 1 # Version number.
+#ifdef SHARED
+ .string "zPLR" # NUL-terminated augmentation
+ # string.
+#else
+ .string "zPL" # NUL-terminated augmentation
+ # string.
+#endif
+ .uleb128 1 # Code alignment factor.
+ .sleb128 -4 # Data alignment factor.
+ .byte 8 # Return address register
+ # column.
+#ifdef SHARED
+ .uleb128 7 # Augmentation value length.
+ .byte 0x9b # Personality: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4
+ # + DW_EH_PE_indirect
+ .long DW.ref.__gcc_personality_v0-.
+ .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+ .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+#else
+ .uleb128 6 # Augmentation value length.
+ .byte 0x0 # Personality: absolute
+ .long __gcc_personality_v0
+ .byte 0x0 # LSDA Encoding: absolute
+#endif
+ .byte 0x0c # DW_CFA_def_cfa
+ .uleb128 4
+ .uleb128 4
+ .byte 0x88 # DW_CFA_offset, column 0x10
+ .uleb128 1
+ .align 4
+.LENDCIE:
+
+ .long .LENDFDE-.LSTARTFDE # Length of the FDE.
+.LSTARTFDE:
+ .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
+#ifdef SHARED
+ .long .LSTARTCODE-. # PC-relative start address
+ # of the code.
+#else
+ .long .LSTARTCODE # Start address of the code.
+#endif
+ .long .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 4 # Augmentation size
+#ifdef SHARED
+ .long .LexceptSTART-.
+#else
+ .long .LexceptSTART
+#endif
+
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_esi-.LSTARTCODE
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0x86 # DW_CFA_offset %esi
+ .uleb128 2
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_edi-.Lpush_esi
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 12
+ .byte 0x87 # DW_CFA_offset %edi
+ .uleb128 3
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_ebx-.Lpush_edi
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0x83 # DW_CFA_offset %ebx
+ .uleb128 4
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lsub_esp-.Lpush_ebx
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 28
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Ladd_esp-.Lsub_esp
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_ebx-.Ladd_esp
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 12
+ .byte 0xc3 # DW_CFA_restore %ebx
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_edi-.Lpop_ebx
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0xc7 # DW_CFA_restore %edi
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_esi-.Lpop_edi
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 4
+ .byte 0xc6 # DW_CFA_restore %esi
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lafter_ret-.Lpop_esi
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 28
+ .byte 0x86 # DW_CFA_offset %esi
+ .uleb128 2
+ .byte 0x87 # DW_CFA_offset %edi
+ .uleb128 3
+ .byte 0x83 # DW_CFA_offset %ebx
+ .uleb128 4
+ .align 4
+.LENDFDE:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S
new file mode 100644
index 000000000..dad96858f
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S
@@ -0,0 +1,79 @@
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <lowlevellock.h>
+
+ .text
+
+ .globl __new_sem_trywait
+ .type __new_sem_trywait,@function
+ .align 16
+__new_sem_trywait:
+ movl 4(%esp), %ecx
+
+ movl (%ecx), %eax
+2: testl %eax, %eax
+ jz 1f
+
+ leal -1(%eax), %edx
+ LOCK
+ cmpxchgl %edx, (%ecx)
+ jne 2b
+ xorl %eax, %eax
+ ret
+
+1:
+#ifdef __PIC__
+ call __x86.get_pc_thunk.cx
+#else
+ movl $3f, %ecx
+3:
+#endif
+ addl $_GLOBAL_OFFSET_TABLE_, %ecx
+#if USE___THREAD
+# ifdef NO_TLS_DIRECT_SEG_REFS
+ movl errno@gotntpoff(%ecx), %edx
+ addl %gs:0, %edx
+ movl $EAGAIN, (%edx)
+# else
+ movl errno@gotntpoff(%ecx), %edx
+ movl $EAGAIN, %gs:(%edx)
+# endif
+#else
+ call __errno_location@plt
+ movl $EAGAIN, (%eax)
+#endif
+ orl $-1, %eax
+ ret
+ .size __new_sem_trywait,.-__new_sem_trywait
+weak_alias(__new_sem_trywait, sem_trywait)
+
+
+#ifdef __PIC__
+ .section .gnu.linkonce.t.__x86.get_pc_thunk.cx,"ax",@progbits
+ .globl __x86.get_pc_thunk.cx
+ .hidden __x86.get_pc_thunk.cx
+ .type __x86.get_pc_thunk.cx,@function
+__x86.get_pc_thunk.cx:
+ movl (%esp), %ecx;
+ ret
+ .size __x86.get_pc_thunk.cx,.-__x86.get_pc_thunk.cx
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
new file mode 100644
index 000000000..b1c32ee4d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
@@ -0,0 +1,269 @@
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <structsem.h>
+#include <lowlevellock.h>
+
+
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
+
+ .text
+
+ .globl __new_sem_wait
+ .type __new_sem_wait,@function
+ .align 16
+__new_sem_wait:
+.LSTARTCODE:
+ pushl %ebx
+.Lpush_ebx:
+ pushl %esi
+.Lpush_esi:
+ subl $4, %esp
+.Lsub_esp:
+
+ movl 16(%esp), %ebx
+
+ movl (%ebx), %eax
+2: testl %eax, %eax
+ je 1f
+
+ leal -1(%eax), %edx
+ LOCK
+ cmpxchgl %edx, (%ebx)
+ jne 2b
+7: xorl %eax, %eax
+
+9: movl 4(%esp), %esi
+ movl 8(%esp), %ebx
+ addl $12, %esp
+.Ladd_esp:
+ ret
+
+.Lafter_ret:
+1: LOCK
+ incl NWAITERS(%ebx)
+
+.LcleanupSTART:
+6: call __pthread_enable_asynccancel
+ movl %eax, (%esp)
+
+#if FUTEX_WAIT == 0
+ movl PRIVATE(%ebx), %ecx
+#else
+ movl $FUTEX_WAIT, %ecx
+ orl PRIVATE(%ebx), %ecx
+#endif
+ xorl %esi, %esi
+ xorl %edx, %edx
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+ movl %eax, %esi
+
+ movl (%esp), %eax
+ call __pthread_disable_asynccancel
+.LcleanupEND:
+
+ testl %esi, %esi
+ je 3f
+ cmpl $-EWOULDBLOCK, %esi
+ jne 4f
+
+3:
+ movl (%ebx), %eax
+5: testl %eax, %eax
+ je 6b
+
+ leal -1(%eax), %edx
+ LOCK
+ cmpxchgl %edx, (%ebx)
+ jne 5b
+
+ LOCK
+ decl NWAITERS(%ebx)
+ jmp 7b
+
+4: LOCK
+ decl NWAITERS(%ebx)
+
+ negl %esi
+#ifdef __PIC__
+ call __x86.get_pc_thunk.bx
+#else
+ movl $8f, %ebx
+8:
+#endif
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+#if USE___THREAD
+# ifdef NO_TLS_DIRECT_SEG_REFS
+ movl errno@gotntpoff(%ebx), %edx
+ addl %gs:0, %edx
+ movl %esi, (%edx)
+# else
+ movl errno@gotntpoff(%ebx), %edx
+ movl %esi, %gs:(%edx)
+# endif
+#else
+ call __errno_location@plt
+ movl %esi, (%eax)
+#endif
+ orl $-1, %eax
+
+ jmp 9b
+ .size __new_sem_wait,.-__new_sem_wait
+weak_alias(__new_sem_wait, sem_wait)
+
+
+ .type sem_wait_cleanup,@function
+sem_wait_cleanup:
+ LOCK
+ decl NWAITERS(%ebx)
+ movl %eax, (%esp)
+.LcallUR:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE:
+ .size sem_wait_cleanup,.-sem_wait_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff # @LPStart format (omit)
+ .byte 0xff # @TType format (omit)
+ .byte 0x01 # call-site format
+ # DW_EH_PE_uleb128
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 sem_wait_cleanup-.LSTARTCODE
+ .uleb128 0
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+ .long .LENDCIE-.LSTARTCIE # Length of the CIE.
+.LSTARTCIE:
+ .long 0 # CIE ID.
+ .byte 1 # Version number.
+#ifdef SHARED
+ .string "zPLR" # NUL-terminated augmentation
+ # string.
+#else
+ .string "zPL" # NUL-terminated augmentation
+ # string.
+#endif
+ .uleb128 1 # Code alignment factor.
+ .sleb128 -4 # Data alignment factor.
+ .byte 8 # Return address register
+ # column.
+#ifdef SHARED
+ .uleb128 7 # Augmentation value length.
+ .byte 0x9b # Personality: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4
+ # + DW_EH_PE_indirect
+ .long DW.ref.__gcc_personality_v0-.
+ .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+ .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+#else
+ .uleb128 6 # Augmentation value length.
+ .byte 0x0 # Personality: absolute
+ .long __gcc_personality_v0
+ .byte 0x0 # LSDA Encoding: absolute
+#endif
+ .byte 0x0c # DW_CFA_def_cfa
+ .uleb128 4
+ .uleb128 4
+ .byte 0x88 # DW_CFA_offset, column 0x10
+ .uleb128 1
+ .align 4
+.LENDCIE:
+
+ .long .LENDFDE-.LSTARTFDE # Length of the FDE.
+.LSTARTFDE:
+ .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
+#ifdef SHARED
+ .long .LSTARTCODE-. # PC-relative start address
+ # of the code.
+#else
+ .long .LSTARTCODE # Start address of the code.
+#endif
+ .long .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 4 # Augmentation size
+#ifdef SHARED
+ .long .LexceptSTART-.
+#else
+ .long .LexceptSTART
+#endif
+
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_ebx-.LSTARTCODE
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0x83 # DW_CFA_offset %ebx
+ .uleb128 2
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_esi-.Lpush_ebx
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 12
+ .byte 0x86 # DW_CFA_offset %esi
+ .uleb128 3
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lsub_esp-.Lpush_esi
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Ladd_esp-.Lsub_esp
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 4
+ .byte 0xc3 # DW_CFA_restore %ebx
+ .byte 0xc6 # DW_CFA_restore %esi
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lafter_ret-.Ladd_esp
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0x83 # DW_CFA_offset %ebx
+ .uleb128 2
+ .byte 0x86 # DW_CFA_offset %esi
+ .uleb128 3
+ .align 4
+.LENDFDE:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
+
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevellock.S
new file mode 100644
index 000000000..f567c1d6d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevellock.S
@@ -0,0 +1 @@
+#include "../i486/libc-lowlevellock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevellock.S
new file mode 100644
index 000000000..e60dea89e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevellock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/lowlevellock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelrobustlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelrobustlock.S
new file mode 100644
index 000000000..f768e16a7
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevelrobustlock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/lowlevelrobustlock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_barrier_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_barrier_wait.S
new file mode 100644
index 000000000..6d20b9a95
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_barrier_wait.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_barrier_wait.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_broadcast.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_broadcast.S
new file mode 100644
index 000000000..5e1024eab
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_broadcast.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_cond_broadcast.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_signal.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_signal.S
new file mode 100644
index 000000000..da4e8cbab
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_signal.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_cond_signal.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_timedwait.S
new file mode 100644
index 000000000..c0131555b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_timedwait.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_cond_timedwait.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_wait.S
new file mode 100644
index 000000000..9b57fbaca
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_wait.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_cond_wait.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_rdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_rdlock.S
new file mode 100644
index 000000000..da2bc4704
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_rdlock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_rwlock_rdlock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedrdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedrdlock.S
new file mode 100644
index 000000000..0f2ec168b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedrdlock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_rwlock_timedrdlock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedwrlock.S
new file mode 100644
index 000000000..26501590a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedwrlock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_rwlock_timedwrlock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_unlock.S
new file mode 100644
index 000000000..5515e4895
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_unlock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_rwlock_unlock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_wrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_wrlock.S
new file mode 100644
index 000000000..04ac275f6
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_wrlock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_rwlock_wrlock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_post.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_post.S
new file mode 100644
index 000000000..7317e1582
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_post.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/sem_post.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S
new file mode 100644
index 000000000..f34539d56
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/sem_timedwait.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S
new file mode 100644
index 000000000..64145c2e3
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/sem_trywait.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S
new file mode 100644
index 000000000..b3d462125
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/sem_wait.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S
new file mode 100644
index 000000000..f567c1d6d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S
@@ -0,0 +1 @@
+#include "../i486/libc-lowlevellock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevellock.S
new file mode 100644
index 000000000..e60dea89e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevellock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/lowlevellock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrobustlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrobustlock.S
new file mode 100644
index 000000000..f768e16a7
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevelrobustlock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/lowlevelrobustlock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_barrier_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_barrier_wait.S
new file mode 100644
index 000000000..6d20b9a95
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_barrier_wait.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_barrier_wait.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_broadcast.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_broadcast.S
new file mode 100644
index 000000000..5e1024eab
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_broadcast.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_cond_broadcast.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_signal.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_signal.S
new file mode 100644
index 000000000..da4e8cbab
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_signal.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_cond_signal.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_timedwait.S
new file mode 100644
index 000000000..07d481f37
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_timedwait.S
@@ -0,0 +1,21 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define HAVE_CMOV 1
+#include "../i486/pthread_cond_timedwait.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_wait.S
new file mode 100644
index 000000000..9b57fbaca
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_wait.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_cond_wait.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_rdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_rdlock.S
new file mode 100644
index 000000000..da2bc4704
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_rdlock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_rwlock_rdlock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedrdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedrdlock.S
new file mode 100644
index 000000000..0f2ec168b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedrdlock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_rwlock_timedrdlock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedwrlock.S
new file mode 100644
index 000000000..26501590a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedwrlock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_rwlock_timedwrlock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_unlock.S
new file mode 100644
index 000000000..0894f0546
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_unlock.S
@@ -0,0 +1,21 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define HAVE_CMOV 1
+#include "../i486/pthread_rwlock_unlock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_wrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_wrlock.S
new file mode 100644
index 000000000..04ac275f6
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_wrlock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/pthread_rwlock_wrlock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_post.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_post.S
new file mode 100644
index 000000000..7317e1582
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_post.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/sem_post.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S
new file mode 100644
index 000000000..f34539d56
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/sem_timedwait.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S
new file mode 100644
index 000000000..64145c2e3
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/sem_trywait.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S
new file mode 100644
index 000000000..b3d462125
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "../i486/sem_wait.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
new file mode 100644
index 000000000..55add8b8e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
@@ -0,0 +1,584 @@
+/* Copyright (C) 2002-2004, 2006-2008, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H 1
+
+#ifndef __ASSEMBLER__
+# include <time.h>
+# include <sys/param.h>
+# include <bits/pthreadtypes.h>
+# include <bits/kernel-features.h>
+# include <tcb-offsets.h>
+
+# ifndef LOCK_INSTR
+# ifdef UP
+# define LOCK_INSTR /* nothing */
+# else
+# define LOCK_INSTR "lock;"
+# endif
+# endif
+#else
+# ifndef LOCK
+# ifdef UP
+# define LOCK
+# else
+# define LOCK lock
+# endif
+# endif
+#endif
+
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_CMP_REQUEUE 4
+#define FUTEX_WAKE_OP 5
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_WAIT_BITSET 9
+#define FUTEX_WAKE_BITSET 10
+#define FUTEX_WAIT_REQUEUE_PI 11
+#define FUTEX_CMP_REQUEUE_PI 12
+#define FUTEX_PRIVATE_FLAG 128
+#define FUTEX_CLOCK_REALTIME 256
+
+#define FUTEX_BITSET_MATCH_ANY 0xffffffff
+
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ({ unsigned int __fl = ((private) ^ FUTEX_PRIVATE_FLAG); \
+ __asm__ ("andl %%gs:%P1, %0" : "+r" (__fl) \
+ : "i" (offsetof (struct pthread, header.private_futex))); \
+ __fl | (fl); }))
+# endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+/* Initializer for compatibility lock. */
+#define LLL_LOCK_INITIALIZER (0)
+#define LLL_LOCK_INITIALIZER_LOCKED (1)
+#define LLL_LOCK_INITIALIZER_WAITERS (2)
+
+
+#ifdef __PIC__
+# define LLL_EBX_LOAD "xchgl %2, %%ebx\n"
+# define LLL_EBX_REG "D"
+#else
+# define LLL_EBX_LOAD
+# define LLL_EBX_REG "b"
+#endif
+
+#ifdef I386_USE_SYSENTER
+# ifdef SHARED
+# define LLL_ENTER_KERNEL "call *%%gs:%P6\n\t"
+# else
+# define LLL_ENTER_KERNEL "call *_dl_sysinfo\n\t"
+# endif
+#else
+# define LLL_ENTER_KERNEL "int $0x80\n\t"
+#endif
+
+/* Delay in spinlock loop. */
+#define BUSY_WAIT_NOP __asm__ ("rep; nop")
+
+
+#define LLL_STUB_UNWIND_INFO_START \
+ ".section .eh_frame,\"a\",@progbits\n" \
+"5:\t" ".long 7f-6f # Length of Common Information Entry\n" \
+"6:\t" ".long 0x0 # CIE Identifier Tag\n\t" \
+ ".byte 0x1 # CIE Version\n\t" \
+ ".ascii \"zR\\0\" # CIE Augmentation\n\t" \
+ ".uleb128 0x1 # CIE Code Alignment Factor\n\t" \
+ ".sleb128 -4 # CIE Data Alignment Factor\n\t" \
+ ".byte 0x8 # CIE RA Column\n\t" \
+ ".uleb128 0x1 # Augmentation size\n\t" \
+ ".byte 0x1b # FDE Encoding (pcrel sdata4)\n\t" \
+ ".byte 0xc # DW_CFA_def_cfa\n\t" \
+ ".uleb128 0x4\n\t" \
+ ".uleb128 0x0\n\t" \
+ ".align 4\n" \
+"7:\t" ".long 17f-8f # FDE Length\n" \
+"8:\t" ".long 8b-5b # FDE CIE offset\n\t" \
+ ".long 1b-. # FDE initial location\n\t" \
+ ".long 4b-1b # FDE address range\n\t" \
+ ".uleb128 0x0 # Augmentation size\n\t" \
+ ".byte 0x16 # DW_CFA_val_expression\n\t" \
+ ".uleb128 0x8\n\t" \
+ ".uleb128 10f-9f\n" \
+"9:\t" ".byte 0x78 # DW_OP_breg8\n\t" \
+ ".sleb128 3b-1b\n"
+#define LLL_STUB_UNWIND_INFO_END \
+ ".byte 0x16 # DW_CFA_val_expression\n\t" \
+ ".uleb128 0x8\n\t" \
+ ".uleb128 12f-11f\n" \
+"11:\t" ".byte 0x78 # DW_OP_breg8\n\t" \
+ ".sleb128 3b-2b\n" \
+"12:\t" ".byte 0x40 + (3b-2b-1) # DW_CFA_advance_loc\n\t" \
+ ".byte 0x16 # DW_CFA_val_expression\n\t" \
+ ".uleb128 0x8\n\t" \
+ ".uleb128 16f-13f\n" \
+"13:\t" ".byte 0x78 # DW_OP_breg8\n\t" \
+ ".sleb128 15f-14f\n\t" \
+ ".byte 0x0d # DW_OP_const4s\n" \
+"14:\t" ".4byte 3b-.\n\t" \
+ ".byte 0x1c # DW_OP_minus\n\t" \
+ ".byte 0x0d # DW_OP_const4s\n" \
+"15:\t" ".4byte 18f-.\n\t" \
+ ".byte 0x22 # DW_OP_plus\n" \
+"16:\t" ".align 4\n" \
+"17:\t" ".previous\n"
+
+/* Unwind info for
+ 1: lea ..., ...
+ 2: call ...
+ 3: jmp 18f
+ 4:
+ snippet. */
+#define LLL_STUB_UNWIND_INFO_3 \
+LLL_STUB_UNWIND_INFO_START \
+"10:\t" ".byte 0x40 + (2b-1b) # DW_CFA_advance_loc\n\t" \
+LLL_STUB_UNWIND_INFO_END
+
+/* Unwind info for
+ 1: lea ..., ...
+ 0: movl ..., ...
+ 2: call ...
+ 3: jmp 18f
+ 4:
+ snippet. */
+#define LLL_STUB_UNWIND_INFO_4 \
+LLL_STUB_UNWIND_INFO_START \
+"10:\t" ".byte 0x40 + (0b-1b) # DW_CFA_advance_loc\n\t" \
+ ".byte 0x16 # DW_CFA_val_expression\n\t" \
+ ".uleb128 0x8\n\t" \
+ ".uleb128 20f-19f\n" \
+"19:\t" ".byte 0x78 # DW_OP_breg8\n\t" \
+ ".sleb128 3b-0b\n" \
+"20:\t" ".byte 0x40 + (2b-0b) # DW_CFA_advance_loc\n\t" \
+LLL_STUB_UNWIND_INFO_END
+
+
+#define lll_futex_wait(futex, val, private) \
+ lll_futex_timed_wait (futex, val, NULL, private)
+
+
+#define lll_futex_timed_wait(futex, val, timeout, private) \
+ ({ \
+ int __status; \
+ register __typeof (val) _val __asm__ ("edx") = (val); \
+ __asm__ __volatile (LLL_EBX_LOAD \
+ LLL_ENTER_KERNEL \
+ LLL_EBX_LOAD \
+ : "=a" (__status) \
+ : "0" (SYS_futex), LLL_EBX_REG (futex), "S" (timeout), \
+ "c" (__lll_private_flag (FUTEX_WAIT, private)), \
+ "d" (_val), "i" (offsetof (tcbhead_t, sysinfo)) \
+ : "memory"); \
+ __status; \
+ })
+
+
+#define lll_futex_wake(futex, nr, private) \
+ do { \
+ int __ignore; \
+ register __typeof (nr) _nr __asm__ ("edx") = (nr); \
+ __asm__ __volatile (LLL_EBX_LOAD \
+ LLL_ENTER_KERNEL \
+ LLL_EBX_LOAD \
+ : "=a" (__ignore) \
+ : "0" (SYS_futex), LLL_EBX_REG (futex), \
+ "c" (__lll_private_flag (FUTEX_WAKE, private)), \
+ "d" (_nr), \
+ "i" (0) /* phony, to align next arg's number */, \
+ "i" (offsetof (tcbhead_t, sysinfo))); \
+ } while (0)
+
+
+/* NB: in the lll_trylock macro we simply return the value in %eax
+ after the cmpxchg instruction. In case the operation succeded this
+ value is zero. In case the operation failed, the cmpxchg instruction
+ has loaded the current value of the memory work which is guaranteed
+ to be nonzero. */
+#if defined NOT_IN_libc || defined UP
+# define __lll_trylock_asm LOCK_INSTR "cmpxchgl %2, %1"
+#else
+# define __lll_trylock_asm "cmpl $0, %%gs:%P5\n\t" \
+ "je 0f\n\t" \
+ "lock\n" \
+ "0:\tcmpxchgl %2, %1"
+#endif
+
+#define lll_trylock(futex) \
+ ({ int ret; \
+ __asm__ __volatile (__lll_trylock_asm \
+ : "=a" (ret), "=m" (futex) \
+ : "r" (LLL_LOCK_INITIALIZER_LOCKED), "m" (futex), \
+ "0" (LLL_LOCK_INITIALIZER), \
+ "i" (MULTIPLE_THREADS_OFFSET) \
+ : "memory"); \
+ ret; })
+
+#define lll_robust_trylock(futex, id) \
+ ({ int ret; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %2, %1" \
+ : "=a" (ret), "=m" (futex) \
+ : "r" (id), "m" (futex), \
+ "0" (LLL_LOCK_INITIALIZER) \
+ : "memory"); \
+ ret; })
+
+
+#define lll_cond_trylock(futex) \
+ ({ int ret; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %2, %1" \
+ : "=a" (ret), "=m" (futex) \
+ : "r" (LLL_LOCK_INITIALIZER_WAITERS), \
+ "m" (futex), "0" (LLL_LOCK_INITIALIZER) \
+ : "memory"); \
+ ret; })
+
+#if defined NOT_IN_libc || defined UP
+# define __lll_lock_asm_start LOCK_INSTR "cmpxchgl %1, %2\n\t"
+#else
+# define __lll_lock_asm_start "cmpl $0, %%gs:%P6\n\t" \
+ "je 0f\n\t" \
+ "lock\n" \
+ "0:\tcmpxchgl %1, %2\n\t"
+#endif
+
+#define lll_lock(futex, private) \
+ (void) \
+ ({ int ignore1, ignore2; \
+ if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \
+ __asm__ __volatile (__lll_lock_asm_start \
+ "jnz _L_lock_%=\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_lock_%=,@function\n" \
+ "_L_lock_%=:\n" \
+ "1:\tleal %2, %%ecx\n" \
+ "2:\tcall __lll_lock_wait_private\n" \
+ "3:\tjmp 18f\n" \
+ "4:\t.size _L_lock_%=, 4b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_3 \
+ "18:" \
+ : "=a" (ignore1), "=c" (ignore2), "=m" (futex) \
+ : "0" (0), "1" (1), "m" (futex), \
+ "i" (MULTIPLE_THREADS_OFFSET) \
+ : "memory"); \
+ else \
+ { \
+ int ignore3; \
+ __asm__ __volatile (__lll_lock_asm_start \
+ "jnz _L_lock_%=\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_lock_%=,@function\n" \
+ "_L_lock_%=:\n" \
+ "1:\tleal %2, %%edx\n" \
+ "0:\tmovl %8, %%ecx\n" \
+ "2:\tcall __lll_lock_wait\n" \
+ "3:\tjmp 18f\n" \
+ "4:\t.size _L_lock_%=, 4b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_4 \
+ "18:" \
+ : "=a" (ignore1), "=c" (ignore2), \
+ "=m" (futex), "=&d" (ignore3) \
+ : "1" (1), "m" (futex), \
+ "i" (MULTIPLE_THREADS_OFFSET), "0" (0), \
+ "g" ((int) (private)) \
+ : "memory"); \
+ } \
+ })
+
+#define lll_robust_lock(futex, id, private) \
+ ({ int __result, ignore1, ignore2; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %1, %2\n\t" \
+ "jnz _L_robust_lock_%=\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_robust_lock_%=,@function\n" \
+ "_L_robust_lock_%=:\n" \
+ "1:\tleal %2, %%edx\n" \
+ "0:\tmovl %7, %%ecx\n" \
+ "2:\tcall __lll_robust_lock_wait\n" \
+ "3:\tjmp 18f\n" \
+ "4:\t.size _L_robust_lock_%=, 4b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_4 \
+ "18:" \
+ : "=a" (__result), "=c" (ignore1), "=m" (futex), \
+ "=&d" (ignore2) \
+ : "0" (0), "1" (id), "m" (futex), "g" ((int) (private))\
+ : "memory"); \
+ __result; })
+
+
+/* Special version of lll_lock which causes the unlock function to
+ always wakeup waiters. */
+#define lll_cond_lock(futex, private) \
+ (void) \
+ ({ int ignore1, ignore2, ignore3; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %1, %2\n\t" \
+ "jnz _L_cond_lock_%=\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_cond_lock_%=,@function\n" \
+ "_L_cond_lock_%=:\n" \
+ "1:\tleal %2, %%edx\n" \
+ "0:\tmovl %7, %%ecx\n" \
+ "2:\tcall __lll_lock_wait\n" \
+ "3:\tjmp 18f\n" \
+ "4:\t.size _L_cond_lock_%=, 4b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_4 \
+ "18:" \
+ : "=a" (ignore1), "=c" (ignore2), "=m" (futex), \
+ "=&d" (ignore3) \
+ : "0" (0), "1" (2), "m" (futex), "g" ((int) (private))\
+ : "memory"); \
+ })
+
+
+#define lll_robust_cond_lock(futex, id, private) \
+ ({ int __result, ignore1, ignore2; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %1, %2\n\t" \
+ "jnz _L_robust_cond_lock_%=\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_robust_cond_lock_%=,@function\n" \
+ "_L_robust_cond_lock_%=:\n" \
+ "1:\tleal %2, %%edx\n" \
+ "0:\tmovl %7, %%ecx\n" \
+ "2:\tcall __lll_robust_lock_wait\n" \
+ "3:\tjmp 18f\n" \
+ "4:\t.size _L_robust_cond_lock_%=, 4b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_4 \
+ "18:" \
+ : "=a" (__result), "=c" (ignore1), "=m" (futex), \
+ "=&d" (ignore2) \
+ : "0" (0), "1" (id | FUTEX_WAITERS), "m" (futex), \
+ "g" ((int) (private)) \
+ : "memory"); \
+ __result; })
+
+
+#define lll_timedlock(futex, timeout, private) \
+ ({ int __result, ignore1, ignore2, ignore3; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %1, %3\n\t" \
+ "jnz _L_timedlock_%=\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_timedlock_%=,@function\n" \
+ "_L_timedlock_%=:\n" \
+ "1:\tleal %3, %%ecx\n" \
+ "0:\tmovl %8, %%edx\n" \
+ "2:\tcall __lll_timedlock_wait\n" \
+ "3:\tjmp 18f\n" \
+ "4:\t.size _L_timedlock_%=, 4b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_4 \
+ "18:" \
+ : "=a" (__result), "=c" (ignore1), "=&d" (ignore2), \
+ "=m" (futex), "=S" (ignore3) \
+ : "0" (0), "1" (1), "m" (futex), "m" (timeout), \
+ "4" ((int) (private)) \
+ : "memory"); \
+ __result; })
+
+
+#define lll_robust_timedlock(futex, timeout, id, private) \
+ ({ int __result, ignore1, ignore2, ignore3; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %1, %3\n\t" \
+ "jnz _L_robust_timedlock_%=\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_robust_timedlock_%=,@function\n" \
+ "_L_robust_timedlock_%=:\n" \
+ "1:\tleal %3, %%ecx\n" \
+ "0:\tmovl %8, %%edx\n" \
+ "2:\tcall __lll_robust_timedlock_wait\n" \
+ "3:\tjmp 18f\n" \
+ "4:\t.size _L_robust_timedlock_%=, 4b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_4 \
+ "18:" \
+ : "=a" (__result), "=c" (ignore1), "=&d" (ignore2), \
+ "=m" (futex), "=S" (ignore3) \
+ : "0" (0), "1" (id), "m" (futex), "m" (timeout), \
+ "4" ((int) (private)) \
+ : "memory"); \
+ __result; })
+
+#if defined NOT_IN_libc || defined UP
+# define __lll_unlock_asm LOCK_INSTR "subl $1, %0\n\t"
+#else
+# define __lll_unlock_asm "cmpl $0, %%gs:%P3\n\t" \
+ "je 0f\n\t" \
+ "lock\n" \
+ "0:\tsubl $1,%0\n\t"
+#endif
+
+#define lll_unlock(futex, private) \
+ (void) \
+ ({ int ignore; \
+ if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \
+ __asm__ __volatile (__lll_unlock_asm \
+ "jne _L_unlock_%=\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_unlock_%=,@function\n" \
+ "_L_unlock_%=:\n" \
+ "1:\tleal %0, %%eax\n" \
+ "2:\tcall __lll_unlock_wake_private\n" \
+ "3:\tjmp 18f\n" \
+ "4:\t.size _L_unlock_%=, 4b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_3 \
+ "18:" \
+ : "=m" (futex), "=&a" (ignore) \
+ : "m" (futex), "i" (MULTIPLE_THREADS_OFFSET) \
+ : "memory"); \
+ else \
+ { \
+ int ignore2; \
+ __asm__ __volatile (__lll_unlock_asm \
+ "jne _L_unlock_%=\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_unlock_%=,@function\n" \
+ "_L_unlock_%=:\n" \
+ "1:\tleal %0, %%eax\n" \
+ "0:\tmovl %5, %%ecx\n" \
+ "2:\tcall __lll_unlock_wake\n" \
+ "3:\tjmp 18f\n" \
+ "4:\t.size _L_unlock_%=, 4b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_4 \
+ "18:" \
+ : "=m" (futex), "=&a" (ignore), "=&c" (ignore2) \
+ : "i" (MULTIPLE_THREADS_OFFSET), "m" (futex), \
+ "g" ((int) (private)) \
+ : "memory"); \
+ } \
+ })
+
+#define lll_robust_unlock(futex, private) \
+ (void) \
+ ({ int ignore, ignore2; \
+ __asm__ __volatile (LOCK_INSTR "andl %3, %0\n\t" \
+ "jne _L_robust_unlock_%=\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_robust_unlock_%=,@function\n" \
+ "_L_robust_unlock_%=:\n\t" \
+ "1:\tleal %0, %%eax\n" \
+ "0:\tmovl %5, %%ecx\n" \
+ "2:\tcall __lll_unlock_wake\n" \
+ "3:\tjmp 18f\n" \
+ "4:\t.size _L_robust_unlock_%=, 4b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_4 \
+ "18:" \
+ : "=m" (futex), "=&a" (ignore), "=&c" (ignore2) \
+ : "i" (FUTEX_WAITERS), "m" (futex), \
+ "g" ((int) (private)) \
+ : "memory"); \
+ })
+
+
+#define lll_robust_dead(futex, private) \
+ (void) \
+ ({ int __ignore; \
+ register int _nr __asm__ ("edx") = 1; \
+ __asm__ __volatile (LOCK_INSTR "orl %5, (%2)\n\t" \
+ LLL_EBX_LOAD \
+ LLL_ENTER_KERNEL \
+ LLL_EBX_LOAD \
+ : "=a" (__ignore) \
+ : "0" (SYS_futex), LLL_EBX_REG (&(futex)), \
+ "c" (__lll_private_flag (FUTEX_WAKE, private)), \
+ "d" (_nr), "i" (FUTEX_OWNER_DIED), \
+ "i" (offsetof (tcbhead_t, sysinfo))); \
+ })
+
+#define lll_islocked(futex) \
+ (futex != LLL_LOCK_INITIALIZER)
+
+/* The kernel notifies a process with uses CLONE_CLEARTID via futex
+ wakeup when the clone terminates. The memory location contains the
+ thread ID while the clone is running and is reset to zero
+ afterwards.
+
+ The macro parameter must not have any side effect. */
+#define lll_wait_tid(tid) \
+ do { \
+ int __ignore; \
+ register __typeof (tid) _tid __asm__ ("edx") = (tid); \
+ if (_tid != 0) \
+ __asm__ __volatile (LLL_EBX_LOAD \
+ "1:\tmovl %1, %%eax\n\t" \
+ LLL_ENTER_KERNEL \
+ "cmpl $0, (%%ebx)\n\t" \
+ "jne 1b\n\t" \
+ LLL_EBX_LOAD \
+ : "=&a" (__ignore) \
+ : "i" (SYS_futex), LLL_EBX_REG (&tid), "S" (0), \
+ "c" (FUTEX_WAIT), "d" (_tid), \
+ "i" (offsetof (tcbhead_t, sysinfo)) \
+ : "memory"); \
+ } while (0)
+
+extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
+ __attribute__ ((regparm (2))) attribute_hidden;
+#define lll_timedwait_tid(tid, abstime) \
+ ({ \
+ int __result = 0; \
+ if (tid != 0) \
+ { \
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) \
+ __result = EINVAL; \
+ else \
+ __result = __lll_timedwait_tid (&tid, abstime); \
+ } \
+ __result; })
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* lowlevellock.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-__syscall_error.c b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-__syscall_error.c
new file mode 100644
index 000000000..620640ad6
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-__syscall_error.c
@@ -0,0 +1 @@
+#include <../../../../../../../libc/sysdeps/linux/i386/__syscall_error.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-vfork.S
new file mode 100644
index 000000000..aff926a8f
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-vfork.S
@@ -0,0 +1,68 @@
+/* Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Schwab <schwab@gnu.org>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+
+/* Save the PID value. */
+#define SAVE_PID \
+ movl %gs:PID, %edx; \
+ movl %edx, %eax; \
+ negl %eax; \
+ movl %eax, %gs:PID
+
+/* Restore the old PID value in the parent. */
+#define RESTORE_PID \
+ testl %eax, %eax; \
+ je 1f; \
+ movl %edx, %gs:PID; \
+1:
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+ /* Pop the return PC value into ECX. */
+ popl %ecx
+
+ SAVE_PID
+
+ /* Stuff the syscall number in EAX and enter into the kernel. */
+ movl $SYS_ify (vfork), %eax
+ int $0x80
+
+ RESTORE_PID
+
+ /* Jump to the return PC. Don't jump directly since this
+ disturbs the branch target cache. Instead push the return
+ address back on the stack. */
+ pushl %ecx
+
+ cmpl $-4095, %eax
+ jae SYSCALL_ERROR_LABEL /* Branch forward if it failed. */
+L(pseudo_end):
+ ret
+PSEUDO_END (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S
new file mode 100644
index 000000000..7a2cbf464
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S
@@ -0,0 +1,197 @@
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unwindbuf.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+#include <lowlevellock.h>
+#include <tls.h>
+
+
+ .comm __fork_generation, 4, 4
+
+ .text
+
+
+ .globl __pthread_once
+ .type __pthread_once,@function
+ .protected __pthread_once
+ .align 16
+ cfi_startproc
+__pthread_once:
+ movl 4(%esp), %ecx
+ testl $2, (%ecx)
+ jz 1f
+ xorl %eax, %eax
+ ret
+
+1: pushl %ebx
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (3, 0)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (6, 0)
+ movl %ecx, %ebx
+ xorl %esi, %esi
+
+ /* Not yet initialized or initialization in progress.
+ Get the fork generation counter now. */
+6: movl (%ebx), %eax
+#ifdef __PIC__
+ call __x86.get_pc_thunk.cx
+ addl $_GLOBAL_OFFSET_TABLE_, %ecx
+#endif
+
+5: movl %eax, %edx
+
+ testl $2, %eax
+ jnz 4f
+
+ andl $3, %edx
+#ifdef __PIC__
+ orl __fork_generation@GOTOFF(%ecx), %edx
+#else
+ orl __fork_generation, %edx
+#endif
+ orl $1, %edx
+
+ LOCK
+ cmpxchgl %edx, (%ebx)
+ jnz 5b
+
+ /* Check whether another thread already runs the initializer. */
+ testl $1, %eax
+ jz 3f /* No -> do it. */
+
+ /* Check whether the initializer execution was interrupted
+ by a fork. */
+ xorl %edx, %eax
+ testl $0xfffffffc, %eax
+ jnz 3f /* Different for generation -> run initializer. */
+
+ /* Somebody else got here first. Wait. */
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAIT|FUTEX_PRIVATE_FLAG, %ecx
+#else
+# if FUTEX_WAIT == 0
+ movl %gs:PRIVATE_FUTEX, %ecx
+# else
+ movl $FUTEX_WAIT, %ecx
+ orl %gs:PRIVATE_FUTEX, %ecx
+# endif
+#endif
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+ jmp 6b
+
+3: /* Call the initializer function after setting up the
+ cancellation handler. Note that it is not possible here
+ to use the unwind-based cleanup handling. This would require
+ that the user-provided function and all the code it calls
+ is compiled with exceptions. Unfortunately this cannot be
+ guaranteed. */
+ subl $UNWINDBUFSIZE+8, %esp
+ cfi_adjust_cfa_offset (UNWINDBUFSIZE+8)
+ movl %ecx, %ebx /* PIC register value. */
+
+ leal 8+UWJMPBUF(%esp), %eax
+ movl $0, 4(%esp)
+ movl %eax, (%esp)
+ call __sigsetjmp@PLT
+ testl %eax, %eax
+ jne 7f
+
+ leal 8(%esp), %eax
+ call HIDDEN_JUMPTARGET(__pthread_register_cancel)
+
+ /* Call the user-provided initialization function. */
+ call *24+UNWINDBUFSIZE(%esp)
+
+ /* Pop the cleanup handler. */
+ leal 8(%esp), %eax
+ call HIDDEN_JUMPTARGET(__pthread_unregister_cancel)
+ addl $UNWINDBUFSIZE+8, %esp
+ cfi_adjust_cfa_offset (-UNWINDBUFSIZE-8)
+
+ /* Sucessful run of the initializer. Signal that we are done. */
+ movl 12(%esp), %ebx
+ LOCK
+ addl $1, (%ebx)
+
+ /* Wake up all other threads. */
+ movl $0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %ecx
+#else
+ movl $FUTEX_WAKE, %ecx
+ orl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+4: popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (6)
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (3)
+ xorl %eax, %eax
+ ret
+
+7: /* __sigsetjmp returned for the second time. */
+ movl 20+UNWINDBUFSIZE(%esp), %ebx
+ cfi_adjust_cfa_offset (UNWINDBUFSIZE+16)
+ cfi_offset (3, -8)
+ cfi_offset (6, -12)
+ movl $0, (%ebx)
+
+ movl $0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %ecx
+#else
+ movl $FUTEX_WAKE, %ecx
+ orl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ movl $SYS_futex, %eax
+ ENTER_KERNEL
+
+ leal 8(%esp), %eax
+ call HIDDEN_JUMPTARGET (__pthread_unwind_next)
+ /* NOTREACHED */
+ hlt
+ cfi_endproc
+ .size __pthread_once,.-__pthread_once
+
+ .globl __pthread_once_internal
+__pthread_once_internal = __pthread_once
+
+ .globl pthread_once
+pthread_once = __pthread_once
+
+
+#ifdef __PIC__
+ .section .gnu.linkonce.t.__x86.get_pc_thunk.cx,"ax",@progbits
+ .globl __x86.get_pc_thunk.cx
+ .hidden __x86.get_pc_thunk.cx
+ .type __x86.get_pc_thunk.cx,@function
+__x86.get_pc_thunk.cx:
+ movl (%esp), %ecx;
+ ret
+ .size __x86.get_pc_thunk.cx,.-__x86.get_pc_thunk.cx
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_init.c b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_init.c
new file mode 100644
index 000000000..d36e5373d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_init.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/pthread_spin_init.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_unlock.S
new file mode 100644
index 000000000..8bae0fd31
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_unlock.S
@@ -0,0 +1 @@
+#include <sysdeps/i386/pthread_spin_unlock.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/smp.h b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/smp.h
new file mode 100644
index 000000000..f68a0c075
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/smp.h
@@ -0,0 +1,56 @@
+/* Determine whether the host has multiple processors. Linux version.
+ Copyright (C) 1996, 2002, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/utsname.h>
+#include <not-cancel.h>
+
+/* Test whether the machine has more than one processor. This is not the
+ best test but good enough. More complicated tests would require `malloc'
+ which is not available at that time. */
+static inline int
+is_smp_system (void)
+{
+ union
+ {
+ struct utsname uts;
+ char buf[512];
+ } u;
+ char *cp;
+
+ /* Try reading the number using `sysctl' first. */
+ if (uname (&u.uts) == 0)
+ cp = u.uts.version;
+ else
+ {
+ /* This was not successful. Now try reading the /proc filesystem. */
+ int fd = open_not_cancel_2 ("/proc/sys/kernel/version", O_RDONLY);
+ if (__builtin_expect (fd, 0) == -1
+ || read_not_cancel (fd, u.buf, sizeof (u.buf)) <= 0)
+ /* This also didn't work. We give up and say it's a UP machine. */
+ u.buf[0] = '\0';
+
+ close_not_cancel_no_status (fd);
+ cp = u.buf;
+ }
+
+ return strstr (cp, "SMP") != NULL;
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
new file mode 100644
index 000000000..cb8d6891c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
@@ -0,0 +1,155 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ cmpl $0, %gs:MULTIPLE_THREADS_OFFSET; \
+ jne L(pseudo_cancel); \
+ .type __##syscall_name##_nocancel,@function; \
+ .globl __##syscall_name##_nocancel; \
+ __##syscall_name##_nocancel: \
+ DO_CALL (syscall_name, args); \
+ cmpl $-4095, %eax; \
+ jae SYSCALL_ERROR_LABEL; \
+ ret; \
+ .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
+ L(pseudo_cancel): \
+ CENABLE \
+ SAVE_OLDTYPE_##args \
+ PUSHCARGS_##args \
+ DOCARGS_##args \
+ movl $SYS_ify (syscall_name), %eax; \
+ ENTER_KERNEL; \
+ POPCARGS_##args; \
+ POPSTATE_##args \
+ cmpl $-4095, %eax; \
+ jae SYSCALL_ERROR_LABEL; \
+ L(pseudo_end):
+
+# define SAVE_OLDTYPE_0 movl %eax, %ecx;
+# define SAVE_OLDTYPE_1 SAVE_OLDTYPE_0
+# define SAVE_OLDTYPE_2 pushl %eax; cfi_adjust_cfa_offset (4);
+# define SAVE_OLDTYPE_3 SAVE_OLDTYPE_2
+# define SAVE_OLDTYPE_4 SAVE_OLDTYPE_2
+# define SAVE_OLDTYPE_5 SAVE_OLDTYPE_2
+# define SAVE_OLDTYPE_6 SAVE_OLDTYPE_2
+
+# define PUSHCARGS_0 /* No arguments to push. */
+# define DOCARGS_0 /* No arguments to frob. */
+# define POPCARGS_0 /* No arguments to pop. */
+# define _PUSHCARGS_0 /* No arguments to push. */
+# define _POPCARGS_0 /* No arguments to pop. */
+
+# define PUSHCARGS_1 movl %ebx, %edx; cfi_register (ebx, edx); PUSHCARGS_0
+# define DOCARGS_1 _DOARGS_1 (4)
+# define POPCARGS_1 POPCARGS_0; movl %edx, %ebx; cfi_restore (ebx);
+# define _PUSHCARGS_1 pushl %ebx; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (ebx, 0); _PUSHCARGS_0
+# define _POPCARGS_1 _POPCARGS_0; popl %ebx; \
+ cfi_adjust_cfa_offset (-4); cfi_restore (ebx);
+
+# define PUSHCARGS_2 PUSHCARGS_1
+# define DOCARGS_2 _DOARGS_2 (12)
+# define POPCARGS_2 POPCARGS_1
+# define _PUSHCARGS_2 _PUSHCARGS_1
+# define _POPCARGS_2 _POPCARGS_1
+
+# define PUSHCARGS_3 _PUSHCARGS_2
+# define DOCARGS_3 _DOARGS_3 (20)
+# define POPCARGS_3 _POPCARGS_3
+# define _PUSHCARGS_3 _PUSHCARGS_2
+# define _POPCARGS_3 _POPCARGS_2
+
+# define PUSHCARGS_4 _PUSHCARGS_4
+# define DOCARGS_4 _DOARGS_4 (28)
+# define POPCARGS_4 _POPCARGS_4
+# define _PUSHCARGS_4 pushl %esi; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (esi, 0); _PUSHCARGS_3
+# define _POPCARGS_4 _POPCARGS_3; popl %esi; \
+ cfi_adjust_cfa_offset (-4); cfi_restore (esi);
+
+# define PUSHCARGS_5 _PUSHCARGS_5
+# define DOCARGS_5 _DOARGS_5 (36)
+# define POPCARGS_5 _POPCARGS_5
+# define _PUSHCARGS_5 pushl %edi; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (edi, 0); _PUSHCARGS_4
+# define _POPCARGS_5 _POPCARGS_4; popl %edi; \
+ cfi_adjust_cfa_offset (-4); cfi_restore (edi);
+
+# define PUSHCARGS_6 _PUSHCARGS_6
+# define DOCARGS_6 _DOARGS_6 (44)
+# define POPCARGS_6 _POPCARGS_6
+# define _PUSHCARGS_6 pushl %ebp; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (ebp, 0); _PUSHCARGS_5
+# define _POPCARGS_6 _POPCARGS_5; popl %ebp; \
+ cfi_adjust_cfa_offset (-4); cfi_restore (ebp);
+
+# ifdef IS_IN_libpthread
+# define CENABLE call __pthread_enable_asynccancel;
+# define CDISABLE call __pthread_disable_asynccancel
+# elif !defined NOT_IN_libc
+# define CENABLE call __libc_enable_asynccancel;
+# define CDISABLE call __libc_disable_asynccancel
+# elif defined IS_IN_librt
+# define CENABLE call __librt_enable_asynccancel;
+# define CDISABLE call __librt_disable_asynccancel
+# else
+# error Unsupported library
+# endif
+# define POPSTATE_0 \
+ pushl %eax; cfi_adjust_cfa_offset (4); movl %ecx, %eax; \
+ CDISABLE; popl %eax; cfi_adjust_cfa_offset (-4);
+# define POPSTATE_1 POPSTATE_0
+# define POPSTATE_2 xchgl (%esp), %eax; CDISABLE; popl %eax; \
+ cfi_adjust_cfa_offset (-4);
+# define POPSTATE_3 POPSTATE_2
+# define POPSTATE_4 POPSTATE_3
+# define POPSTATE_5 POPSTATE_4
+# define POPSTATE_6 POPSTATE_5
+
+# ifndef __ASSEMBLER__
+# define SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+# else
+# define SINGLE_THREAD_P cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
+# endif
+
+#elif !defined __ASSEMBLER__
+
+# define SINGLE_THREAD_P (1)
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/vfork.S
new file mode 100644
index 000000000..b39099af5
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/vfork.S
@@ -0,0 +1,38 @@
+/* Copyright (C) 1999,2002,2004,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <tcb-offsets.h>
+
+/* Save the PID value. */
+#define SAVE_PID \
+ movl %gs:PID, %edx; \
+ movl %edx, %eax; \
+ negl %eax; \
+ jne 1f; \
+ movl $0x80000000, %eax; \
+1: movl %eax, %gs:PID
+
+/* Restore the old PID value in the parent. */
+#define RESTORE_PID \
+ testl %eax, %eax; \
+ je 1f; \
+ movl %edx, %gs:PID; \
+1:
+
+
+#include <libc/sysdeps/linux/i386/vfork.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/internaltypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/internaltypes.h
new file mode 100644
index 000000000..3466c7fe5
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/internaltypes.h
@@ -0,0 +1,162 @@
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _INTERNALTYPES_H
+#define _INTERNALTYPES_H 1
+
+#include <stdint.h>
+#include <sched.h>
+
+struct pthread_attr
+{
+ /* Scheduler parameters and priority. */
+ struct sched_param schedparam;
+ int schedpolicy;
+ /* Various flags like detachstate, scope, etc. */
+ int flags;
+ /* Size of guard area. */
+ size_t guardsize;
+ /* Stack handling. */
+ void *stackaddr;
+ size_t stacksize;
+ /* Affinity map. */
+ cpu_set_t *cpuset;
+ size_t cpusetsize;
+};
+
+#define ATTR_FLAG_DETACHSTATE 0x0001
+#define ATTR_FLAG_NOTINHERITSCHED 0x0002
+#define ATTR_FLAG_SCOPEPROCESS 0x0004
+#define ATTR_FLAG_STACKADDR 0x0008
+#define ATTR_FLAG_OLDATTR 0x0010
+#define ATTR_FLAG_SCHED_SET 0x0020
+#define ATTR_FLAG_POLICY_SET 0x0040
+
+
+/* Mutex attribute data structure. */
+struct pthread_mutexattr
+{
+ /* Identifier for the kind of mutex.
+
+ Bit 31 is set if the mutex is to be shared between processes.
+
+ Bit 0 to 30 contain one of the PTHREAD_MUTEX_ values to identify
+ the type of the mutex. */
+ int mutexkind;
+};
+
+
+/* Conditional variable attribute data structure. */
+struct pthread_condattr
+{
+ /* Combination of values:
+
+ Bit 0 : flag whether coditional variable will be shareable between
+ processes.
+
+ Bit 1-7: clock ID. */
+ int value;
+};
+
+
+/* The __NWAITERS field is used as a counter and to house the number
+ of bits for other purposes. COND_CLOCK_BITS is the number
+ of bits needed to represent the ID of the clock. COND_NWAITERS_SHIFT
+ is the number of bits reserved for other purposes like the clock. */
+#define COND_CLOCK_BITS 1
+#define COND_NWAITERS_SHIFT 1
+
+
+/* Read-write lock variable attribute data structure. */
+struct pthread_rwlockattr
+{
+ int lockkind;
+ int pshared;
+};
+
+
+/* Barrier data structure. */
+struct pthread_barrier
+{
+ unsigned int curr_event;
+ int lock;
+ unsigned int left;
+ unsigned int init_count;
+ int private;
+};
+
+
+/* Barrier variable attribute data structure. */
+struct pthread_barrierattr
+{
+ int pshared;
+};
+
+
+/* Thread-local data handling. */
+struct pthread_key_struct
+{
+ /* Sequence numbers. Even numbers indicated vacant entries. Note
+ that zero is even. We use uintptr_t to not require padding on
+ 32- and 64-bit machines. On 64-bit machines it helps to avoid
+ wrapping, too. */
+ uintptr_t seq;
+
+ /* Destructor for the data. */
+ void (*destr) (void *);
+};
+
+/* Check whether an entry is unused. */
+#define KEY_UNUSED(p) (((p) & 1) == 0)
+/* Check whether a key is usable. We cannot reuse an allocated key if
+ the sequence counter would overflow after the next destroy call.
+ This would mean that we potentially free memory for a key with the
+ same sequence. This is *very* unlikely to happen, A program would
+ have to create and destroy a key 2^31 times (on 32-bit platforms,
+ on 64-bit platforms that would be 2^63). If it should happen we
+ simply don't use this specific key anymore. */
+#define KEY_USABLE(p) (((uintptr_t) (p)) < ((uintptr_t) ((p) + 2)))
+
+
+/* Handling of read-write lock data. */
+// XXX For now there is only one flag. Maybe more in future.
+#define RWLOCK_RECURSIVE(rwlock) ((rwlock)->__data.__flags != 0)
+
+
+/* Semaphore variable structure. */
+struct new_sem
+{
+ unsigned int value;
+ int private;
+ unsigned long int nwaiters;
+};
+
+struct old_sem
+{
+ unsigned int value;
+};
+
+
+/* Compatibility type for old conditional variable interfaces. */
+typedef struct
+{
+ pthread_cond_t *cond;
+} pthread_cond_2_0_t;
+
+#endif /* internaltypes.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c b/libpthread/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c
new file mode 100644
index 000000000..f2795510a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/jmp-unwind.c
@@ -0,0 +1,39 @@
+/* Clean up stack frames unwound by longjmp. Linux version.
+ Copyright (C) 1995, 1997, 2002, 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <setjmp.h>
+#include <stddef.h>
+#include <pthreadP.h>
+
+extern void __pthread_cleanup_upto (__jmp_buf env, char *targetframe);
+#pragma weak __pthread_cleanup_upto
+
+
+void
+_longjmp_unwind (jmp_buf env, int val)
+{
+#ifdef SHARED
+ if (__libc_pthread_functions_init)
+ PTHFCT_CALL (ptr___pthread_cleanup_upto, (env->__jmpbuf,
+ CURRENT_STACK_FRAME));
+#else
+ if (__pthread_cleanup_upto != NULL)
+ __pthread_cleanup_upto (env->__jmpbuf, CURRENT_STACK_FRAME);
+#endif
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h b/libpthread/nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h
new file mode 100644
index 000000000..9be630268
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/kernel-posix-timers.h
@@ -0,0 +1 @@
+#include <../../../../../../librt/kernel-posix-timers.h>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c
new file mode 100644
index 000000000..b19282281
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/libc-lowlevellock.c
@@ -0,0 +1,21 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* No difference to lowlevellock.c, except we lose a couple of functions. */
+#include "lowlevellock.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c b/libpthread/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c
new file mode 100644
index 000000000..a96f17490
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <pthreadP.h>
+
+#ifndef NOT_IN_libc
+# ifndef TLS_MULTIPLE_THREADS_IN_TCB
+int __libc_multiple_threads attribute_hidden;
+# endif
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c b/libpthread/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c
new file mode 100644
index 000000000..136b44595
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c
@@ -0,0 +1,74 @@
+/* Copyright (C) 2002,2003,2005,2006,2007,2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+#include <list.h>
+#include <fork.h>
+#include <dl-sysdep.h>
+#include <tls.h>
+#include <string.h>
+#include <pthreadP.h>
+#include <bits/libc-lock.h>
+#include <sysdep.h>
+#include <ldsodefs.h>
+
+
+#ifdef TLS_MULTIPLE_THREADS_IN_TCB
+void
+#else
+extern int __libc_multiple_threads attribute_hidden;
+
+int *
+#endif
+__libc_pthread_init (
+ unsigned long int *ptr,
+ void (*reclaim) (void),
+ const struct pthread_functions *functions)
+{
+ /* Remember the pointer to the generation counter in libpthread. */
+ __fork_generation_pointer = ptr;
+
+ /* Called by a child after fork. */
+ __register_atfork (NULL, NULL, reclaim, NULL);
+
+#ifdef SHARED
+ /* We copy the content of the variable pointed to by the FUNCTIONS
+ parameter to one in libc.so since this means access to the array
+ can be done with one memory access instead of two.
+ */
+ memcpy (&__libc_pthread_functions, functions,
+ sizeof (__libc_pthread_functions));
+ __libc_pthread_functions_init = 1;
+#endif
+
+#ifndef TLS_MULTIPLE_THREADS_IN_TCB
+ return &__libc_multiple_threads;
+#endif
+}
+
+#ifdef SHARED
+#if 0
+void
+libc_freeres_fn (freeres_libptread)
+{
+ if (__libc_pthread_functions_init)
+ PTHFCT_CALL (ptr_freeres, ());
+}
+#endif
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym
new file mode 100644
index 000000000..cfe22b089
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelbarrier.sym
@@ -0,0 +1,12 @@
+#include <stddef.h>
+#include <sched.h>
+#include <bits/pthreadtypes.h>
+#include "internaltypes.h"
+
+--
+
+CURR_EVENT offsetof (struct pthread_barrier, curr_event)
+MUTEX offsetof (struct pthread_barrier, lock)
+LEFT offsetof (struct pthread_barrier, left)
+INIT_COUNT offsetof (struct pthread_barrier, init_count)
+PRIVATE offsetof (struct pthread_barrier, private)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym
new file mode 100644
index 000000000..18e1adad4
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym
@@ -0,0 +1,16 @@
+#include <stddef.h>
+#include <sched.h>
+#include <bits/pthreadtypes.h>
+#include <internaltypes.h>
+
+--
+
+cond_lock offsetof (pthread_cond_t, __data.__lock)
+cond_futex offsetof (pthread_cond_t, __data.__futex)
+cond_nwaiters offsetof (pthread_cond_t, __data.__nwaiters)
+total_seq offsetof (pthread_cond_t, __data.__total_seq)
+wakeup_seq offsetof (pthread_cond_t, __data.__wakeup_seq)
+woken_seq offsetof (pthread_cond_t, __data.__woken_seq)
+dep_mutex offsetof (pthread_cond_t, __data.__mutex)
+broadcast_seq offsetof (pthread_cond_t, __data.__broadcast_seq)
+nwaiters_shift COND_NWAITERS_SHIFT
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
new file mode 100644
index 000000000..e07d78819
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
@@ -0,0 +1,127 @@
+/* low level locking for pthread library. Generic futex-using version.
+ Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <sys/time.h>
+#include <tls.h>
+#include <tcb-offsets.h>
+
+
+void
+__lll_lock_wait_private (int *futex)
+{
+ if (*futex == 2)
+ lll_futex_wait (futex, 2, LLL_PRIVATE);
+
+ while (atomic_exchange_acq (futex, 2) != 0)
+ lll_futex_wait (futex, 2, LLL_PRIVATE);
+}
+
+
+/* These functions don't get included in libc.so */
+#ifdef IS_IN_libpthread
+void
+__lll_lock_wait (int *futex, int private)
+{
+ if (*futex == 2)
+ lll_futex_wait (futex, 2, private);
+
+ while (atomic_exchange_acq (futex, 2) != 0)
+ lll_futex_wait (futex, 2, private);
+}
+
+
+int
+__lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
+{
+ /* Reject invalid timeouts. */
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+ return EINVAL;
+
+ /* Try locking. */
+ while (atomic_exchange_acq (futex, 2) != 0)
+ {
+ struct timeval tv;
+
+ /* Get the current time. */
+ (void) gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ struct timespec rt;
+ rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+ rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+ if (rt.tv_nsec < 0)
+ {
+ rt.tv_nsec += 1000000000;
+ --rt.tv_sec;
+ }
+
+ if (rt.tv_sec < 0)
+ return ETIMEDOUT;
+
+ /* Wait. */
+ lll_futex_timed_wait (futex, 2, &rt, private);
+ }
+
+ return 0;
+}
+
+
+int
+__lll_timedwait_tid (int *tidp, const struct timespec *abstime)
+{
+ int tid;
+
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+ return EINVAL;
+
+ /* Repeat until thread terminated. */
+ while ((tid = *tidp) != 0)
+ {
+ struct timeval tv;
+ struct timespec rt;
+
+ /* Get the current time. */
+ (void) __gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+ rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+ if (rt.tv_nsec < 0)
+ {
+ rt.tv_nsec += 1000000000;
+ --rt.tv_sec;
+ }
+
+ /* Already timed out? */
+ if (rt.tv_sec < 0)
+ return ETIMEDOUT;
+
+ /* Wait until thread terminates. The kernel so far does not use
+ the private futex operations for this. */
+ if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT)
+ return ETIMEDOUT;
+ }
+
+ return 0;
+}
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
new file mode 100644
index 000000000..3830f94da
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
@@ -0,0 +1,114 @@
+/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2006.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <sys/time.h>
+#include <pthreadP.h>
+
+
+int
+__lll_robust_lock_wait (int *futex, int private)
+{
+ int oldval = *futex;
+ int tid = THREAD_GETMEM (THREAD_SELF, tid);
+
+ /* If the futex changed meanwhile try locking again. */
+ if (oldval == 0)
+ goto try;
+
+ do
+ {
+ if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
+ return oldval;
+
+ int newval = oldval | FUTEX_WAITERS;
+ if (oldval != newval
+ && atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
+ continue;
+
+ lll_futex_wait (futex, newval, private);
+
+ try:
+ ;
+ }
+ while ((oldval = atomic_compare_and_exchange_val_acq (futex,
+ tid | FUTEX_WAITERS,
+ 0)) != 0);
+ return 0;
+}
+
+
+int
+__lll_robust_timedlock_wait (int *futex, const struct timespec *abstime,
+ int private)
+{
+ /* Reject invalid timeouts. */
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+ return EINVAL;
+
+ int tid = THREAD_GETMEM (THREAD_SELF, tid);
+ int oldval = *futex;
+
+ /* If the futex changed meanwhile try locking again. */
+ if (oldval == 0)
+ goto try;
+
+ do
+ {
+ struct timeval tv;
+ struct timespec rt;
+
+ /* Get the current time. */
+ (void) __gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+ rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+ if (rt.tv_nsec < 0)
+ {
+ rt.tv_nsec += 1000000000;
+ --rt.tv_sec;
+ }
+
+ /* Already timed out? */
+ if (rt.tv_sec < 0)
+ return ETIMEDOUT;
+
+ /* Wait. */
+ if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
+ return oldval;
+
+ int newval = oldval | FUTEX_WAITERS;
+ if (oldval != newval
+ && atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
+ continue;
+
+ lll_futex_timed_wait (futex, newval, &rt, private);
+
+ try:
+ ;
+ }
+ while ((oldval = atomic_compare_and_exchange_val_acq (futex,
+ tid | FUTEX_WAITERS,
+ 0)) != 0);
+
+ return 0;
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym
new file mode 100644
index 000000000..2f1e9da52
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.sym
@@ -0,0 +1,6 @@
+#include <stddef.h>
+#include <pthreadP.h>
+
+--
+
+TID offsetof (struct pthread, tid)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym
new file mode 100644
index 000000000..f50b25bfb
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrwlock.sym
@@ -0,0 +1,16 @@
+#include <stddef.h>
+#include <stdio.h>
+#include <bits/pthreadtypes.h>
+#include <bits/wordsize.h>
+
+--
+
+MUTEX offsetof (pthread_rwlock_t, __data.__lock)
+NR_READERS offsetof (pthread_rwlock_t, __data.__nr_readers)
+READERS_WAKEUP offsetof (pthread_rwlock_t, __data.__readers_wakeup)
+WRITERS_WAKEUP offsetof (pthread_rwlock_t, __data.__writer_wakeup)
+READERS_QUEUED offsetof (pthread_rwlock_t, __data.__nr_readers_queued)
+WRITERS_QUEUED offsetof (pthread_rwlock_t, __data.__nr_writers_queued)
+FLAGS offsetof (pthread_rwlock_t, __data.__flags)
+WRITER offsetof (pthread_rwlock_t, __data.__writer)
+PSHARED offsetof (pthread_rwlock_t, __data.__shared)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lseek.S b/libpthread/nptl/sysdeps/unix/sysv/linux/lseek.S
new file mode 100644
index 000000000..70a920ba1
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lseek.S
@@ -0,0 +1,7 @@
+#include <sysdep-cancel.h>
+PSEUDO (__libc_lseek, lseek, 3)
+ret
+PSEUDO_END (__libc_lseek)
+libc_hidden_def (__libc_lseek)
+weak_alias (__libc_lseek, lseek)
+libc_hidden_weak (lseek)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile
new file mode 100644
index 000000000..43a6fad84
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile
@@ -0,0 +1,13 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../../../../../
+top_builddir=../../../../../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.arch
+include $(top_srcdir)Makerules
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile.arch
new file mode 100644
index 000000000..8e7917bb0
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile.arch
@@ -0,0 +1,50 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+libpthread_SSRC = pt-vfork.S
+libpthread_CSRC = pthread_once.c pt-__syscall_rt_sigaction.c
+
+libc_a_CSRC = fork.c
+
+CFLAGS-OMIT-fork.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y)
+CFLAGS-fork.c = -D__USE_STDIO_FUTEXES__
+endif
+CFLAGS-pthread_once.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-pt-__syscall_rt_sigaction.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
+ASFLAGS-pt-vfork.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
+CFLAGS += $(SSP_ALL_CFLAGS)
+#CFLAGS:=$(CFLAGS:-O1=-O2)
+
+LINUX_ARCH_DIR:=$(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/mips
+LINUX_ARCH_OUT:=$(top_builddir)libpthread/nptl/sysdeps/unix/sysv/linux/mips
+
+LINUX_ARCH_OBJ:=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libpthread_SSRC))
+LINUX_ARCH_OBJ+=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libpthread_CSRC))
+
+ifeq ($(DOPIC),y)
+libpthread-a-y += $(LINUX_ARCH_OBJ:.o=.os)
+else
+libpthread-a-y += $(LINUX_ARCH_OBJ)
+endif
+libpthread-so-y += $(LINUX_ARCH_OBJ:.o=.oS)
+
+libpthread-nomulti-y+=$(LINUX_ARCH_OBJS)
+
+LIBC_LINUX_ARCH_OBJ:=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libc_a_CSRC))
+
+libc-static-y+=$(LIBC_LINUX_ARCH_OBJ)
+libc-shared-y+=$(LIBC_LINUX_ARCH_OBJ:.o=.oS)
+
+libc-nomulti-y+=$(LIBC_LINUX_ARCH_OBJ)
+
+objclean-y+=pthread_linux_arch_objclean
+
+pthread_linux_arch_objclean:
+ $(RM) $(LINUX_ARCH_OUT)/*.{o,os,oS}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/bits/pthreadtypes.h
new file mode 100644
index 000000000..166a6c6ae
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/bits/pthreadtypes.h
@@ -0,0 +1,229 @@
+/* Machine-specific pthread type layouts. MIPS version.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H 1
+
+#include <endian.h>
+
+#if _MIPS_SIM == _ABI64
+# define __SIZEOF_PTHREAD_ATTR_T 56
+# define __SIZEOF_PTHREAD_MUTEX_T 40
+# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+# define __SIZEOF_PTHREAD_COND_T 48
+# define __SIZEOF_PTHREAD_CONDATTR_T 4
+# define __SIZEOF_PTHREAD_RWLOCK_T 56
+# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+# define __SIZEOF_PTHREAD_BARRIER_T 32
+# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+#else
+# define __SIZEOF_PTHREAD_ATTR_T 36
+# define __SIZEOF_PTHREAD_MUTEX_T 24
+# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+# define __SIZEOF_PTHREAD_COND_T 48
+# define __SIZEOF_PTHREAD_CONDATTR_T 4
+# define __SIZEOF_PTHREAD_RWLOCK_T 32
+# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+# define __SIZEOF_PTHREAD_BARRIER_T 20
+# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+#endif
+
+
+/* Thread identifiers. The structure of the attribute type is
+ deliberately not exposed. */
+typedef unsigned long int pthread_t;
+
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_ATTR_T];
+ long int __align;
+} pthread_attr_t;
+
+
+#if _MIPS_SIM == _ABI64
+typedef struct __pthread_internal_list
+{
+ struct __pthread_internal_list *__prev;
+ struct __pthread_internal_list *__next;
+} __pthread_list_t;
+#else
+typedef struct __pthread_internal_slist
+{
+ struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+#endif
+
+
+/* Data structures for mutex handling. The structure of the attribute
+ type is deliberately not exposed. */
+typedef union
+{
+ struct __pthread_mutex_s
+ {
+ int __lock;
+ unsigned int __count;
+ int __owner;
+#if _MIPS_SIM == _ABI64
+ unsigned int __nusers;
+#endif
+ /* KIND must stay at this position in the structure to maintain
+ binary compatibility. */
+ int __kind;
+#if _MIPS_SIM == _ABI64
+ int __spins;
+ __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV 1
+#else
+ unsigned int __nusers;
+ __extension__ union
+ {
+ int __spins;
+ __pthread_slist_t __list;
+ };
+#endif
+ } __data;
+ char __size[__SIZEOF_PTHREAD_MUTEX_T];
+ long int __align;
+} pthread_mutex_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+ int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling. The structure of
+ the attribute type is deliberately not exposed. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned int __futex;
+ __extension__ unsigned long long int __total_seq;
+ __extension__ unsigned long long int __wakeup_seq;
+ __extension__ unsigned long long int __woken_seq;
+ void *__mutex;
+ unsigned int __nwaiters;
+ unsigned int __broadcast_seq;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_COND_T];
+ __extension__ long long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+ int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Data structure for read-write lock variable handling. The
+ structure of the attribute type is deliberately not exposed. */
+typedef union
+{
+# if _MIPS_SIM == _ABI64
+ struct
+ {
+ int __lock;
+ unsigned int __nr_readers;
+ unsigned int __readers_wakeup;
+ unsigned int __writer_wakeup;
+ unsigned int __nr_readers_queued;
+ unsigned int __nr_writers_queued;
+ int __writer;
+ int __shared;
+ unsigned long int __pad1;
+ unsigned long int __pad2;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned int __flags;
+ } __data;
+# else
+ struct
+ {
+ int __lock;
+ unsigned int __nr_readers;
+ unsigned int __readers_wakeup;
+ unsigned int __writer_wakeup;
+ unsigned int __nr_readers_queued;
+ unsigned int __nr_writers_queued;
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned char __pad1;
+ unsigned char __pad2;
+ unsigned char __shared;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned char __flags;
+#else
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned char __flags;
+ unsigned char __shared;
+ unsigned char __pad1;
+ unsigned char __pad2;
+#endif
+ int __writer;
+ } __data;
+# endif
+ char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+ long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+ long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type. */
+typedef volatile int pthread_spinlock_t;
+
+
+/* POSIX barriers data type. The structure of the type is
+ deliberately not exposed. */
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIER_T];
+ long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+ int __align;
+} pthread_barrierattr_t;
+#endif
+
+
+#endif /* bits/pthreadtypes.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/bits/semaphore.h
new file mode 100644
index 000000000..af43a6048
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/bits/semaphore.h
@@ -0,0 +1,37 @@
+/* Copyright (C) 2002, 2005, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+#if _MIPS_SIM == _ABI64
+# define __SIZEOF_SEM_T 32
+#else
+# define __SIZEOF_SEM_T 16
+#endif
+
+/* Value returned if `sem_open' failed. */
+#define SEM_FAILED ((sem_t *) 0)
+
+
+typedef union
+{
+ char __size[__SIZEOF_SEM_T];
+ long int __align;
+} sem_t;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/createthread.c
new file mode 100644
index 000000000..d8a7c5539
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/createthread.c
@@ -0,0 +1,24 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Value passed to 'clone' for initialization of the thread register. */
+#define TLS_VALUE ((void *) (pd) \
+ + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE)
+
+/* Get the real implementation. */
+#include <sysdeps/pthread/createthread.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/fork.c
new file mode 100644
index 000000000..06b7e1c69
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/fork.c
@@ -0,0 +1 @@
+#include "../i386/fork.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/lowlevellock.h
new file mode 100644
index 000000000..01bcf4120
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/lowlevellock.h
@@ -0,0 +1,295 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008,
+ 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H 1
+
+#include <time.h>
+#include <sys/param.h>
+#include <bits/pthreadtypes.h>
+#include <atomic.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_REQUEUE 3
+#define FUTEX_CMP_REQUEUE 4
+#define FUTEX_WAKE_OP 5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_WAIT_BITSET 9
+#define FUTEX_WAKE_BITSET 10
+#define FUTEX_PRIVATE_FLAG 128
+#define FUTEX_CLOCK_REALTIME 256
+
+#define FUTEX_BITSET_MATCH_ANY 0xffffffff
+
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
+ & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
+
+#define lll_futex_wait(futexp, val, private) \
+ lll_futex_timed_wait(futexp, val, NULL, private)
+
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (long) (futexp), \
+ __lll_private_flag (FUTEX_WAIT, private), \
+ (val), (timespec)); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
+ })
+
+#define lll_futex_wake(futexp, nr, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (long) (futexp), \
+ __lll_private_flag (FUTEX_WAKE, private), \
+ (nr), 0); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
+ })
+
+#define lll_robust_dead(futexv, private) \
+ do \
+ { \
+ int *__futexp = &(futexv); \
+ atomic_or (__futexp, FUTEX_OWNER_DIED); \
+ lll_futex_wake (__futexp, 1, private); \
+ } \
+ while (0)
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (long) (futexp), \
+ __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+ (nr_wake), (nr_move), (mutex), (val)); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_WAKE_OP, private), \
+ (nr_wake), (nr_wake2), (futexp2), \
+ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+static inline int __attribute__((always_inline))
+__lll_trylock(int *futex)
+{
+ return atomic_compare_and_exchange_val_acq (futex, 1, 0) != 0;
+}
+#define lll_trylock(lock) __lll_trylock (&(lock))
+
+
+static inline int __attribute__((always_inline))
+__lll_cond_trylock(int *futex)
+{
+ return atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0;
+}
+#define lll_cond_trylock(lock) __lll_cond_trylock (&(lock))
+
+
+static inline int __attribute__((always_inline))
+__lll_robust_trylock(int *futex, int id)
+{
+ return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0;
+}
+#define lll_robust_trylock(lock, id) \
+ __lll_robust_trylock (&(lock), id)
+
+extern void __lll_lock_wait_private (int *futex) attribute_hidden;
+extern void __lll_lock_wait (int *futex, int private) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden;
+
+#define __lll_lock(futex, private) \
+ ((void) ({ \
+ int *__futex = (futex); \
+ if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, \
+ 1, 0), 0)) \
+ { \
+ if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \
+ __lll_lock_wait_private (__futex); \
+ else \
+ __lll_lock_wait (__futex, private); \
+ } \
+ }))
+#define lll_lock(futex, private) __lll_lock (&(futex), private)
+
+
+#define __lll_robust_lock(futex, id, private) \
+ ({ \
+ int *__futex = (futex); \
+ int __val = 0; \
+ \
+ if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id, \
+ 0), 0)) \
+ __val = __lll_robust_lock_wait (__futex, private); \
+ __val; \
+ })
+#define lll_robust_lock(futex, id, private) \
+ __lll_robust_lock (&(futex), id, private)
+
+
+static inline void __attribute__ ((always_inline))
+__lll_cond_lock (int *futex, int private)
+{
+ if (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0)
+ __lll_lock_wait (futex, private);
+}
+#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
+
+
+#define lll_robust_cond_lock(futex, id, private) \
+ __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS, private)
+
+
+extern int __lll_timedlock_wait (int *futex, const struct timespec *,
+ int private) attribute_hidden;
+extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
+ int private) attribute_hidden;
+
+static inline int __attribute__ ((always_inline))
+__lll_timedlock (int *futex, const struct timespec *abstime, int private)
+{
+ int result = 0;
+ if (atomic_compare_and_exchange_bool_acq (futex, 1, 0) != 0)
+ result = __lll_timedlock_wait (futex, abstime, private);
+ return result;
+}
+#define lll_timedlock(futex, abstime, private) \
+ __lll_timedlock (&(futex), abstime, private)
+
+
+static inline int __attribute__ ((always_inline))
+__lll_robust_timedlock (int *futex, const struct timespec *abstime,
+ int id, int private)
+{
+ int result = 0;
+ if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+ result = __lll_robust_timedlock_wait (futex, abstime, private);
+ return result;
+}
+#define lll_robust_timedlock(futex, abstime, id, private) \
+ __lll_robust_timedlock (&(futex), abstime, id, private)
+
+
+#define __lll_unlock(futex, private) \
+ ((void) ({ \
+ int *__futex = (futex); \
+ int __val = atomic_exchange_rel (__futex, 0); \
+ \
+ if (__builtin_expect (__val > 1, 0)) \
+ lll_futex_wake (__futex, 1, private); \
+ }))
+#define lll_unlock(futex, private) __lll_unlock(&(futex), private)
+
+
+#define __lll_robust_unlock(futex, private) \
+ ((void) ({ \
+ int *__futex = (futex); \
+ int __val = atomic_exchange_rel (__futex, 0); \
+ \
+ if (__builtin_expect (__val & FUTEX_WAITERS, 0)) \
+ lll_futex_wake (__futex, 1, private); \
+ }))
+#define lll_robust_unlock(futex, private) \
+ __lll_robust_unlock(&(futex), private)
+
+
+#define lll_islocked(futex) \
+ (futex != 0)
+
+
+/* Our internal lock implementation is identical to the binary-compatible
+ mutex implementation. */
+
+/* Initializers for lock. */
+#define LLL_LOCK_INITIALIZER (0)
+#define LLL_LOCK_INITIALIZER_LOCKED (1)
+
+/* The states of a lock are:
+ 0 - untaken
+ 1 - taken by one user
+ >1 - taken by more users */
+
+/* The kernel notifies a process which uses CLONE_CLEARTID via futex
+ wakeup when the clone terminates. The memory location contains the
+ thread ID while the clone is running and is reset to zero
+ afterwards. */
+#define lll_wait_tid(tid) \
+ do { \
+ __typeof (tid) __tid; \
+ while ((__tid = (tid)) != 0) \
+ lll_futex_wait (&(tid), __tid, LLL_SHARED); \
+ } while (0)
+
+extern int __lll_timedwait_tid (int *, const struct timespec *)
+ attribute_hidden;
+
+#define lll_timedwait_tid(tid, abstime) \
+ ({ \
+ int __res = 0; \
+ if ((tid) != 0) \
+ __res = __lll_timedwait_tid (&(tid), (abstime)); \
+ __res; \
+ })
+
+#endif /* lowlevellock.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-__syscall_rt_sigaction.c b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-__syscall_rt_sigaction.c
new file mode 100644
index 000000000..50137c84a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-__syscall_rt_sigaction.c
@@ -0,0 +1 @@
+#include <../../../../../../../libc/sysdeps/linux/common/__syscall_rt_sigaction.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-clone.S
new file mode 100644
index 000000000..add405523
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-clone.S
@@ -0,0 +1,2 @@
+#define RESET_PID
+#include <../../../../../../../libc/sysdeps/linux/mips/clone.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-vfork.S
new file mode 100644
index 000000000..c02ffca93
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-vfork.S
@@ -0,0 +1,38 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <features.h>
+#include <tls.h>
+
+/* Save the PID value. */
+#define SAVE_PID \
+ READ_THREAD_POINTER(v1); /* Get the thread pointer. */ \
+ lw a2, PID_OFFSET(v1); /* Load the saved PID. */ \
+ subu a2, $0, a2; /* Negate it. */ \
+ sw a2, PID_OFFSET(v1); /* Store the temporary PID. */
+
+/* Restore the old PID value in the parent. */
+#define RESTORE_PID \
+ beqz v0, 1f; /* If we are the parent... */ \
+ READ_THREAD_POINTER(v1); /* Get the thread pointer. */ \
+ lw a2, PID_OFFSET(v1); /* Load the saved PID. */ \
+ subu a2, $0, a2; /* Re-negate it. */ \
+ sw a2, PID_OFFSET(v1); /* Restore the PID. */ \
+1:
+
+#include <../../../../../../../libc/sysdeps/linux/mips/vfork.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pthread_once.c
new file mode 100644
index 000000000..cc4658b32
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pthread_once.c
@@ -0,0 +1,95 @@
+/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+unsigned long int __fork_generation attribute_hidden;
+
+
+static void
+clear_once_control (void *arg)
+{
+ pthread_once_t *once_control = (pthread_once_t *) arg;
+
+ *once_control = 0;
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+}
+
+
+int
+attribute_protected
+__pthread_once (once_control, init_routine)
+ pthread_once_t *once_control;
+ void (*init_routine) (void);
+{
+ while (1)
+ {
+ int oldval, val, newval;
+
+ val = *once_control;
+ do
+ {
+ /* Check if the initialized has already been done. */
+ if ((val & 2) != 0)
+ return 0;
+
+ oldval = val;
+ newval = (oldval & 3) | __fork_generation | 1;
+ val = atomic_compare_and_exchange_val_acq (once_control, newval,
+ oldval);
+ }
+ while (__builtin_expect (val != oldval, 0));
+
+ /* Check if another thread already runs the initializer. */
+ if ((oldval & 1) != 0)
+ {
+ /* Check whether the initializer execution was interrupted
+ by a fork. */
+ if (((oldval ^ newval) & -4) == 0)
+ {
+ /* Same generation, some other thread was faster. Wait. */
+ lll_futex_wait (once_control, newval, LLL_PRIVATE);
+ continue;
+ }
+ }
+
+ /* This thread is the first here. Do the initialization.
+ Register a cleanup handler so that in case the thread gets
+ interrupted the initialization can be restarted. */
+ pthread_cleanup_push (clear_once_control, once_control);
+
+ init_routine ();
+
+ pthread_cleanup_pop (0);
+
+
+ /* Add one to *once_control. */
+ atomic_increment (once_control);
+
+ /* Wake up all other threads. */
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+ break;
+ }
+
+ return 0;
+}
+weak_alias (__pthread_once, pthread_once)
+strong_alias (__pthread_once, __pthread_once_internal)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h
new file mode 100644
index 000000000..1cf625f4e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h
@@ -0,0 +1,188 @@
+/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# ifdef __PIC__
+# define PSEUDO_CPLOAD .cpload t9;
+# define PSEUDO_ERRJMP la t9, __syscall_error; jr t9;
+# define PSEUDO_SAVEGP sw gp, 32(sp); cfi_rel_offset (gp, 32);
+# define PSEUDO_LOADGP lw gp, 32(sp);
+# else
+# define PSEUDO_CPLOAD
+# define PSEUDO_ERRJMP j __syscall_error;
+# define PSEUDO_SAVEGP
+# define PSEUDO_LOADGP
+# endif
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .align 2; \
+ L(pseudo_start): \
+ cfi_startproc; \
+ 99: PSEUDO_ERRJMP \
+ .type __##syscall_name##_nocancel, @function; \
+ .globl __##syscall_name##_nocancel; \
+ __##syscall_name##_nocancel: \
+ .set noreorder; \
+ PSEUDO_CPLOAD \
+ li v0, SYS_ify(syscall_name); \
+ syscall; \
+ .set reorder; \
+ bne a3, zero, 99b; \
+ ret; \
+ .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
+ ENTRY (name) \
+ .set noreorder; \
+ PSEUDO_CPLOAD \
+ .set reorder; \
+ SINGLE_THREAD_P(v1); \
+ bne zero, v1, L(pseudo_cancel); \
+ .set noreorder; \
+ li v0, SYS_ify(syscall_name); \
+ syscall; \
+ .set reorder; \
+ bne a3, zero, 99b; \
+ ret; \
+ L(pseudo_cancel): \
+ SAVESTK_##args; \
+ sw ra, 28(sp); \
+ cfi_rel_offset (ra, 28); \
+ PSEUDO_SAVEGP \
+ PUSHARGS_##args; /* save syscall args */ \
+ CENABLE; \
+ PSEUDO_LOADGP \
+ sw v0, 44(sp); /* save mask */ \
+ POPARGS_##args; /* restore syscall args */ \
+ .set noreorder; \
+ li v0, SYS_ify (syscall_name); \
+ syscall; \
+ .set reorder; \
+ sw v0, 36(sp); /* save syscall result */ \
+ sw a3, 40(sp); /* save syscall error flag */ \
+ lw a0, 44(sp); /* pass mask as arg1 */ \
+ CDISABLE; \
+ PSEUDO_LOADGP \
+ lw v0, 36(sp); /* restore syscall result */ \
+ lw a3, 40(sp); /* restore syscall error flag */ \
+ lw ra, 28(sp); /* restore return address */ \
+ .set noreorder; \
+ bne a3, zero, 99b; \
+ RESTORESTK; \
+ L(pseudo_end): \
+ .set reorder;
+
+# undef PSEUDO_END
+# define PSEUDO_END(sym) cfi_endproc; .end sym; .size sym,.-sym
+
+# define PUSHARGS_0 /* nothing to do */
+# define PUSHARGS_1 PUSHARGS_0 sw a0, 0(sp); cfi_rel_offset (a0, 0);
+# define PUSHARGS_2 PUSHARGS_1 sw a1, 4(sp); cfi_rel_offset (a1, 4);
+# define PUSHARGS_3 PUSHARGS_2 sw a2, 8(sp); cfi_rel_offset (a2, 8);
+# define PUSHARGS_4 PUSHARGS_3 sw a3, 12(sp); cfi_rel_offset (a3, 12);
+# define PUSHARGS_5 PUSHARGS_4 /* handled by SAVESTK_## */
+# define PUSHARGS_6 PUSHARGS_5
+# define PUSHARGS_7 PUSHARGS_6
+
+# define POPARGS_0 /* nothing to do */
+# define POPARGS_1 POPARGS_0 lw a0, 0(sp);
+# define POPARGS_2 POPARGS_1 lw a1, 4(sp);
+# define POPARGS_3 POPARGS_2 lw a2, 8(sp);
+# define POPARGS_4 POPARGS_3 lw a3, 12(sp);
+# define POPARGS_5 POPARGS_4 /* args already in new stackframe */
+# define POPARGS_6 POPARGS_5
+# define POPARGS_7 POPARGS_6
+
+
+# define STKSPACE 48
+# define SAVESTK_0 subu sp, STKSPACE; cfi_adjust_cfa_offset(STKSPACE)
+# define SAVESTK_1 SAVESTK_0
+# define SAVESTK_2 SAVESTK_1
+# define SAVESTK_3 SAVESTK_2
+# define SAVESTK_4 SAVESTK_3
+# define SAVESTK_5 lw t0, 16(sp); \
+ SAVESTK_0; \
+ sw t0, 16(sp)
+
+# define SAVESTK_6 lw t0, 16(sp); \
+ lw t1, 20(sp); \
+ SAVESTK_0; \
+ sw t0, 16(sp); \
+ sw t1, 20(sp)
+
+# define SAVESTK_7 lw t0, 16(sp); \
+ lw t1, 20(sp); \
+ lw t2, 24(sp); \
+ SAVESTK_0; \
+ sw t0, 16(sp); \
+ sw t1, 20(sp); \
+ sw t2, 24(sp)
+
+# define RESTORESTK addu sp, STKSPACE; cfi_adjust_cfa_offset(-STKSPACE)
+
+
+# ifdef __PIC__
+/* We use jalr rather than jal. This means that the assembler will not
+ automatically restore $gp (in case libc has multiple GOTs) so we must
+ do it manually - which we have to do anyway since we don't use .cprestore.
+ It also shuts up the assembler warning about not using .cprestore. */
+# define PSEUDO_JMP(sym) la t9, sym; jalr t9;
+# else
+# define PSEUDO_JMP(sym) jal sym;
+# endif
+
+# ifdef IS_IN_libpthread
+# define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel)
+# define CDISABLE PSEUDO_JMP (__pthread_disable_asynccancel)
+# elif defined IS_IN_librt
+# define CENABLE PSEUDO_JMP (__librt_enable_asynccancel)
+# define CDISABLE PSEUDO_JMP (__librt_disable_asynccancel)
+# else
+# define CENABLE PSEUDO_JMP (__libc_enable_asynccancel)
+# define CDISABLE PSEUDO_JMP (__libc_disable_asynccancel)
+# endif
+
+# ifndef __ASSEMBLER__
+# define SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) \
+ == 0, 1)
+# else
+# define SINGLE_THREAD_P(reg) \
+ READ_THREAD_POINTER(reg); \
+ lw reg, MULTIPLE_THREADS_OFFSET(reg)
+#endif
+
+#elif !defined __ASSEMBLER__
+
+# define SINGLE_THREAD_P 1
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mq_notify.c b/libpthread/nptl/sysdeps/unix/sysv/linux/mq_notify.c
new file mode 100644
index 000000000..188040ee8
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mq_notify.c
@@ -0,0 +1,286 @@
+/* Copyright (C) 2004, 2005, 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contribute by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysdep.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <not-cancel.h>
+#include <bits/kernel-features.h>
+
+
+#ifdef __NR_mq_notify
+
+/* Defined in the kernel headers: */
+#define NOTIFY_COOKIE_LEN 32 /* Length of the cookie used. */
+#define NOTIFY_WOKENUP 1 /* Code for notifcation. */
+#define NOTIFY_REMOVED 2 /* Code for closed message queue
+ of de-notifcation. */
+
+
+/* Data structure for the queued notification requests. */
+union notify_data
+{
+ struct
+ {
+ void (*fct) (union sigval); /* The function to run. */
+ union sigval param; /* The parameter to pass. */
+ pthread_attr_t *attr; /* Attributes to create the thread with. */
+ /* NB: on 64-bit machines the struct as a size of 24 bytes. Which means
+ byte 31 can still be used for returning the status. */
+ };
+ char raw[NOTIFY_COOKIE_LEN];
+};
+
+
+/* Keep track of the initialization. */
+static pthread_once_t once = PTHREAD_ONCE_INIT;
+
+
+/* The netlink socket. */
+static int netlink_socket = -1;
+
+
+/* Barrier used to make sure data passed to the new thread is not
+ resused by the parent. */
+static pthread_barrier_t notify_barrier;
+
+
+/* Modify the signal mask. We move this into a separate function so
+ that the stack space needed for sigset_t is not deducted from what
+ the thread can use. */
+static int
+__attribute__ ((noinline))
+change_sigmask (int how, sigset_t *oss)
+{
+ sigset_t ss;
+ sigfillset (&ss);
+ return pthread_sigmask (how, &ss, oss);
+}
+
+
+/* The function used for the notification. */
+static void *
+notification_function (void *arg)
+{
+ /* Copy the function and parameter so that the parent thread can go
+ on with its life. */
+ volatile union notify_data *data = (volatile union notify_data *) arg;
+ void (*fct) (union sigval) = data->fct;
+ union sigval param = data->param;
+
+ /* Let the parent go. */
+ (void) pthread_barrier_wait (&notify_barrier);
+
+ /* Make the thread detached. */
+ (void) pthread_detach (pthread_self ());
+
+ /* The parent thread has all signals blocked. This is probably a
+ bit surprising for this thread. So we unblock all of them. */
+ (void) change_sigmask (SIG_UNBLOCK, NULL);
+
+ /* Now run the user code. */
+ fct (param);
+
+ /* And we are done. */
+ return NULL;
+}
+
+
+/* Helper thread. */
+static void *
+helper_thread (void *arg)
+{
+ while (1)
+ {
+ union notify_data data;
+
+ ssize_t n = recv (netlink_socket, &data, sizeof (data),
+ MSG_NOSIGNAL | MSG_WAITALL);
+ if (n < NOTIFY_COOKIE_LEN)
+ continue;
+
+ if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_WOKENUP)
+ {
+ /* Just create the thread as instructed. There is no way to
+ report a problem with creating a thread. */
+ pthread_t th;
+ if (__builtin_expect (pthread_create (&th, data.attr,
+ notification_function, &data)
+ == 0, 0))
+ /* Since we passed a pointer to DATA to the new thread we have
+ to wait until it is done with it. */
+ (void) pthread_barrier_wait (&notify_barrier);
+ }
+ else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED)
+ /* The only state we keep is the copy of the thread attributes. */
+ free (data.attr);
+ }
+ return NULL;
+}
+
+
+static void
+reset_once (void)
+{
+ once = PTHREAD_ONCE_INIT;
+}
+
+
+static void
+init_mq_netlink (void)
+{
+ /* This code might be called a second time after fork(). The file
+ descriptor is inherited from the parent. */
+ if (netlink_socket == -1)
+ {
+ /* Just a normal netlink socket, not bound. */
+ netlink_socket = socket (AF_NETLINK, SOCK_RAW, 0);
+ /* No need to do more if we have no socket. */
+ if (netlink_socket == -1)
+ return;
+
+ /* Make sure the descriptor is closed on exec. */
+ if (fcntl (netlink_socket, F_SETFD, FD_CLOEXEC) != 0)
+ goto errout;
+ }
+
+ int err = 1;
+
+ /* Initialize the barrier. */
+ if (__builtin_expect (pthread_barrier_init (&notify_barrier, NULL, 2) == 0,
+ 0))
+ {
+ /* Create the helper thread. */
+ pthread_attr_t attr;
+ (void) pthread_attr_init (&attr);
+ (void) pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+ /* We do not need much stack space, the bare minimum will be enough. */
+ (void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+
+ /* Temporarily block all signals so that the newly created
+ thread inherits the mask. */
+ sigset_t oss;
+ int have_no_oss = change_sigmask (SIG_BLOCK, &oss);
+
+ pthread_t th;
+ err = pthread_create (&th, &attr, helper_thread, NULL);
+
+ /* Reset the signal mask. */
+ if (!have_no_oss)
+ pthread_sigmask (SIG_SETMASK, &oss, NULL);
+
+ (void) pthread_attr_destroy (&attr);
+
+ if (err == 0)
+ {
+ static int added_atfork;
+
+ if (added_atfork == 0
+ && pthread_atfork (NULL, NULL, reset_once) != 0)
+ {
+ /* The child thread will call recv() which is a
+ cancellation point. */
+ (void) pthread_cancel (th);
+ err = 1;
+ }
+ else
+ added_atfork = 1;
+ }
+ }
+
+ if (err != 0)
+ {
+ errout:
+ close_not_cancel_no_status (netlink_socket);
+ netlink_socket = -1;
+ }
+}
+
+
+/* Register notification upon message arrival to an empty message queue
+ MQDES. */
+int
+mq_notify (mqd_t mqdes, const struct sigevent *notification)
+{
+ /* Make sure the type is correctly defined. */
+ assert (sizeof (union notify_data) == NOTIFY_COOKIE_LEN);
+
+ /* Special treatment needed for SIGEV_THREAD. */
+ if (notification == NULL || notification->sigev_notify != SIGEV_THREAD)
+ return INLINE_SYSCALL (mq_notify, 2, mqdes, notification);
+
+ /* The kernel cannot directly start threads. This will have to be
+ done at userlevel. Since we cannot start threads from signal
+ handlers we have to create a dedicated thread which waits for
+ notifications for arriving messages and creates threads in
+ response. */
+
+ /* Initialize only once. */
+ pthread_once (&once, init_mq_netlink);
+
+ /* If we cannot create the netlink socket we cannot provide
+ SIGEV_THREAD support. */
+ if (__builtin_expect (netlink_socket == -1, 0))
+ {
+ __set_errno (ENOSYS);
+ return -1;
+ }
+
+ /* Create the cookie. It will hold almost all the state. */
+ union notify_data data;
+ memset (&data, '\0', sizeof (data));
+ data.fct = notification->sigev_notify_function;
+ data.param = notification->sigev_value;
+
+ if (notification->sigev_notify_attributes != NULL)
+ {
+ /* The thread attribute has to be allocated separately. */
+ data.attr = (pthread_attr_t *) malloc (sizeof (pthread_attr_t));
+ if (data.attr == NULL)
+ return -1;
+
+ memcpy (data.attr, notification->sigev_notify_attributes,
+ sizeof (pthread_attr_t));
+ }
+
+ /* Construct the new request. */
+ struct sigevent se;
+ se.sigev_notify = SIGEV_THREAD;
+ se.sigev_signo = netlink_socket;
+ se.sigev_value.sival_ptr = &data;
+
+ /* Tell the kernel. */
+ int retval = INLINE_SYSCALL (mq_notify, 2, mqdes, &se);
+
+ /* If it failed, free the allocated memory. */
+ if (__builtin_expect (retval != 0, 0))
+ free (data.attr);
+
+ return retval;
+}
+
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/msync.S b/libpthread/nptl/sysdeps/unix/sysv/linux/msync.S
new file mode 100644
index 000000000..074a0d717
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/msync.S
@@ -0,0 +1,7 @@
+#include <sysdep-cancel.h>
+PSEUDO (__libc_msync, msync, 3)
+ret
+PSEUDO_END(__libc_msync)
+libc_hidden_def (__libc_msync)
+weak_alias (__libc_msync, msync)
+libc_hidden_weak (msync)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nanosleep.S b/libpthread/nptl/sysdeps/unix/sysv/linux/nanosleep.S
new file mode 100644
index 000000000..71efe32f9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/nanosleep.S
@@ -0,0 +1,9 @@
+#include <sysdep-cancel.h>
+PSEUDO (__libc_nanosleep, nanosleep, 3)
+ret
+PSEUDO_END (__libc_nanosleep)
+libc_hidden_def (__libc_nanosleep)
+weak_alias (__libc_nanosleep, __nanosleep)
+libc_hidden_weak (__nanosleep)
+weak_alias (__libc_nanosleep, nanosleep)
+libc_hidden_weak (nanosleep)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h
new file mode 100644
index 000000000..80d33be29
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/not-cancel.h
@@ -0,0 +1,105 @@
+/* Uncancelable versions of cancelable interfaces. Linux version.
+ Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sys/types.h>
+#include <sysdep.h>
+
+/* Uncancelable open. */
+#define open_not_cancel(name, flags, mode) \
+ INLINE_SYSCALL (open, 3, (const char *) (name), (flags), (mode))
+#define open_not_cancel_2(name, flags) \
+ INLINE_SYSCALL (open, 2, (const char *) (name), (flags))
+
+/* Uncancelable openat. */
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+extern int __openat_nocancel (int fd, const char *fname, int oflag,
+ mode_t mode) attribute_hidden;
+extern int __openat64_nocancel (int fd, const char *fname, int oflag,
+ mode_t mode) attribute_hidden;
+#else
+# define __openat_nocancel(fd, fname, oflag, mode) \
+ openat (fd, fname, oflag, mode)
+# define __openat64_nocancel(fd, fname, oflag, mode) \
+ openat64 (fd, fname, oflag, mode)
+#endif
+
+#define openat_not_cancel(fd, fname, oflag, mode) \
+ __openat_nocancel (fd, fname, oflag, mode)
+#define openat_not_cancel_3(fd, fname, oflag) \
+ __openat_nocancel (fd, fname, oflag, 0)
+#define openat64_not_cancel(fd, fname, oflag, mode) \
+ __openat64_nocancel (fd, fname, oflag, mode)
+#define openat64_not_cancel_3(fd, fname, oflag) \
+ __openat64_nocancel (fd, fname, oflag, 0)
+
+/* Uncancelable close. */
+#define close_not_cancel(fd) \
+ INLINE_SYSCALL (close, 1, fd)
+#define close_not_cancel_no_status(fd) \
+ (void) ({ INTERNAL_SYSCALL_DECL (err); \
+ INTERNAL_SYSCALL (close, err, 1, (fd)); })
+
+/* Uncancelable read. */
+#define read_not_cancel(fd, buf, n) \
+ INLINE_SYSCALL (read, 3, (fd), (buf), (n))
+
+/* Uncancelable write. */
+#define write_not_cancel(fd, buf, n) \
+ INLINE_SYSCALL (write, 3, (fd), (buf), (n))
+
+/* Uncancelable writev. */
+#define writev_not_cancel_no_status(fd, iov, n) \
+ (void) ({ INTERNAL_SYSCALL_DECL (err); \
+ INTERNAL_SYSCALL (writev, err, 3, (fd), (iov), (n)); })
+
+/* Uncancelable fcntl. */
+#define fcntl_not_cancel(fd, cmd, val) \
+ __fcntl_nocancel (fd, cmd, val)
+
+/* Uncancelable waitpid. */
+#ifdef __NR_waitpid
+# define waitpid_not_cancel(pid, stat_loc, options) \
+ INLINE_SYSCALL (waitpid, 3, pid, stat_loc, options)
+#else
+# define waitpid_not_cancel(pid, stat_loc, options) \
+ INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL)
+#endif
+
+/* Uncancelable pause. */
+#ifdef __NR_pause
+# define pause_not_cancel() \
+ INLINE_SYSCALL (pause, 0)
+#else
+# define pause_not_cancel() \
+ __pause_nocancel ()
+#endif
+
+/* Uncancelable nanosleep. */
+#ifdef __NR_nanosleep
+# define nanosleep_not_cancel(requested_time, remaining) \
+ INLINE_SYSCALL (nanosleep, 2, requested_time, remaining)
+#else
+# define nanosleep_not_cancel(requested_time, remaining) \
+ __nanosleep_nocancel (requested_time, remaining)
+#endif
+
+/* Uncancelable sigsuspend. */
+#define sigsuspend_not_cancel(set) \
+ __sigsuspend_nocancel (set)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/open.S b/libpthread/nptl/sysdeps/unix/sysv/linux/open.S
new file mode 100644
index 000000000..486686a22
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/open.S
@@ -0,0 +1,21 @@
+#include <sysdep-cancel.h>
+
+/*
+extern int __open_nocancel (const char *, int, ...) attribute_hidden;
+*/
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+PSEUDO (__libc_open, open, 3)
+ret
+PSEUDO_END(__libc_open)
+
+libc_hidden_def (__open_nocancel)
+libc_hidden_def (__libc_open)
+weak_alias (__libc_open, __open)
+libc_hidden_weak (__open)
+weak_alias (__libc_open, open)
+libc_hidden_weak (open)
+
+
+
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pause.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pause.S
new file mode 100644
index 000000000..3841018a8
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pause.S
@@ -0,0 +1,7 @@
+#include <sysdep-cancel.h>
+PSEUDO (__libc_pause, pause, 0)
+ret
+PSEUDO_END (__libc_pause)
+libc_hidden_def (__libc_pause)
+weak_alias (__libc_pause, pause)
+libc_hidden_weak (pause)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile
new file mode 100644
index 000000000..e98c9bd86
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile
@@ -0,0 +1,2 @@
+# pull in __syscall_error routine
+libpthread-routines += sysdep
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
new file mode 100644
index 000000000..c0b59c336
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
@@ -0,0 +1,221 @@
+/* Machine-specific pthread type layouts. PowerPC version.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H 1
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+# define __SIZEOF_PTHREAD_ATTR_T 56
+# define __SIZEOF_PTHREAD_MUTEX_T 40
+# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+# define __SIZEOF_PTHREAD_COND_T 48
+# define __SIZEOF_PTHREAD_CONDATTR_T 4
+# define __SIZEOF_PTHREAD_RWLOCK_T 56
+# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+# define __SIZEOF_PTHREAD_BARRIER_T 32
+# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+#else
+# define __SIZEOF_PTHREAD_ATTR_T 36
+# define __SIZEOF_PTHREAD_MUTEX_T 24
+# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+# define __SIZEOF_PTHREAD_COND_T 48
+# define __SIZEOF_PTHREAD_CONDATTR_T 4
+# define __SIZEOF_PTHREAD_RWLOCK_T 32
+# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+# define __SIZEOF_PTHREAD_BARRIER_T 20
+# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+#endif
+
+
+/* Thread identifiers. The structure of the attribute type is
+ deliberately not exposed. */
+typedef unsigned long int pthread_t;
+
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_ATTR_T];
+ long int __align;
+} pthread_attr_t;
+
+
+#if __WORDSIZE == 64
+typedef struct __pthread_internal_list
+{
+ struct __pthread_internal_list *__prev;
+ struct __pthread_internal_list *__next;
+} __pthread_list_t;
+#else
+typedef struct __pthread_internal_slist
+{
+ struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+#endif
+
+
+/* Data structures for mutex handling. The structure of the attribute
+ type is deliberately not exposed. */
+typedef union
+{
+ struct __pthread_mutex_s
+ {
+ int __lock;
+ unsigned int __count;
+ int __owner;
+#if __WORDSIZE == 64
+ unsigned int __nusers;
+#endif
+ /* KIND must stay at this position in the structure to maintain
+ binary compatibility. */
+ int __kind;
+#if __WORDSIZE == 64
+ int __spins;
+ __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV 1
+#else
+ unsigned int __nusers;
+ __extension__ union
+ {
+ int __spins;
+ __pthread_slist_t __list;
+ };
+#endif
+ } __data;
+ char __size[__SIZEOF_PTHREAD_MUTEX_T];
+ long int __align;
+} pthread_mutex_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+ int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling. The structure of
+ the attribute type is deliberately not exposed. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned int __futex;
+ __extension__ unsigned long long int __total_seq;
+ __extension__ unsigned long long int __wakeup_seq;
+ __extension__ unsigned long long int __woken_seq;
+ void *__mutex;
+ unsigned int __nwaiters;
+ unsigned int __broadcast_seq;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_COND_T];
+ __extension__ long long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+ int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Data structure for read-write lock variable handling. The
+ structure of the attribute type is deliberately not exposed. */
+typedef union
+{
+# if __WORDSIZE == 64
+ struct
+ {
+ int __lock;
+ unsigned int __nr_readers;
+ unsigned int __readers_wakeup;
+ unsigned int __writer_wakeup;
+ unsigned int __nr_readers_queued;
+ unsigned int __nr_writers_queued;
+ int __writer;
+ int __shared;
+ unsigned long int __pad1;
+ unsigned long int __pad2;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned int __flags;
+ } __data;
+# else
+ struct
+ {
+ int __lock;
+ unsigned int __nr_readers;
+ unsigned int __readers_wakeup;
+ unsigned int __writer_wakeup;
+ unsigned int __nr_readers_queued;
+ unsigned int __nr_writers_queued;
+ unsigned char __pad1;
+ unsigned char __pad2;
+ unsigned char __shared;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned char __flags;
+ int __writer;
+ } __data;
+# endif
+ char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+ long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+ long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type. */
+typedef volatile int pthread_spinlock_t;
+
+
+/* POSIX barriers data type. The structure of the type is
+ deliberately not exposed. */
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIER_T];
+ long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+ int __align;
+} pthread_barrierattr_t;
+#endif
+
+
+#endif /* bits/pthreadtypes.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h
new file mode 100644
index 000000000..c7f121ba5
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/bits/semaphore.h
@@ -0,0 +1,41 @@
+/* Machine-specific POSIX semaphore type layouts. PowerPC version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+# define __SIZEOF_SEM_T 32
+#else
+# define __SIZEOF_SEM_T 16
+#endif
+
+/* Value returned if `sem_open' failed. */
+#define SEM_FAILED ((sem_t *) 0)
+
+
+typedef union
+{
+ char __size[__SIZEOF_SEM_T];
+ long int __align;
+} sem_t;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c
new file mode 100644
index 000000000..e811ad74e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c
@@ -0,0 +1,25 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Value passed to 'clone' for initialization of the thread register. */
+#define TLS_VALUE ((void *) (pd) \
+ + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE)
+
+/* Get the real implementation. */
+#include <nptl/sysdeps/pthread/createthread.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/fork.c
new file mode 100644
index 000000000..06b7e1c69
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/fork.c
@@ -0,0 +1 @@
+#include "../i386/fork.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
new file mode 100644
index 000000000..66c02cbbd
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
@@ -0,0 +1,314 @@
+/* Copyright (C) 2003, 2004, 2006-2008, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H 1
+
+#include <time.h>
+#include <sys/param.h>
+#include <bits/pthreadtypes.h>
+#include <atomic.h>
+#include <kernel-features.h>
+
+#ifndef __NR_futex
+# define __NR_futex 221
+#endif
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_REQUEUE 3
+#define FUTEX_CMP_REQUEUE 4
+#define FUTEX_WAKE_OP 5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_WAIT_BITSET 9
+#define FUTEX_WAKE_BITSET 10
+#define FUTEX_PRIVATE_FLAG 128
+#define FUTEX_CLOCK_REALTIME 256
+
+#define FUTEX_BITSET_MATCH_ANY 0xffffffff
+
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
+ & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
+#define lll_futex_wait(futexp, val, private) \
+ lll_futex_timed_wait (futexp, val, NULL, private)
+
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAIT, private), \
+ (val), (timespec)); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
+ })
+
+#define lll_futex_wake(futexp, nr, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAKE, private), \
+ (nr), 0); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
+ })
+
+#define lll_robust_dead(futexv, private) \
+ do \
+ { \
+ INTERNAL_SYSCALL_DECL (__err); \
+ int *__futexp = &(futexv); \
+ \
+ atomic_or (__futexp, FUTEX_OWNER_DIED); \
+ INTERNAL_SYSCALL (futex, __err, 4, __futexp, \
+ __lll_private_flag (FUTEX_WAKE, private), 1, 0); \
+ } \
+ while (0)
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+ (nr_wake), (nr_move), (mutex), (val)); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_WAKE_OP, private), \
+ (nr_wake), (nr_wake2), (futexp2), \
+ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+
+#ifdef UP
+# define __lll_acq_instr ""
+# define __lll_rel_instr ""
+#else
+# define __lll_acq_instr "isync"
+# ifdef _ARCH_PWR4
+/*
+ * Newer powerpc64 processors support the new "light weight" sync (lwsync)
+ * So if the build is using -mcpu=[power4,power5,power5+,970] we can
+ * safely use lwsync.
+ */
+# define __lll_rel_instr "lwsync"
+# else
+/*
+ * Older powerpc32 processors don't support the new "light weight"
+ * sync (lwsync). So the only safe option is to use normal sync
+ * for all powerpc32 applications.
+ */
+# define __lll_rel_instr "sync"
+# endif
+#endif
+
+/* Set *futex to ID if it is 0, atomically. Returns the old value */
+#define __lll_robust_trylock(futex, id) \
+ ({ int __val; \
+ __asm __volatile ("1: lwarx %0,0,%2" MUTEX_HINT_ACQ "\n" \
+ " cmpwi 0,%0,0\n" \
+ " bne 2f\n" \
+ " stwcx. %3,0,%2\n" \
+ " bne- 1b\n" \
+ "2: " __lll_acq_instr \
+ : "=&r" (__val), "=m" (*futex) \
+ : "r" (futex), "r" (id), "m" (*futex) \
+ : "cr0", "memory"); \
+ __val; \
+ })
+
+#define lll_robust_trylock(lock, id) __lll_robust_trylock (&(lock), id)
+
+/* Set *futex to 1 if it is 0, atomically. Returns the old value */
+#define __lll_trylock(futex) __lll_robust_trylock (futex, 1)
+
+#define lll_trylock(lock) __lll_trylock (&(lock))
+
+/* Set *futex to 2 if it is 0, atomically. Returns the old value */
+#define __lll_cond_trylock(futex) __lll_robust_trylock (futex, 2)
+
+#define lll_cond_trylock(lock) __lll_cond_trylock (&(lock))
+
+
+extern void __lll_lock_wait_private (int *futex) attribute_hidden;
+extern void __lll_lock_wait (int *futex, int private) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden;
+
+#define lll_lock(lock, private) \
+ (void) ({ \
+ int *__futex = &(lock); \
+ if (__builtin_expect (atomic_compare_and_exchange_val_acq (__futex, 1, 0),\
+ 0) != 0) \
+ { \
+ if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \
+ __lll_lock_wait_private (__futex); \
+ else \
+ __lll_lock_wait (__futex, private); \
+ } \
+ })
+
+#define lll_robust_lock(lock, id, private) \
+ ({ \
+ int *__futex = &(lock); \
+ int __val = 0; \
+ if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id, \
+ 0), 0)) \
+ __val = __lll_robust_lock_wait (__futex, private); \
+ __val; \
+ })
+
+#define lll_cond_lock(lock, private) \
+ (void) ({ \
+ int *__futex = &(lock); \
+ if (__builtin_expect (atomic_compare_and_exchange_val_acq (__futex, 2, 0),\
+ 0) != 0) \
+ __lll_lock_wait (__futex, private); \
+ })
+
+#define lll_robust_cond_lock(lock, id, private) \
+ ({ \
+ int *__futex = &(lock); \
+ int __val = 0; \
+ int __id = id | FUTEX_WAITERS; \
+ if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, __id,\
+ 0), 0)) \
+ __val = __lll_robust_lock_wait (__futex, private); \
+ __val; \
+ })
+
+
+extern int __lll_timedlock_wait
+ (int *futex, const struct timespec *, int private) attribute_hidden;
+extern int __lll_robust_timedlock_wait
+ (int *futex, const struct timespec *, int private) attribute_hidden;
+
+#define lll_timedlock(lock, abstime, private) \
+ ({ \
+ int *__futex = &(lock); \
+ int __val = 0; \
+ if (__builtin_expect (atomic_compare_and_exchange_val_acq (__futex, 1, 0),\
+ 0) != 0) \
+ __val = __lll_timedlock_wait (__futex, abstime, private); \
+ __val; \
+ })
+
+#define lll_robust_timedlock(lock, abstime, id, private) \
+ ({ \
+ int *__futex = &(lock); \
+ int __val = 0; \
+ if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id, \
+ 0), 0)) \
+ __val = __lll_robust_timedlock_wait (__futex, abstime, private); \
+ __val; \
+ })
+
+#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); \
+ }))
+
+#define lll_robust_unlock(lock, private) \
+ ((void) ({ \
+ int *__futex = &(lock); \
+ int __val = atomic_exchange_rel (__futex, 0); \
+ if (__builtin_expect (__val & FUTEX_WAITERS, 0)) \
+ lll_futex_wake (__futex, 1, private); \
+ }))
+
+#define lll_islocked(futex) \
+ (futex != 0)
+
+
+/* Initializers for lock. */
+#define LLL_LOCK_INITIALIZER (0)
+#define LLL_LOCK_INITIALIZER_LOCKED (1)
+
+/* The states of a lock are:
+ 0 - untaken
+ 1 - taken by one user
+ >1 - taken by more users */
+
+/* The kernel notifies a process which uses CLONE_CLEARTID via futex
+ wakeup when the clone terminates. The memory location contains the
+ thread ID while the clone is running and is reset to zero
+ afterwards. */
+#define lll_wait_tid(tid) \
+ do { \
+ __typeof (tid) __tid; \
+ while ((__tid = (tid)) != 0) \
+ lll_futex_wait (&(tid), __tid, LLL_SHARED); \
+ } while (0)
+
+extern int __lll_timedwait_tid (int *, const struct timespec *)
+ attribute_hidden;
+
+#define lll_timedwait_tid(tid, abstime) \
+ ({ \
+ int __res = 0; \
+ if ((tid) != 0) \
+ __res = __lll_timedwait_tid (&(tid), (abstime)); \
+ __res; \
+ })
+
+#endif /* lowlevellock.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/not-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/not-cancel.h
new file mode 100644
index 000000000..acf1a617e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/not-cancel.h
@@ -0,0 +1 @@
+#include "../i386/not-cancel.h"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
new file mode 100644
index 000000000..675a997e9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
@@ -0,0 +1,9 @@
+/* We want an #include_next, but we are the main source file.
+ So, #include ourselves and in that incarnation we can use #include_next. */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/pt-vfork.S
new file mode 100644
index 000000000..61651fd97
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/pt-vfork.S
@@ -0,0 +1,49 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+ lwz 0,PID(2)
+ neg 0,0
+ stw 0,PID(2)
+
+ DO_CALL (SYS_ify (vfork))
+
+ cmpwi 1,3,0
+ beqlr- 1
+
+ lwz 0,PID(2)
+ neg 0,0
+ stw 0,PID(2)
+
+ PSEUDO_RET
+
+PSEUDO_END (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
new file mode 100644
index 000000000..88b24e7d9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
@@ -0,0 +1,119 @@
+/* Cancellable system call stubs. Linux/PowerPC version.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <nptl/pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .section ".text"; \
+ ENTRY (name) \
+ SINGLE_THREAD_P; \
+ bne- .Lpseudo_cancel; \
+ .type __##syscall_name##_nocancel,@function; \
+ .globl __##syscall_name##_nocancel; \
+ __##syscall_name##_nocancel: \
+ DO_CALL (SYS_ify (syscall_name)); \
+ PSEUDO_RET; \
+ .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
+ .Lpseudo_cancel: \
+ stwu 1,-48(1); \
+ cfi_adjust_cfa_offset (48); \
+ mflr 9; \
+ stw 9,52(1); \
+ cfi_offset (lr, 4); \
+ DOCARGS_##args; /* save syscall args around CENABLE. */ \
+ CENABLE; \
+ stw 3,16(1); /* store CENABLE return value (MASK). */ \
+ UNDOCARGS_##args; /* restore syscall args. */ \
+ DO_CALL (SYS_ify (syscall_name)); \
+ mfcr 0; /* save CR/R3 around CDISABLE. */ \
+ stw 3,8(1); \
+ stw 0,12(1); \
+ lwz 3,16(1); /* pass MASK to CDISABLE. */ \
+ CDISABLE; \
+ lwz 4,52(1); \
+ lwz 0,12(1); /* restore CR/R3. */ \
+ lwz 3,8(1); \
+ mtlr 4; \
+ mtcr 0; \
+ addi 1,1,48;
+
+# define DOCARGS_0
+# define UNDOCARGS_0
+
+# define DOCARGS_1 stw 3,20(1); DOCARGS_0
+# define UNDOCARGS_1 lwz 3,20(1); UNDOCARGS_0
+
+# define DOCARGS_2 stw 4,24(1); DOCARGS_1
+# define UNDOCARGS_2 lwz 4,24(1); UNDOCARGS_1
+
+# define DOCARGS_3 stw 5,28(1); DOCARGS_2
+# define UNDOCARGS_3 lwz 5,28(1); UNDOCARGS_2
+
+# define DOCARGS_4 stw 6,32(1); DOCARGS_3
+# define UNDOCARGS_4 lwz 6,32(1); UNDOCARGS_3
+
+# define DOCARGS_5 stw 7,36(1); DOCARGS_4
+# define UNDOCARGS_5 lwz 7,36(1); UNDOCARGS_4
+
+# define DOCARGS_6 stw 8,40(1); DOCARGS_5
+# define UNDOCARGS_6 lwz 8,40(1); UNDOCARGS_5
+
+# ifdef IS_IN_libpthread
+# define CENABLE bl __pthread_enable_asynccancel@local
+# define CDISABLE bl __pthread_disable_asynccancel@local
+# elif !defined NOT_IN_libc
+# define CENABLE bl __libc_enable_asynccancel@local
+# define CDISABLE bl __libc_disable_asynccancel@local
+# elif defined IS_IN_librt
+# define CENABLE bl __librt_enable_asynccancel@local
+# define CDISABLE bl __librt_disable_asynccancel@local
+# else
+# error Unsupported library
+# endif
+
+# ifndef __ASSEMBLER__
+# define SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+# else
+# define SINGLE_THREAD_P \
+ lwz 10,MULTIPLE_THREADS_OFFSET(2); \
+ cmpwi 10,0
+# endif
+
+#elif !defined __ASSEMBLER__
+
+# define SINGLE_THREAD_P (1)
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S
new file mode 100644
index 000000000..eed2a8f1a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S
@@ -0,0 +1,57 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+ lwz 0,PID(2)
+ cmpwi 0,0,0
+ neg 0,0
+ bne- 0,1f
+ lis 0,0x8000
+1: stw 0,PID(2)
+
+ DO_CALL (SYS_ify (vfork))
+
+ cmpwi 1,3,0
+ beqlr- 1
+
+ lwz 0,PID(2)
+ /* Cannot use clrlwi. here, because cr0 needs to be preserved
+ until PSEUDO_RET. */
+ clrlwi 4,0,1
+ cmpwi 1,4,0
+ beq- 1,1f
+ neg 4,0
+1: stw 4,PID(2)
+
+ PSEUDO_RET
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+weak_alias (__vfork, vfork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
new file mode 100644
index 000000000..675a997e9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
@@ -0,0 +1,9 @@
+/* We want an #include_next, but we are the main source file.
+ So, #include ourselves and in that incarnation we can use #include_next. */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/pt-vfork.S
new file mode 100644
index 000000000..e5b7b535c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/pt-vfork.S
@@ -0,0 +1,49 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+ lwz 0,PID(13)
+ neg 0,0
+ stw 0,PID(13)
+
+ DO_CALL (SYS_ify (vfork))
+
+ cmpwi 1,3,0
+ beqlr- 1
+
+ lwz 0,PID(13)
+ neg 0,0
+ stw 0,PID(13)
+
+ PSEUDO_RET
+
+PSEUDO_END (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
new file mode 100644
index 000000000..707765ab5
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
@@ -0,0 +1,125 @@
+/* Cancellable system call stubs. Linux/PowerPC64 version.
+ Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <nptl/pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# ifdef HAVE_ASM_GLOBAL_DOT_NAME
+# define DASHDASHPFX(str) .__##str
+# else
+# define DASHDASHPFX(str) __##str
+# endif
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .section ".text"; \
+ ENTRY (name) \
+ SINGLE_THREAD_P; \
+ bne- .Lpseudo_cancel; \
+ .type DASHDASHPFX(syscall_name##_nocancel),@function; \
+ .globl DASHDASHPFX(syscall_name##_nocancel); \
+ DASHDASHPFX(syscall_name##_nocancel): \
+ DO_CALL (SYS_ify (syscall_name)); \
+ PSEUDO_RET; \
+ .size DASHDASHPFX(syscall_name##_nocancel),.-DASHDASHPFX(syscall_name##_nocancel); \
+ .Lpseudo_cancel: \
+ stdu 1,-128(1); \
+ cfi_adjust_cfa_offset (128); \
+ mflr 9; \
+ std 9,128+16(1); \
+ cfi_offset (lr, 16); \
+ DOCARGS_##args; /* save syscall args around CENABLE. */ \
+ CENABLE; \
+ std 3,72(1); /* store CENABLE return value (MASK). */ \
+ UNDOCARGS_##args; /* restore syscall args. */ \
+ DO_CALL (SYS_ify (syscall_name)); \
+ mfcr 0; /* save CR/R3 around CDISABLE. */ \
+ std 3,64(1); \
+ std 0,8(1); \
+ ld 3,72(1); /* pass MASK to CDISABLE. */ \
+ CDISABLE; \
+ ld 9,128+16(1); \
+ ld 0,8(1); /* restore CR/R3. */ \
+ ld 3,64(1); \
+ mtlr 9; \
+ mtcr 0; \
+ addi 1,1,128;
+
+# define DOCARGS_0
+# define UNDOCARGS_0
+
+# define DOCARGS_1 std 3,80(1); DOCARGS_0
+# define UNDOCARGS_1 ld 3,80(1); UNDOCARGS_0
+
+# define DOCARGS_2 std 4,88(1); DOCARGS_1
+# define UNDOCARGS_2 ld 4,88(1); UNDOCARGS_1
+
+# define DOCARGS_3 std 5,96(1); DOCARGS_2
+# define UNDOCARGS_3 ld 5,96(1); UNDOCARGS_2
+
+# define DOCARGS_4 std 6,104(1); DOCARGS_3
+# define UNDOCARGS_4 ld 6,104(1); UNDOCARGS_3
+
+# define DOCARGS_5 std 7,112(1); DOCARGS_4
+# define UNDOCARGS_5 ld 7,112(1); UNDOCARGS_4
+
+# define DOCARGS_6 std 8,120(1); DOCARGS_5
+# define UNDOCARGS_6 ld 8,120(1); UNDOCARGS_5
+
+# ifdef IS_IN_libpthread
+# define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel)
+# define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel)
+# elif !defined NOT_IN_libc
+# define CENABLE bl JUMPTARGET(__libc_enable_asynccancel)
+# define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel)
+# elif defined IS_IN_librt
+# define CENABLE bl JUMPTARGET(__librt_enable_asynccancel)
+# define CDISABLE bl JUMPTARGET(__librt_disable_asynccancel)
+# else
+# error Unsupported library
+# endif
+
+# ifndef __ASSEMBLER__
+# define SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+# else
+# define SINGLE_THREAD_P \
+ lwz 10,MULTIPLE_THREADS_OFFSET(13); \
+ cmpwi 10,0
+# endif
+
+#elif !defined __ASSEMBLER__
+
+# define SINGLE_THREAD_P (1)
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_create.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_create.c
new file mode 100644
index 000000000..172223af3
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_create.c
@@ -0,0 +1 @@
+#include "../x86_64/timer_create.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_delete.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_delete.c
new file mode 100644
index 000000000..537516e0a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_delete.c
@@ -0,0 +1 @@
+#include "../x86_64/timer_delete.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_getoverr.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_getoverr.c
new file mode 100644
index 000000000..3f21a73c9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_getoverr.c
@@ -0,0 +1 @@
+#include "../x86_64/timer_getoverr.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_gettime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_gettime.c
new file mode 100644
index 000000000..a50143adc
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_gettime.c
@@ -0,0 +1 @@
+#include "../x86_64/timer_gettime.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_settime.c
new file mode 100644
index 000000000..37baeffac
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/timer_settime.c
@@ -0,0 +1 @@
+#include "../x86_64/timer_settime.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S
new file mode 100644
index 000000000..26885bb95
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S
@@ -0,0 +1,55 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+ lwz 0,PID(13)
+ cmpwi 0,0,0
+ neg 0,0
+ bne- 0,1f
+ lis 0,0x8000
+1: stw 0,PID(13)
+
+ DO_CALL (SYS_ify (vfork))
+
+ cmpwi 1,3,0
+ beqlr- 1
+
+ lwz 0,PID(13)
+ clrlwi 4,0,1
+ cmpwi 1,4,0
+ beq- 1,1f
+ neg 4,0
+1: stw 4,PID(13)
+
+ PSEUDO_RET
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+weak_alias (__vfork, vfork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c
new file mode 100644
index 000000000..b6d6b3d55
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <setjmp.h>
+#include <stdlib.h>
+#include <bits/wordsize.h>
+#include "pthreadP.h"
+
+void
+__vmx_longjmp (jmp_buf env, int val)
+{
+ __libc_longjmp (env, val);
+}
+
+void
+__vmx_siglongjmp (jmp_buf env, int val)
+{
+ __libc_siglongjmp (env, val);
+}
+weak_alias(__vmx_longjmp, longjmp)
+weak_alias(__vmx_siglongjmp, siglongjmp)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
new file mode 100644
index 000000000..bc5f3f0f1
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
@@ -0,0 +1,101 @@
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+unsigned long int __fork_generation attribute_hidden;
+
+
+static void
+clear_once_control (void *arg)
+{
+ pthread_once_t *once_control = (pthread_once_t *) arg;
+
+ *once_control = 0;
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+}
+
+
+int
+attribute_protected
+__pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+{
+ for (;;)
+ {
+ int oldval;
+ int newval;
+ int tmp;
+
+ /* Pseudo code:
+ newval = __fork_generation | 1;
+ oldval = *once_control;
+ if ((oldval & 2) == 0)
+ *once_control = newval;
+ Do this atomically.
+ */
+ newval = __fork_generation | 1;
+ __asm __volatile ("1: lwarx %0,0,%3\n"
+ " andi. %1,%0,2\n"
+ " bne 2f\n"
+ " stwcx. %4,0,%3\n"
+ " bne 1b\n"
+ "2: isync"
+ : "=&r" (oldval), "=&r" (tmp), "=m" (*once_control)
+ : "r" (once_control), "r" (newval), "m" (*once_control)
+ : "cr0");
+
+ /* Check if the initializer has already been done. */
+ if ((oldval & 2) != 0)
+ return 0;
+
+ /* Check if another thread already runs the initializer. */
+ if ((oldval & 1) == 0)
+ break;
+
+ /* Check whether the initializer execution was interrupted by a fork. */
+ if (oldval != newval)
+ break;
+
+ /* Same generation, some other thread was faster. Wait. */
+ lll_futex_wait (once_control, oldval, LLL_PRIVATE);
+ }
+
+
+ /* This thread is the first here. Do the initialization.
+ Register a cleanup handler so that in case the thread gets
+ interrupted the initialization can be restarted. */
+ pthread_cleanup_push (clear_once_control, once_control);
+
+ init_routine ();
+
+ pthread_cleanup_pop (0);
+
+
+ /* Add one to *once_control to take the bottom 2 bits from 01 to 10. */
+ atomic_increment (once_control);
+
+ /* Wake up all other threads. */
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+
+ return 0;
+}
+weak_alias (__pthread_once, pthread_once)
+strong_alias (__pthread_once, __pthread_once_internal)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c
new file mode 100644
index 000000000..90f2dc67c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c
@@ -0,0 +1,29 @@
+/* pthread_spin_unlock -- unlock a spin lock. PowerPC version.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+int
+pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+ __asm __volatile (__lll_rel_instr ::: "memory");
+ *lock = 0;
+ return 0;
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c
new file mode 100644
index 000000000..0082c570a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c
@@ -0,0 +1,47 @@
+/* sem_post -- post to a POSIX semaphore. Powerpc version.
+ Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+
+int
+__new_sem_post (sem_t *sem)
+{
+ struct new_sem *isem = (struct new_sem *) sem;
+
+ __asm __volatile (__lll_rel_instr ::: "memory");
+ atomic_increment (&isem->value);
+ __asm __volatile (__lll_acq_instr ::: "memory");
+ if (isem->nwaiters > 0)
+ {
+ int err = lll_futex_wake (&isem->value, 1,
+ isem->private ^ FUTEX_PRIVATE_FLAG);
+ if (__builtin_expect (err, 0) < 0)
+ {
+ __set_errno (-err);
+ return -1;
+ }
+ }
+ return 0;
+}
+weak_alias(__new_sem_post, sem_post)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-accept.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-accept.S
new file mode 100644
index 000000000..24062101d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-accept.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_accept
+#error Missing definition of NR_accept needed for cancellation.
+#endif
+PSEUDO (__libc_accept, accept, 3)
+ret
+PSEUDO_END(__libc_accept)
+libpthread_hidden_def (__libc_accept)
+weak_alias (__libc_accept, __accept)
+libpthread_hidden_weak (__accept)
+weak_alias (__libc_accept, accept)
+libpthread_hidden_weak (accept)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-close.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-close.S
new file mode 100644
index 000000000..ab32ca598
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-close.S
@@ -0,0 +1,9 @@
+#include <sysdep-cancel.h>
+PSEUDO (__libc_close, close, 1)
+ret
+PSEUDO_END (__libc_close)
+libpthread_hidden_def (__libc_close)
+weak_alias (__libc_close, __close)
+libpthread_hidden_weak (__close)
+weak_alias (__libc_close, close)
+libpthread_hidden_weak (close)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-connect.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-connect.S
new file mode 100644
index 000000000..b5124f8ec
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-connect.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_connect
+#error Missing definition of NR_connect needed for cancellation.
+#endif
+PSEUDO (__libc_connect, connect, 3)
+ret
+PSEUDO_END(__libc_connect)
+libpthread_hidden_def (__libc_connect)
+weak_alias (__libc_connect, __connect)
+libpthread_hidden_weak (__connect)
+weak_alias (__libc_connect, connect)
+libpthread_hidden_weak (connect)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-fcntl.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-fcntl.c
new file mode 100644
index 000000000..0a8fd3cc2
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-fcntl.c
@@ -0,0 +1 @@
+#include <../../../../../../libc/sysdeps/linux/common/__syscall_fcntl.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-fork.c
new file mode 100644
index 000000000..3e1b70f86
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-fork.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unistd.h>
+
+extern int __libc_fork (void);
+
+pid_t
+__fork (void)
+{
+ return __libc_fork ();
+}
+strong_alias (__fork, fork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-fsync.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-fsync.c
new file mode 100644
index 000000000..6ec4821c7
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-fsync.c
@@ -0,0 +1,2 @@
+#include <pthreadP.h>
+#include <../../../../../../libc/sysdeps/linux/common/fsync.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-llseek.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-llseek.c
new file mode 100644
index 000000000..1d0d57870
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-llseek.c
@@ -0,0 +1,3 @@
+#include <pthreadP.h>
+#define libc_hidden libpthread_hidden
+#include <../../../../../../libc/sysdeps/linux/common/llseek.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-lseek.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-lseek.S
new file mode 100644
index 000000000..4db71722a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-lseek.S
@@ -0,0 +1,7 @@
+#include <sysdep-cancel.h>
+PSEUDO (__libc_lseek, lseek, 3)
+ret
+PSEUDO_END (__libc_lseek)
+libpthread_hidden_def (__libc_lseek)
+weak_alias (__libc_lseek, lseek)
+libpthread_hidden_weak (lseek)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-msgrcv.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-msgrcv.c
new file mode 100644
index 000000000..3bb9d53df
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-msgrcv.c
@@ -0,0 +1,2 @@
+#define L_msgrcv
+#include <../../../../../../libc/misc/sysvipc/msgq.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-msgsnd.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-msgsnd.c
new file mode 100644
index 000000000..1566f65f4
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-msgsnd.c
@@ -0,0 +1,2 @@
+#define L_msgsnd
+#include <../../../../../../libc/misc/sysvipc/msgq.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-msync.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-msync.S
new file mode 100644
index 000000000..640270ad9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-msync.S
@@ -0,0 +1,7 @@
+#include <sysdep-cancel.h>
+PSEUDO (__libc_msync, msync, 3)
+ret
+PSEUDO_END(__libc_msync)
+libpthread_hidden_def (__libc_msync)
+weak_alias (__libc_msync, msync)
+libpthread_hidden_weak (msync)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-nanosleep.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-nanosleep.S
new file mode 100644
index 000000000..08d8f0150
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-nanosleep.S
@@ -0,0 +1,9 @@
+#include <sysdep-cancel.h>
+PSEUDO (__libc_nanosleep, nanosleep, 3)
+ret
+PSEUDO_END (__libc_nanosleep)
+libpthread_hidden_def (__libc_nanosleep)
+weak_alias (__libc_nanosleep, __nanosleep)
+libpthread_hidden_weak (__nanosleep)
+weak_alias (__libc_nanosleep, nanosleep)
+libpthread_hidden_weak (nanosleep)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-open.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-open.S
new file mode 100644
index 000000000..39ed92cc7
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-open.S
@@ -0,0 +1,9 @@
+#include <sysdep-cancel.h>
+PSEUDO (__libc_open, open, 3)
+ret
+PSEUDO_END (__libc_open)
+libpthread_hidden_def (__libc_open)
+weak_alias (__libc_open, __open)
+libpthread_hidden_weak (__open)
+weak_alias (__libc_open, open)
+libpthread_hidden_weak (open)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-open64.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-open64.c
new file mode 100644
index 000000000..2029539a7
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-open64.c
@@ -0,0 +1 @@
+#include <../../../../../../libc/sysdeps/linux/common/open64.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-pause.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-pause.S
new file mode 100644
index 000000000..c6cb57180
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-pause.S
@@ -0,0 +1,7 @@
+#include <sysdep-cancel.h>
+PSEUDO (__libc_pause, pause, 0)
+ret
+PSEUDO_END (__libc_pause)
+libpthread_hidden_def (__libc_pause)
+weak_alias (__libc_pause, pause)
+libpthread_hidden_weak (pause)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-pread_pwrite.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-pread_pwrite.c
new file mode 100644
index 000000000..f32c0a670
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-pread_pwrite.c
@@ -0,0 +1 @@
+#include "pread_write.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-raise.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-raise.c
new file mode 100644
index 000000000..d256ebcb0
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-raise.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+#include <bits/kernel-features.h>
+
+
+int
+raise (
+ int sig)
+{
+#if __ASSUME_TGKILL || defined __NR_tgkill
+ /* raise is an async-safe function. It could be called while the
+ fork function temporarily invalidated the PID field. Adjust for
+ that. */
+ pid_t pid = THREAD_GETMEM (THREAD_SELF, pid);
+ if (__builtin_expect (pid < 0, 0))
+ pid = -pid;
+#endif
+
+#if __ASSUME_TGKILL
+ return INLINE_SYSCALL (tgkill, 3, pid, THREAD_GETMEM (THREAD_SELF, tid),
+ sig);
+#else
+# ifdef __NR_tgkill
+ int res = INLINE_SYSCALL (tgkill, 3, pid, THREAD_GETMEM (THREAD_SELF, tid),
+ sig);
+ if (res != -1 || errno != ENOSYS)
+ return res;
+# endif
+ return INLINE_SYSCALL (tkill, 2, THREAD_GETMEM (THREAD_SELF, tid), sig);
+#endif
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-read.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-read.S
new file mode 100644
index 000000000..623ba27a8
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-read.S
@@ -0,0 +1,9 @@
+#include <sysdep-cancel.h>
+PSEUDO (__libc_read, read, 3)
+ret
+PSEUDO_END (__libc_read)
+libpthread_hidden_def (__libc_read)
+weak_alias (__libc_read, __read)
+libpthread_hidden_weak (__read)
+weak_alias (__libc_read, read)
+libpthread_hidden_weak (read)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-recv.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-recv.S
new file mode 100644
index 000000000..6d2e3c2d6
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-recv.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_recv
+#error Missing definition of NR_recv needed for cancellation.
+#endif
+PSEUDO (__libc_recv, recv, 4)
+ret
+PSEUDO_END(__libc_recv)
+libpthread_hidden_def (__libc_recv)
+weak_alias (__libc_recv, __recv)
+libpthread_hidden_weak (__recv)
+weak_alias (__libc_recv, recv)
+libpthread_hidden_weak (recv)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-recvfrom.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-recvfrom.S
new file mode 100644
index 000000000..96aeeaa3d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-recvfrom.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_recvfrom
+#error Missing definition of NR_recvfrom needed for cancellation.
+#endif
+PSEUDO (__libc_recvfrom, recvfrom, 6)
+ret
+PSEUDO_END(__libc_recvfrom)
+libpthread_hidden_def (__libc_recvfrom)
+weak_alias (__libc_recvfrom, __recvfrom)
+libpthread_hidden_weak (__recvfrom)
+weak_alias (__libc_recvfrom, recvfrom)
+libpthread_hidden_weak (recvfrom)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-recvmsg.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-recvmsg.S
new file mode 100644
index 000000000..f7161e47c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-recvmsg.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_recvmsg
+#error Missing definition of NR_recvmsg needed for cancellation.
+#endif
+PSEUDO (__libc_recvmsg, recvmsg, 3)
+ret
+PSEUDO_END(__libc_recvmsg)
+libpthread_hidden_def (__libc_recvmsg)
+weak_alias (__libc_recvmsg, __recvmsg)
+libpthread_hidden_weak (__recvmsg)
+weak_alias (__libc_recvmsg, recvmsg)
+libpthread_hidden_weak (recvmsg)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-send.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-send.S
new file mode 100644
index 000000000..76bed39ec
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-send.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_send
+#error Missing definition of NR_send needed for cancellation.
+#endif
+PSEUDO (__libc_send, send, 4)
+ret
+PSEUDO_END (__libc_send)
+libpthread_hidden_def (__libc_send)
+weak_alias (__libc_send, __send)
+libpthread_hidden_weak (__send)
+weak_alias (__libc_send, send)
+libpthread_hidden_weak (send)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-sendmsg.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-sendmsg.S
new file mode 100644
index 000000000..d17096eae
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-sendmsg.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_sendmsg
+#error Missing definition of NR_sendmsg needed for cancellation.
+#endif
+PSEUDO (__libc_sendmsg, sendmsg, 3)
+ret
+PSEUDO_END(__libc_sendmsg)
+libpthread_hidden_def (__libc_sendmsg)
+weak_alias (__libc_sendmsg, __sendmsg)
+libpthread_hidden_weak (__sendmsg)
+weak_alias (__libc_sendmsg, sendmsg)
+libpthread_hidden_weak (sendmsg)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-sendto.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-sendto.S
new file mode 100644
index 000000000..d07a71f8a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-sendto.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_sendto
+#error Missing definition of NR_sendto needed for cancellation.
+#endif
+PSEUDO (__libc_sendto, sendto, 6)
+ret
+PSEUDO_END(__libc_sendto)
+libpthread_hidden_def (__libc_sendto)
+weak_alias (__libc_sendto, __sendto)
+libpthread_hidden_weak (__sendto)
+weak_alias (__libc_sendto, sendto)
+libpthread_hidden_weak (sendto)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-sigwait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-sigwait.c
new file mode 100644
index 000000000..bde0a9292
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-sigwait.c
@@ -0,0 +1,2 @@
+#include <pthreadP.h>
+#include "../../../../../../libc/signal/sigwait.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-sleep.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-sleep.c
new file mode 100644
index 000000000..9e948adce
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-sleep.c
@@ -0,0 +1,2 @@
+#include <pthreadP.h>
+#include <../../../../../../libc/unistd/sleep.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-tcdrain.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-tcdrain.c
new file mode 100644
index 000000000..07c1f8233
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-tcdrain.c
@@ -0,0 +1 @@
+#include <../../../../../../libc/termios/tcdrain.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-wait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-wait.c
new file mode 100644
index 000000000..a05c3eb49
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-wait.c
@@ -0,0 +1,2 @@
+#include <pthreadP.h>
+#include <../../../../../../libc/sysdeps/linux/common/wait.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-waitpid.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-waitpid.c
new file mode 100644
index 000000000..8461c3ff2
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-waitpid.c
@@ -0,0 +1 @@
+#include <../../../../../../libc/sysdeps/linux/common/waitpid.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-write.S b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-write.S
new file mode 100644
index 000000000..6bc666779
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-write.S
@@ -0,0 +1,9 @@
+#include <sysdep-cancel.h>
+PSEUDO (__libc_write, write, 3)
+ret
+PSEUDO_END (__libc_write)
+libpthread_hidden_def (__libc_write)
+weak_alias (__libc_write, __write)
+libpthread_hidden_weak (__write)
+weak_alias (__libc_write, write)
+libpthread_hidden_weak (write)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
new file mode 100644
index 000000000..46fbd0de7
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
@@ -0,0 +1,8 @@
+#include <pthreadP.h>
+
+-- These PI macros are used by assembly code.
+
+MUTEX_KIND offsetof (pthread_mutex_t, __data.__kind)
+ROBUST_BIT PTHREAD_MUTEX_ROBUST_NORMAL_NP
+PI_BIT PTHREAD_MUTEX_PRIO_INHERIT_NP
+PS_BIT PTHREAD_MUTEX_PSHARED_BIT
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c
new file mode 100644
index 000000000..2ec2f3d74
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_attr_getaffinity.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <pthreadP.h>
+#include <string.h>
+#include <sysdep.h>
+#include <sys/types.h>
+
+
+int
+pthread_attr_getaffinity_np(const pthread_attr_t *attr, size_t cpusetsize,
+ cpu_set_t *cpuset)
+{
+ const struct pthread_attr *iattr;
+
+ assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+ iattr = (const struct pthread_attr *) attr;
+
+ if (iattr->cpuset != NULL)
+ {
+ /* Check whether there are any bits set beyond the limits
+ the user requested. */
+ for (size_t cnt = cpusetsize; cnt < iattr->cpusetsize; ++cnt)
+ if (((char *) iattr->cpuset)[cnt] != 0)
+ return EINVAL;
+
+ void *p = mempcpy (cpuset, iattr->cpuset, iattr->cpusetsize);
+ if (cpusetsize > iattr->cpusetsize)
+ memset (p, '\0', cpusetsize - iattr->cpusetsize);
+ }
+ else
+ /* We have no information. */
+ memset (cpuset, -1, cpusetsize);
+
+ return 0;
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c
new file mode 100644
index 000000000..609ee2ad1
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c
@@ -0,0 +1,80 @@
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthreadP.h>
+
+
+/* Defined in pthread_setaffinity.c. */
+extern size_t __kernel_cpumask_size attribute_hidden;
+extern int __determine_cpumask_size (pid_t tid);
+libpthread_hidden_proto(__determine_cpumask_size)
+
+int
+pthread_attr_setaffinity_np (pthread_attr_t *attr, size_t cpusetsize,
+ const cpu_set_t *cpuset)
+{
+ struct pthread_attr *iattr;
+
+ assert (sizeof (*attr) >= sizeof (struct pthread_attr));
+ iattr = (struct pthread_attr *) attr;
+
+ if (cpuset == NULL || cpusetsize == 0)
+ {
+ free (iattr->cpuset);
+ iattr->cpuset = NULL;
+ iattr->cpusetsize = 0;
+ }
+ else
+ {
+ if (__kernel_cpumask_size == 0)
+ {
+ int res = __determine_cpumask_size (THREAD_SELF->tid);
+ if (res != 0)
+ /* Some serious problem. */
+ return res;
+ }
+
+ /* Check whether the new bitmask has any bit set beyond the
+ last one the kernel accepts. */
+ for (size_t cnt = __kernel_cpumask_size; cnt < cpusetsize; ++cnt)
+ if (((char *) cpuset)[cnt] != '\0')
+ /* Found a nonzero byte. This means the user request cannot be
+ fulfilled. */
+ return EINVAL;
+
+ if (iattr->cpusetsize != cpusetsize)
+ {
+ void *newp = (cpu_set_t *) realloc (iattr->cpuset, cpusetsize);
+ if (newp == NULL)
+ return ENOMEM;
+
+ iattr->cpuset = newp;
+ iattr->cpusetsize = cpusetsize;
+ }
+
+ memcpy (iattr->cpuset, cpuset, cpusetsize);
+ }
+
+ return 0;
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getaffinity.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getaffinity.c
new file mode 100644
index 000000000..affcc6a65
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getaffinity.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <limits.h>
+#include <pthreadP.h>
+#include <string.h>
+#include <sysdep.h>
+#include <sys/param.h>
+#include <sys/types.h>
+
+
+int
+__pthread_getaffinity_np (pthread_t th, size_t cpusetsize, cpu_set_t *cpuset)
+{
+ const struct pthread *pd = (const struct pthread *) th;
+
+ INTERNAL_SYSCALL_DECL (err);
+ int res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, pd->tid,
+ MIN (INT_MAX, cpusetsize), cpuset);
+ if (INTERNAL_SYSCALL_ERROR_P (res, err))
+ return INTERNAL_SYSCALL_ERRNO (res, err);
+
+ /* Clean the rest of the memory the kernel didn't do. */
+ memset ((char *) cpuset + res, '\0', cpusetsize - res);
+
+ return 0;
+}
+strong_alias(__pthread_getaffinity_np, pthread_getaffinity_np)
+
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c
new file mode 100644
index 000000000..9e28f69fd
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <pthreadP.h>
+#include <sys/time.h>
+#include <tls.h>
+
+
+int
+pthread_getcpuclockid (
+ pthread_t threadid,
+ clockid_t *clockid)
+{
+ struct pthread *pd = (struct pthread *) threadid;
+
+ /* Make sure the descriptor is valid. */
+ if (INVALID_TD_P (pd))
+ /* Not a valid thread handle. */
+ return ESRCH;
+
+#ifdef CLOCK_THREAD_CPUTIME_ID
+ /* We need to store the thread ID in the CLOCKID variable together
+ with a number identifying the clock. We reserve the low 3 bits
+ for the clock ID and the rest for the thread ID. This is
+ problematic if the thread ID is too large. But 29 bits should be
+ fine.
+
+ If some day more clock IDs are needed the ID part can be
+ enlarged. The IDs are entirely internal. */
+ if (pd->tid >= 1 << (8 * sizeof (*clockid) - CLOCK_IDFIELD_SIZE))
+ return ERANGE;
+
+ /* Store the number. */
+ *clockid = CLOCK_THREAD_CPUTIME_ID | (pd->tid << CLOCK_IDFIELD_SIZE);
+
+ return 0;
+#else
+ /* We don't have a timer for that. */
+ return ENOENT;
+#endif
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_kill.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_kill.c
new file mode 100644
index 000000000..3a70c3764
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_kill.c
@@ -0,0 +1,78 @@
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <pthreadP.h>
+#include <tls.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+
+
+int
+__pthread_kill (
+ pthread_t threadid,
+ int signo)
+{
+ struct pthread *pd = (struct pthread *) threadid;
+
+ /* Make sure the descriptor is valid. */
+ if (DEBUGGING_P && INVALID_TD_P (pd))
+ /* Not a valid thread handle. */
+ return ESRCH;
+
+ /* Force load of pd->tid into local variable or register. Otherwise
+ if a thread exits between ESRCH test and tgkill, we might return
+ EINVAL, because pd->tid would be cleared by the kernel. */
+ pid_t tid = atomic_forced_read (pd->tid);
+ if (__builtin_expect (tid <= 0, 0))
+ /* Not a valid thread handle. */
+ return ESRCH;
+
+ /* Disallow sending the signal we use for cancellation, timers, for
+ for the setxid implementation. */
+ if (signo == SIGCANCEL || signo == SIGTIMER || signo == SIGSETXID)
+ return EINVAL;
+
+ /* We have a special syscall to do the work. */
+ INTERNAL_SYSCALL_DECL (err);
+
+ /* One comment: The PID field in the TCB can temporarily be changed
+ (in fork). But this must not affect this code here. Since this
+ function would have to be called while the thread is executing
+ fork, it would have to happen in a signal handler. But this is
+ no allowed, pthread_kill is not guaranteed to be async-safe. */
+ int val;
+#if __ASSUME_TGKILL
+ val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
+ tid, signo);
+#else
+# ifdef __NR_tgkill
+ val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid),
+ tid, signo);
+ if (INTERNAL_SYSCALL_ERROR_P (val, err)
+ && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
+# endif
+ val = INTERNAL_SYSCALL (tkill, err, 2, tid, signo);
+#endif
+
+ return (INTERNAL_SYSCALL_ERROR_P (val, err)
+ ? INTERNAL_SYSCALL_ERRNO (val, err) : 0);
+}
+strong_alias (__pthread_kill, pthread_kill)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
new file mode 100644
index 000000000..804bfab44
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
@@ -0,0 +1,14 @@
+#include <pthreadP.h>
+
+#define LLL_MUTEX_LOCK(mutex) \
+ lll_cond_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex))
+#define LLL_MUTEX_TRYLOCK(mutex) \
+ lll_cond_trylock ((mutex)->__data.__lock)
+#define LLL_ROBUST_MUTEX_LOCK(mutex, id) \
+ lll_robust_cond_lock ((mutex)->__data.__lock, id, \
+ PTHREAD_ROBUST_MUTEX_PSHARED (mutex))
+#define __pthread_mutex_lock __pthread_mutex_cond_lock
+#define __pthread_mutex_lock_full __pthread_mutex_cond_lock_full
+#define NO_INCR
+
+#include <pthread_mutex_lock.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c
new file mode 100644
index 000000000..467e8ec70
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c
@@ -0,0 +1,91 @@
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <alloca.h>
+#include <errno.h>
+#include <pthreadP.h>
+#include <sysdep.h>
+#include <sys/types.h>
+
+
+size_t __kernel_cpumask_size attribute_hidden;
+
+
+/* Determine the current affinity. As a side affect we learn
+ about the size of the cpumask_t in the kernel. */
+extern int __determine_cpumask_size (pid_t tid);
+libpthread_hidden_proto(__determine_cpumask_size)
+int __determine_cpumask_size (pid_t tid)
+{
+ INTERNAL_SYSCALL_DECL (err);
+ int res;
+
+ size_t psize = 128;
+ void *p = alloca (psize);
+
+ while (res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, tid, psize, p),
+ INTERNAL_SYSCALL_ERROR_P (res, err)
+ && INTERNAL_SYSCALL_ERRNO (res, err) == EINVAL)
+ p = extend_alloca (p, psize, 2 * psize);
+
+ if (res == 0 || INTERNAL_SYSCALL_ERROR_P (res, err))
+ return INTERNAL_SYSCALL_ERRNO (res, err);
+
+ __kernel_cpumask_size = res;
+
+ return 0;
+}
+libpthread_hidden_def(__determine_cpumask_size)
+
+int
+pthread_setaffinity_np (pthread_t th, size_t cpusetsize,
+ const cpu_set_t *cpuset)
+{
+ const struct pthread *pd = (const struct pthread *) th;
+
+ INTERNAL_SYSCALL_DECL (err);
+ int res;
+
+ if (__builtin_expect (__kernel_cpumask_size == 0, 0))
+ {
+ res = __determine_cpumask_size (pd->tid);
+ if (res != 0)
+ return res;
+ }
+
+ /* We now know the size of the kernel cpumask_t. Make sure the user
+ does not request to set a bit beyond that. */
+ for (size_t cnt = __kernel_cpumask_size; cnt < cpusetsize; ++cnt)
+ if (((char *) cpuset)[cnt] != '\0')
+ /* Found a nonzero byte. This means the user request cannot be
+ fulfilled. */
+ return EINVAL;
+
+ res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid, cpusetsize,
+ cpuset);
+
+#ifdef RESET_VGETCPU_CACHE
+ if (!INTERNAL_SYSCALL_ERROR_P (res, err))
+ RESET_VGETCPU_CACHE ();
+#endif
+
+ return (INTERNAL_SYSCALL_ERROR_P (res, err)
+ ? INTERNAL_SYSCALL_ERRNO (res, err)
+ : 0);
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_sigqueue.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_sigqueue.c
new file mode 100644
index 000000000..9e49085ce
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_sigqueue.c
@@ -0,0 +1,83 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthreadP.h>
+#include <tls.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+
+
+int
+pthread_sigqueue (
+ pthread_t threadid,
+ int signo,
+ const union sigval value)
+{
+#ifdef __NR_rt_tgsigqueueinfo
+ struct pthread *pd = (struct pthread *) threadid;
+
+ /* Make sure the descriptor is valid. */
+ if (DEBUGGING_P && INVALID_TD_P (pd))
+ /* Not a valid thread handle. */
+ return ESRCH;
+
+ /* Force load of pd->tid into local variable or register. Otherwise
+ if a thread exits between ESRCH test and tgkill, we might return
+ EINVAL, because pd->tid would be cleared by the kernel. */
+ pid_t tid = atomic_forced_read (pd->tid);
+ if (__builtin_expect (tid <= 0, 0))
+ /* Not a valid thread handle. */
+ return ESRCH;
+
+ /* Disallow sending the signal we use for cancellation, timers, for
+ for the setxid implementation. */
+ if (signo == SIGCANCEL || signo == SIGTIMER || signo == SIGSETXID)
+ return EINVAL;
+
+ /* Set up the siginfo_t structure. */
+ siginfo_t info;
+ memset (&info, '\0', sizeof (siginfo_t));
+ info.si_signo = signo;
+ info.si_code = SI_QUEUE;
+ info.si_pid = THREAD_GETMEM (THREAD_SELF, pid);
+ info.si_uid = getuid ();
+ info.si_value = value;
+
+ /* We have a special syscall to do the work. */
+ INTERNAL_SYSCALL_DECL (err);
+
+ /* One comment: The PID field in the TCB can temporarily be changed
+ (in fork). But this must not affect this code here. Since this
+ function would have to be called while the thread is executing
+ fork, it would have to happen in a signal handler. But this is
+ no allowed, pthread_sigqueue is not guaranteed to be async-safe. */
+ int val = INTERNAL_SYSCALL (rt_tgsigqueueinfo, err, 4,
+ THREAD_GETMEM (THREAD_SELF, pid),
+ tid, signo, &info);
+
+ return (INTERNAL_SYSCALL_ERROR_P (val, err)
+ ? INTERNAL_SYSCALL_ERRNO (val, err) : 0);
+#else
+ return ENOSYS;
+#endif
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_yield.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_yield.c
new file mode 100644
index 000000000..5aecffcf0
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_yield.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <pthread.h>
+#include <sched.h>
+
+
+/* With the 1-on-1 model we implement this function is equivalent to
+ the 'sched_yield' function. */
+int
+pthread_yield (void)
+{
+ return sched_yield ();
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/raise.c b/libpthread/nptl/sysdeps/unix/sysv/linux/raise.c
new file mode 100644
index 000000000..da35cfe9f
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/raise.c
@@ -0,0 +1,74 @@
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <pthreadP.h>
+#include <bits/kernel-features.h>
+
+
+int
+raise (
+ int sig)
+{
+ struct pthread *pd = THREAD_SELF;
+#if __ASSUME_TGKILL || defined __NR_tgkill
+ pid_t pid = THREAD_GETMEM (pd, pid);
+#endif
+ pid_t selftid = THREAD_GETMEM (pd, tid);
+ if (selftid == 0)
+ {
+ /* This system call is not supposed to fail. */
+#ifdef INTERNAL_SYSCALL
+ INTERNAL_SYSCALL_DECL (err);
+ selftid = INTERNAL_SYSCALL (gettid, err, 0);
+#else
+ selftid = INLINE_SYSCALL (gettid, 0);
+#endif
+ THREAD_SETMEM (pd, tid, selftid);
+
+#if __ASSUME_TGKILL || defined __NR_tgkill
+ /* We do not set the PID field in the TID here since we might be
+ called from a signal handler while the thread executes fork. */
+ pid = selftid;
+#endif
+ }
+#if __ASSUME_TGKILL || defined __NR_tgkill
+ else
+ /* raise is an async-safe function. It could be called while the
+ fork/vfork function temporarily invalidated the PID field. Adjust for
+ that. */
+ if (__builtin_expect (pid <= 0, 0))
+ pid = (pid & INT_MAX) == 0 ? selftid : -pid;
+#endif
+
+#if __ASSUME_TGKILL
+ return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
+#else
+# ifdef __NR_tgkill
+ int res = INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
+ if (res != -1 || errno != ENOSYS)
+ return res;
+# endif
+ return INLINE_SYSCALL (tkill, 2, selftid, sig);
+#endif
+}
+libc_hidden_def (raise)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/read.S b/libpthread/nptl/sysdeps/unix/sysv/linux/read.S
new file mode 100644
index 000000000..d3adfa84c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/read.S
@@ -0,0 +1,19 @@
+#include <sysdep-cancel.h>
+
+/*
+extern int __read_nocancel (int, void *, size_t) attribute_hidden;
+*/
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+PSEUDO (__libc_read, read, 3)
+ret
+PSEUDO_END(__libc_read)
+
+libc_hidden_def (__read_nocancel)
+libc_hidden_def (__libc_read)
+weak_alias (__libc_read, __read)
+libc_hidden_weak (__read)
+weak_alias (__libc_read, read)
+libc_hidden_weak (read)
+
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/recv.S b/libpthread/nptl/sysdeps/unix/sysv/linux/recv.S
new file mode 100644
index 000000000..95fa6516e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/recv.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_recv
+#error Missing definition of NR_recv needed for cancellation.
+#endif
+PSEUDO (__libc_recv, recv, 4)
+ret
+PSEUDO_END(__libc_recv)
+libc_hidden_def (__libc_recv)
+weak_alias (__libc_recv, __recv)
+libc_hidden_weak (__recv)
+weak_alias (__libc_recv, recv)
+libc_hidden_weak (recv)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/recvfrom.S b/libpthread/nptl/sysdeps/unix/sysv/linux/recvfrom.S
new file mode 100644
index 000000000..d9cc1e9b4
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/recvfrom.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_recvfrom
+#error Missing definition of NR_recvfrom needed for cancellation.
+#endif
+PSEUDO (__libc_recvfrom, recvfrom, 6)
+ret
+PSEUDO_END(__libc_recvfrom)
+libc_hidden_def (__libc_recvfrom)
+weak_alias (__libc_recvfrom, __recvfrom)
+libc_hidden_weak (__recvfrom)
+weak_alias (__libc_recvfrom, recvfrom)
+libc_hidden_weak (recvfrom)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/recvmsg.S b/libpthread/nptl/sysdeps/unix/sysv/linux/recvmsg.S
new file mode 100644
index 000000000..c761b907c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/recvmsg.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_recvmsg
+#error Missing definition of NR_recvmsg needed for cancellation.
+#endif
+PSEUDO (__libc_recvmsg, recvmsg, 3)
+ret
+PSEUDO_END(__libc_recvmsg)
+libc_hidden_def (__libc_recvmsg)
+weak_alias (__libc_recvmsg, __recvmsg)
+libc_hidden_weak (__recvmsg)
+weak_alias (__libc_recvmsg, recvmsg)
+libc_hidden_weak (recvmsg)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/register-atfork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/register-atfork.c
new file mode 100644
index 000000000..f956ad565
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/register-atfork.c
@@ -0,0 +1,149 @@
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fork.h>
+#include <atomic.h>
+#include <tls.h>
+
+
+/* Lock to protect allocation and deallocation of fork handlers. */
+int __fork_lock = LLL_LOCK_INITIALIZER;
+
+
+/* Number of pre-allocated handler entries. */
+#define NHANDLER 48
+
+/* Memory pool for fork handler structures. */
+static struct fork_handler_pool
+{
+ struct fork_handler_pool *next;
+ struct fork_handler mem[NHANDLER];
+} fork_handler_pool;
+
+
+static struct fork_handler *
+fork_handler_alloc (void)
+{
+ struct fork_handler_pool *runp = &fork_handler_pool;
+ struct fork_handler *result = NULL;
+ unsigned int i;
+
+ do
+ {
+ /* Search for an empty entry. */
+ for (i = 0; i < NHANDLER; ++i)
+ if (runp->mem[i].refcntr == 0)
+ goto found;
+ }
+ while ((runp = runp->next) != NULL);
+
+ /* We have to allocate a new entry. */
+ runp = (struct fork_handler_pool *) calloc (1, sizeof (*runp));
+ if (runp != NULL)
+ {
+ /* Enqueue the new memory pool into the list. */
+ runp->next = fork_handler_pool.next;
+ fork_handler_pool.next = runp;
+
+ /* We use the last entry on the page. This means when we start
+ searching from the front the next time we will find the first
+ entry unused. */
+ i = NHANDLER - 1;
+
+ found:
+ result = &runp->mem[i];
+ result->refcntr = 1;
+ result->need_signal = 0;
+ }
+
+ return result;
+}
+
+
+int
+__register_atfork (
+ void (*prepare) (void),
+ void (*parent) (void),
+ void (*child) (void),
+ void *dso_handle)
+{
+ /* Get the lock to not conflict with other allocations. */
+ lll_lock (__fork_lock, LLL_PRIVATE);
+
+ struct fork_handler *newp = fork_handler_alloc ();
+
+ if (newp != NULL)
+ {
+ /* Initialize the new record. */
+ newp->prepare_handler = prepare;
+ newp->parent_handler = parent;
+ newp->child_handler = child;
+ newp->dso_handle = dso_handle;
+
+ __linkin_atfork (newp);
+ }
+
+ /* Release the lock. */
+ lll_unlock (__fork_lock, LLL_PRIVATE);
+
+ return newp == NULL ? ENOMEM : 0;
+}
+libc_hidden_def (__register_atfork)
+
+
+void
+attribute_hidden
+__linkin_atfork (struct fork_handler *newp)
+{
+ do
+ newp->next = __fork_handlers;
+ while (catomic_compare_and_exchange_bool_acq (&__fork_handlers,
+ newp, newp->next) != 0);
+}
+
+#if 0
+libc_freeres_fn (free_mem)
+{
+ /* Get the lock to not conflict with running forks. */
+ lll_lock (__fork_lock, LLL_PRIVATE);
+
+ /* No more fork handlers. */
+ __fork_handlers = NULL;
+
+ /* Free eventually alloated memory blocks for the object pool. */
+ struct fork_handler_pool *runp = fork_handler_pool.next;
+
+ memset (&fork_handler_pool, '\0', sizeof (fork_handler_pool));
+
+ /* Release the lock. */
+ lll_unlock (__fork_lock, LLL_PRIVATE);
+
+ /* We can free the memory after releasing the lock. */
+ while (runp != NULL)
+ {
+ struct fork_handler_pool *oldp = runp;
+ runp = runp->next;
+ free (oldp);
+ }
+}
+#endif
+
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_post.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_post.c
new file mode 100644
index 000000000..edb97c4ba
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_post.c
@@ -0,0 +1,58 @@
+/* sem_post -- post to a POSIX semaphore. Generic futex-using version.
+ Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+#include <tls.h>
+
+int
+__new_sem_post (sem_t *sem)
+{
+ struct new_sem *isem = (struct new_sem *) sem;
+
+ __typeof (isem->value) cur;
+ do
+ {
+ cur = isem->value;
+ if (isem->value == SEM_VALUE_MAX)
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+ }
+ while (atomic_compare_and_exchange_bool_acq (&isem->value, cur + 1, cur));
+
+ atomic_full_barrier ();
+ if (isem->nwaiters > 0)
+ {
+ int err = lll_futex_wake (&isem->value, 1,
+ isem->private ^ FUTEX_PRIVATE_FLAG);
+ if (__builtin_expect (err, 0) < 0)
+ {
+ __set_errno (-err);
+ return -1;
+ }
+ }
+ return 0;
+}
+weak_alias(__new_sem_post, sem_post)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
new file mode 100644
index 000000000..3e5e6dcae
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
@@ -0,0 +1,111 @@
+/* sem_timedwait -- wait on a semaphore. Generic futex-using version.
+ Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+
+#include <pthreadP.h>
+
+
+extern void __sem_wait_cleanup (void *arg) attribute_hidden;
+
+
+int
+sem_timedwait (sem_t *sem, const struct timespec *abstime)
+{
+ struct new_sem *isem = (struct new_sem *) sem;
+ int err;
+
+ if (atomic_decrement_if_positive (&isem->value) > 0)
+ return 0;
+
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ atomic_increment (&isem->nwaiters);
+
+ pthread_cleanup_push (__sem_wait_cleanup, isem);
+
+ while (1)
+ {
+ struct timeval tv;
+ struct timespec rt;
+ int sec, nsec;
+
+ /* Get the current time. */
+ __gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ sec = abstime->tv_sec - tv.tv_sec;
+ nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+ if (nsec < 0)
+ {
+ nsec += 1000000000;
+ --sec;
+ }
+
+ /* Already timed out? */
+ err = -ETIMEDOUT;
+ if (sec < 0)
+ {
+ __set_errno (ETIMEDOUT);
+ err = -1;
+ break;
+ }
+
+ /* Do wait. */
+ rt.tv_sec = sec;
+ rt.tv_nsec = nsec;
+
+ /* Enable asynchronous cancellation. Required by the standard. */
+ int oldtype = __pthread_enable_asynccancel ();
+
+ err = lll_futex_timed_wait (&isem->value, 0, &rt,
+ isem->private ^ FUTEX_PRIVATE_FLAG);
+
+ /* Disable asynchronous cancellation. */
+ __pthread_disable_asynccancel (oldtype);
+
+ if (err != 0 && err != -EWOULDBLOCK)
+ {
+ __set_errno (-err);
+ err = -1;
+ break;
+ }
+
+ if (atomic_decrement_if_positive (&isem->value) > 0)
+ {
+ err = 0;
+ break;
+ }
+ }
+
+ pthread_cleanup_pop (0);
+
+ atomic_decrement (&isem->nwaiters);
+
+ return err;
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_trywait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_trywait.c
new file mode 100644
index 000000000..3cf1d9a8a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_trywait.c
@@ -0,0 +1,44 @@
+/* sem_trywait -- wait on a semaphore. Generic futex-using version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+
+
+int
+__new_sem_trywait (sem_t *sem)
+{
+ int *futex = (int *) sem;
+ int val;
+
+ if (*futex > 0)
+ {
+ val = atomic_decrement_if_positive (futex);
+ if (val > 0)
+ return 0;
+ }
+
+ __set_errno (EAGAIN);
+ return -1;
+}
+weak_alias(__new_sem_trywait, sem_trywait)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_wait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_wait.c
new file mode 100644
index 000000000..e661e09c8
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_wait.c
@@ -0,0 +1,84 @@
+/* sem_wait -- wait on a semaphore. Generic futex-using version.
+ Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+
+#include <pthreadP.h>
+
+
+void
+attribute_hidden
+__sem_wait_cleanup (void *arg)
+{
+ struct new_sem *isem = (struct new_sem *) arg;
+
+ atomic_decrement (&isem->nwaiters);
+}
+
+
+int
+__new_sem_wait (sem_t *sem)
+{
+ struct new_sem *isem = (struct new_sem *) sem;
+ int err;
+
+ if (atomic_decrement_if_positive (&isem->value) > 0)
+ return 0;
+
+ atomic_increment (&isem->nwaiters);
+
+ pthread_cleanup_push (__sem_wait_cleanup, isem);
+
+ while (1)
+ {
+ /* Enable asynchronous cancellation. Required by the standard. */
+ int oldtype = __pthread_enable_asynccancel ();
+
+ err = lll_futex_wait (&isem->value, 0,
+ isem->private ^ FUTEX_PRIVATE_FLAG);
+
+ /* Disable asynchronous cancellation. */
+ __pthread_disable_asynccancel (oldtype);
+
+ if (err != 0 && err != -EWOULDBLOCK)
+ {
+ __set_errno (-err);
+ err = -1;
+ break;
+ }
+
+ if (atomic_decrement_if_positive (&isem->value) > 0)
+ {
+ err = 0;
+ break;
+ }
+ }
+
+ pthread_cleanup_pop (0);
+
+ atomic_decrement (&isem->nwaiters);
+
+ return err;
+}
+weak_alias(__new_sem_wait, sem_wait)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/send.S b/libpthread/nptl/sysdeps/unix/sysv/linux/send.S
new file mode 100644
index 000000000..eb744c712
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/send.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_send
+#error Missing definition of NR_send needed for cancellation.
+#endif
+PSEUDO (__libc_send, send, 4)
+ret
+PSEUDO_END (__libc_send)
+libc_hidden_def (__libc_send)
+weak_alias (__libc_send, __send)
+libc_hidden_weak (__send)
+weak_alias (__libc_send, send)
+libc_hidden_weak (send)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sendmsg.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sendmsg.S
new file mode 100644
index 000000000..4c41e01c1
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sendmsg.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_sendmsg
+#error Missing definition of NR_sendmsg needed for cancellation.
+#endif
+PSEUDO (__libc_sendmsg, sendmsg, 3)
+ret
+PSEUDO_END(__libc_sendmsg)
+libc_hidden_def (__libc_sendmsg)
+weak_alias (__libc_sendmsg, __sendmsg)
+libc_hidden_weak (__sendmsg)
+weak_alias (__libc_sendmsg, sendmsg)
+libc_hidden_weak (sendmsg)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sendto.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sendto.S
new file mode 100644
index 000000000..7cb5278e9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sendto.S
@@ -0,0 +1,12 @@
+#include <sysdep-cancel.h>
+#ifndef __NR_sendto
+#error Missing definition of NR_sendto needed for cancellation.
+#endif
+PSEUDO (__libc_sendto, sendto, 6)
+ret
+PSEUDO_END(__libc_sendto)
+libc_hidden_def (__libc_sendto)
+weak_alias (__libc_sendto, __sendto)
+libc_hidden_weak (__sendto)
+weak_alias (__libc_sendto, sendto)
+libc_hidden_weak (sendto)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile
new file mode 100644
index 000000000..43a6fad84
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile
@@ -0,0 +1,13 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../../../../../
+top_builddir=../../../../../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.arch
+include $(top_srcdir)Makerules
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch
new file mode 100644
index 000000000..940bd62f8
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch
@@ -0,0 +1,85 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+libpthread_SSRC = pt-vfork.S pthread_once.S pthread_rwlock_wrlock.S \
+ pthread_rwlock_rdlock.S pthread_rwlock_unlock.S \
+ lowlevellock.S lowlevelrobustlock.S pthread_barrier_wait.S \
+ pthread_cond_broadcast.S pthread_cond_signal.S \
+ pthread_rwlock_timedwrlock.S pthread_rwlock_timedrdlock.S \
+ sem_post.S sem_timedwait.S sem_trywait.S sem_wait.S
+
+libc_a_CSRC = fork.c
+libc_a_SSRC = libc-lowlevellock.S clone.S vfork.S
+
+ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y)
+CFLAGS-fork.c = -D__USE_STDIO_FUTEXES__
+endif
+
+ASFLAGS-pt-vfork.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-pthread_once.S = -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-pthread_rwlock_wrlock.S = -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-pthread_rwlock_rdlock.S = -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-pthread_rwlock_unlock.S = -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-pthread_rwlock_unlock.S = -D_LIBC_REENTRANT -DUSE___THREAD
+
+ASFLAGS-pthread_barrier_wait.S = -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-pthread_cond_broadcast.S = -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-pthread_cond_signal.S = -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-pthread_cond_wait.S = -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-pthread_cond_timedwait.S = -D_LIBC_REENTRANT -DUSE___THREAD
+
+ASFLAGS-pthread_rwlock_timedwrlock.S = -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-pthread_rwlock_timedrdlock.S = -D_LIBC_REENTRANT -DUSE___THREAD
+
+ASFLAGS-sem_post.S = -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-sem_timedwait.S = -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-sem_trywait.S = -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-sem_wait.S = -D_LIBC_REENTRANT -DUSE___THREAD
+
+ASFLAGS-libc-lowlevellock.S = -D_LIBC_REENTRANT -DUSE___THREAD
+
+ASFLAGS-lowlevellock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-lowlevelrobustlock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+
+ASFLAGS-clone.S = -D_LIBC_REENTRANT
+ASFLAGS-vfork.S = -D_LIBC_REENTRANT
+
+ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y)
+#Needed to use the correct SYSCALL_ERROR_HANDLER
+ASFLAGS-clone.S += -DUSE___THREAD
+ASFLAGS-vfork.S += -DUSE___THREAD
+endif
+
+CFLAGS += $(SSP_ALL_CFLAGS)
+#CFLAGS:=$(CFLAGS:-O1=-O2)
+
+LINUX_ARCH_DIR:=$(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/sh
+LINUX_ARCH_OUT:=$(top_builddir)libpthread/nptl/sysdeps/unix/sysv/linux/sh
+
+LINUX_ARCH_OBJ:=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libpthread_SSRC))
+
+ifeq ($(DOPIC),y)
+libpthread-a-y += $(LINUX_ARCH_OBJ:.o=.os)
+else
+libpthread-a-y += $(LINUX_ARCH_OBJ)
+endif
+libpthread-so-y += $(LINUX_ARCH_OBJ:.o=.oS)
+
+libpthread-nomulti-y+=$(LINUX_ARCH_OBJS)
+
+LIBC_LINUX_ARCH_OBJ:=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libc_a_CSRC))
+LIBC_LINUX_ARCH_OBJ+=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libc_a_SSRC))
+
+libc-static-y+=$(LIBC_LINUX_ARCH_OBJ)
+libc-shared-y+=$(LIBC_LINUX_ARCH_OBJ:.o=.oS)
+
+libc-nomulti-y+=$(LIBC_LINUX_ARCH_OBJ)
+
+objclean-y+=nptl_linux_arch_clean
+
+nptl_linux_arch_clean:
+ $(do_rm) $(addprefix $(LINUX_ARCH_OUT)/*., o os oS)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
new file mode 100644
index 000000000..badcda570
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
@@ -0,0 +1,183 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H 1
+
+#include <endian.h>
+
+#define __SIZEOF_PTHREAD_ATTR_T 36
+#define __SIZEOF_PTHREAD_MUTEX_T 24
+#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+#define __SIZEOF_PTHREAD_COND_T 48
+#define __SIZEOF_PTHREAD_COND_COMPAT_T 12
+#define __SIZEOF_PTHREAD_CONDATTR_T 4
+#define __SIZEOF_PTHREAD_RWLOCK_T 32
+#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+#define __SIZEOF_PTHREAD_BARRIER_T 20
+#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+
+
+/* Thread identifiers. The structure of the attribute type is not
+ exposed on purpose. */
+typedef unsigned long int pthread_t;
+
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_ATTR_T];
+ long int __align;
+} pthread_attr_t;
+
+
+typedef struct __pthread_internal_slist
+{
+ struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+
+
+/* Data structures for mutex handling. The structure of the attribute
+ type is not exposed on purpose. */
+typedef union
+{
+ struct __pthread_mutex_s
+ {
+ int __lock;
+ unsigned int __count;
+ int __owner;
+ /* KIND must stay at this position in the structure to maintain
+ binary compatibility. */
+ int __kind;
+ unsigned int __nusers;
+ __extension__ union
+ {
+ int __spins;
+ __pthread_slist_t __list;
+ };
+ } __data;
+ char __size[__SIZEOF_PTHREAD_MUTEX_T];
+ long int __align;
+} pthread_mutex_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+ long int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling. The structure of
+ the attribute type is not exposed on purpose. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned int __futex;
+ __extension__ unsigned long long int __total_seq;
+ __extension__ unsigned long long int __wakeup_seq;
+ __extension__ unsigned long long int __woken_seq;
+ void *__mutex;
+ unsigned int __nwaiters;
+ unsigned int __broadcast_seq;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_COND_T];
+ __extension__ long long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+ long int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Data structure for read-write lock variable handling. The
+ structure of the attribute type is not exposed on purpose. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned int __nr_readers;
+ unsigned int __readers_wakeup;
+ unsigned int __writer_wakeup;
+ unsigned int __nr_readers_queued;
+ unsigned int __nr_writers_queued;
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned char __pad1;
+ unsigned char __pad2;
+ unsigned char __shared;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned char __flags;
+#else
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned char __flags;
+ unsigned char __shared;
+ unsigned char __pad1;
+ unsigned char __pad2;
+#endif
+ pthread_t __writer;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+ long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+ long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type. */
+typedef volatile int pthread_spinlock_t;
+
+
+/* POSIX barriers data type. The structure of the type is
+ deliberately not exposed. */
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIER_T];
+ long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+ int __align;
+} pthread_barrierattr_t;
+#endif
+
+
+#endif /* bits/pthreadtypes.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h
new file mode 100644
index 000000000..934493c30
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+
+#define __SIZEOF_SEM_T 16
+
+
+/* Value returned if `sem_open' failed. */
+#define SEM_FAILED ((sem_t *) 0)
+
+
+typedef union
+{
+ char __size[__SIZEOF_SEM_T];
+ long int __align;
+} sem_t;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/clone.S
new file mode 100644
index 000000000..918d57926
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/clone.S
@@ -0,0 +1,2 @@
+#define RESET_PID
+#include <libc/sysdeps/linux/sh/clone.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/createthread.c
new file mode 100644
index 000000000..e17c0174b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/createthread.c
@@ -0,0 +1,24 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Value passed to 'clone' for initialization of the thread register. */
+#define TLS_VALUE (pd + 1)
+
+
+/* Get the real implementation. */
+#include <sysdeps/pthread/createthread.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/fork.c
new file mode 100644
index 000000000..6868b9bcd
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/fork.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sched.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+
+/* TLS pointer argument is passed as the 5-th argument. */
+#define ARCH_FORK() \
+ INLINE_SYSCALL (clone, 5, \
+ CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0, \
+ NULL, &THREAD_SELF->tid, NULL)
+
+#include "../fork.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S
new file mode 100644
index 000000000..feb82110c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S
@@ -0,0 +1,19 @@
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "lowlevellock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h
new file mode 100644
index 000000000..c7028360f
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h
@@ -0,0 +1,81 @@
+/* Copyright (C) 2003, 2004, 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef __ASSEMBLER__
+
+#define _IMP1 #1
+#define _IMM1 #-1
+#define _IMM4 #-4
+#define _IMM6 #-6
+#define _IMM8 #-8
+
+#define INC(mem, reg) \
+ .align 2; \
+ mova 99f, r0; \
+ mov r15, r1; \
+ mov _IMM6, r15; \
+98: mov.l mem, reg; \
+ add _IMP1, reg; \
+ mov.l reg, mem; \
+99: mov r1, r15
+
+#define DEC(mem, reg) \
+ .align 2; \
+ mova 99f, r0; \
+ mov r15, r1; \
+ mov _IMM6, r15; \
+98: mov.l mem, reg; \
+ add _IMM1, reg; \
+ mov.l reg, mem; \
+99: mov r1, r15
+
+#define XADD(reg, mem, old, tmp) \
+ .align 2; \
+ mova 99f, r0; \
+ nop; \
+ mov r15, r1; \
+ mov _IMM8, r15; \
+98: mov.l mem, old; \
+ mov reg, tmp; \
+ add old, tmp; \
+ mov.l tmp, mem; \
+99: mov r1, r15
+
+#define XCHG(reg, mem, old) \
+ .align 2; \
+ mova 99f, r0; \
+ nop; \
+ mov r15, r1; \
+ mov _IMM4, r15; \
+98: mov.l mem, old; \
+ mov.l reg, mem; \
+99: mov r1, r15
+
+#define CMPXCHG(reg, mem, new, old) \
+ .align 2; \
+ mova 99f, r0; \
+ nop; \
+ mov r15, r1; \
+ mov _IMM8, r15; \
+98: mov.l mem, old; \
+ cmp/eq old, reg; \
+ bf 99f; \
+ mov.l new, mem; \
+99: mov r1, r15
+
+#endif /* __ASSEMBLER__ */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
new file mode 100644
index 000000000..00edc75a7
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
@@ -0,0 +1,540 @@
+/* Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <lowlevellock.h>
+#include <tcb-offsets.h>
+#include "lowlevel-atomic.h"
+
+ .text
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define LOAD_PRIVATE_FUTEX_WAIT(reg,tmp,tmp2) \
+ mov #(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg; \
+ extu.b reg, reg
+# define LOAD_PRIVATE_FUTEX_WAKE(reg,tmp,tmp2) \
+ mov #(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg; \
+ extu.b reg, reg
+# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
+ mov #(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), tmp; \
+ extu.b tmp, tmp; \
+ xor tmp, reg
+# define LOAD_FUTEX_WAIT_ABS(reg,tmp,tmp2) \
+ mov #(FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG), tmp; \
+ extu.b tmp, tmp; \
+ mov #(FUTEX_CLOCK_REALTIME >> 8), tmp2; \
+ swap.b tmp2, tmp2; \
+ or tmp2, tmp; \
+ xor tmp, reg
+# define LOAD_FUTEX_WAKE(reg,tmp,tmp2) \
+ mov #(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), tmp; \
+ extu.b tmp, tmp; \
+ xor tmp, reg
+#else
+# if FUTEX_WAIT == 0
+# define LOAD_PRIVATE_FUTEX_WAIT(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, reg ; \
+ add reg, tmp ; \
+ bra 98f ; \
+ mov.l @tmp, reg ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98:
+# else
+# define LOAD_PRIVATE_FUTEX_WAIT(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, reg ; \
+ add reg, tmp ; \
+ mov.l @tmp, reg ; \
+ bra 98f ; \
+ mov #FUTEX_WAIT, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: or tmp, reg
+# endif
+# define LOAD_PRIVATE_FUTEX_WAKE(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, reg ; \
+ add reg, tmp ; \
+ mov.l @tmp, reg ; \
+ bra 98f ; \
+ mov #FUTEX_WAKE, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: or tmp, reg
+# if FUTEX_WAIT == 0
+# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, tmp2 ; \
+ add tmp2, tmp ; \
+ mov.l @tmp, tmp2 ; \
+ bra 98f ; \
+ mov #FUTEX_PRIVATE_FLAG, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: extu.b tmp, tmp ; \
+ xor tmp, reg ; \
+ and tmp2, reg
+# else
+# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, tmp2 ; \
+ add tmp2, tmp ; \
+ mov.l @tmp, tmp2 ; \
+ bra 98f ; \
+ mov #FUTEX_PRIVATE_FLAG, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: extu.b tmp, tmp ; \
+ xor tmp, reg ; \
+ and tmp2, reg ; \
+ mov #FUTEX_WAIT, tmp ; \
+ or tmp, reg
+# endif
+# define LOAD_FUTEX_WAIT_ABS(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, tmp2 ; \
+ add tmp2, tmp ; \
+ mov.l @tmp, tmp2 ; \
+ bra 98f ; \
+ mov #FUTEX_PRIVATE_FLAG, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: extu.b tmp, tmp ; \
+ xor tmp, reg ; \
+ and tmp2, reg ; \
+ mov #FUTEX_WAIT_BITSET, tmp ; \
+ mov #(FUTEX_CLOCK_REALTIME >> 8), tmp2; \
+ swap.b tmp2, tmp2; \
+ or tmp2, tmp; \
+ or tmp, reg
+# define LOAD_FUTEX_WAKE(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, tmp2 ; \
+ add tmp2, tmp ; \
+ mov.l @tmp, tmp2 ; \
+ bra 98f ; \
+ mov #FUTEX_PRIVATE_FLAG, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: extu.b tmp, tmp ; \
+ xor tmp, reg ; \
+ and tmp2, reg ; \
+ mov #FUTEX_WAKE, tmp ; \
+ or tmp, reg
+#endif
+
+ .globl __lll_lock_wait_private
+ .type __lll_lock_wait_private,@function
+ .hidden __lll_lock_wait_private
+ .align 5
+ cfi_startproc
+__lll_lock_wait_private:
+ mov.l r8, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r8, 0)
+ mov r4, r6
+ mov r5, r8
+ mov #0, r7 /* No timeout. */
+ LOAD_PRIVATE_FUTEX_WAIT (r5, r0, r1)
+
+ mov #2, r4
+ cmp/eq r4, r6
+ bf 2f
+
+1:
+ mov r8, r4
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+2:
+ mov #2, r6
+ XCHG (r6, @r8, r2)
+ tst r2, r2
+ bf 1b
+
+ mov.l @r15+, r8
+ rts
+ mov r2, r0
+ cfi_endproc
+ .size __lll_lock_wait_private,.-__lll_lock_wait_private
+
+#ifdef NOT_IN_libc
+ .globl __lll_lock_wait
+ .type __lll_lock_wait,@function
+ .hidden __lll_lock_wait
+ .align 5
+ cfi_startproc
+__lll_lock_wait:
+ mov.l r9, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r9, 0)
+ mov.l r8, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r8, 0)
+ mov r6, r9
+ mov r4, r6
+ mov r5, r8
+ mov #0, r7 /* No timeout. */
+ mov r9, r5
+ LOAD_FUTEX_WAIT (r5, r0, r1)
+
+ mov #2, r4
+ cmp/eq r4, r6
+ bf 2f
+
+1:
+ mov r8, r4
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+2:
+ mov #2, r6
+ XCHG (r6, @r8, r2)
+ tst r2, r2
+ bf 1b
+
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ ret
+ mov r2, r0
+ cfi_endproc
+ .size __lll_lock_wait,.-__lll_lock_wait
+
+ /* r5 (r8): futex
+ r7 (r11): flags
+ r6 (r9): timeout
+ r4 (r10): futex value
+ */
+ .globl __lll_timedlock_wait
+ .type __lll_timedlock_wait,@function
+ .hidden __lll_timedlock_wait
+ .align 5
+ cfi_startproc
+__lll_timedlock_wait:
+ mov.l r12, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r12, 0)
+
+# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+ mov.l .Lhave, r1
+# ifdef __PIC__
+ mova .Lgot, r0
+ mov.l .Lgot, r12
+ add r0, r12
+ add r12, r1
+# endif
+ mov.l @r1, r0
+ tst r0, r0
+ bt .Lreltmo
+# endif
+
+ mov r4, r2
+ mov r5, r4
+ mov r7, r5
+ mov r6, r7
+ LOAD_FUTEX_WAIT_ABS (r5, r0, r1)
+
+ mov #2, r6
+ cmp/eq r6, r2
+ bf/s 2f
+ mov r6, r2
+
+1:
+ mov #2, r6
+ mov #-1, r1
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x16
+ SYSCALL_INST_PAD
+ mov r0, r6
+
+2:
+ XCHG (r2, @r4, r3) /* NB: lock is implied */
+
+ tst r3, r3
+ bt/s 3f
+ mov r6, r0
+
+ cmp/eq #-ETIMEDOUT, r0
+ bt 4f
+ cmp/eq #-EINVAL, r0
+ bf 1b
+4:
+ neg r0, r3
+3:
+ mov r3, r0
+ rts
+ mov.l @r15+, r12
+
+ .align 2
+# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+# ifdef __PIC__
+.Lgot:
+ .long _GLOBAL_OFFSET_TABLE_
+.Lhave:
+ .long __have_futex_clock_realtime@GOTOFF
+# else
+.Lhave:
+ .long __have_futex_clock_realtime
+# endif
+
+.Lreltmo:
+ /* Check for a valid timeout value. */
+ mov.l @(4,r6), r1
+ mov.l .L1g, r0
+ cmp/hs r0, r1
+ bt 3f
+
+ mov.l r11, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r11, 0)
+ mov.l r10, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r10, 0)
+ mov.l r9, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r9, 0)
+ mov.l r8, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r8, 0)
+ mov r7, r11
+ mov r4, r10
+ mov r6, r9
+ mov r5, r8
+
+ /* Stack frame for the timespec and timeval structs. */
+ add #-8, r15
+ cfi_adjust_cfa_offset(8)
+
+ mov #2, r2
+ XCHG (r2, @r8, r3)
+
+ tst r3, r3
+ bt 6f
+
+1:
+ /* Get current time. */
+ mov r15, r4
+ mov #0, r5
+ mov #__NR_gettimeofday, r3
+ trapa #0x12
+ SYSCALL_INST_PAD
+
+ /* Compute relative timeout. */
+ mov.l @(4,r15), r0
+ mov.w .L1k, r1
+ dmulu.l r0, r1 /* Micro seconds to nano seconds. */
+ mov.l @r9, r2
+ mov.l @(4,r9), r3
+ mov.l @r15, r0
+ sts macl, r1
+ sub r0, r2
+ clrt
+ subc r1, r3
+ bf 4f
+ mov.l .L1g, r1
+ add r1, r3
+ add #-1, r2
+4:
+ cmp/pz r2
+ bf 2f /* Time is already up. */
+
+ mov.l r2, @r15 /* Store relative timeout. */
+ mov.l r3, @(4,r15)
+
+ mov r8, r4
+ mov r11, r5
+ LOAD_FUTEX_WAIT (r5, r0, r1)
+ mov r10, r6
+ mov r15, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+ mov r0, r5
+
+ mov #2, r2
+ XCHG (r2, @r8, r3)
+
+ tst r3, r3
+ bt/s 6f
+ mov #-ETIMEDOUT, r1
+ cmp/eq r5, r1
+ bf 1b
+
+2: mov #ETIMEDOUT, r3
+
+6:
+ mov r3, r0
+ add #8, r15
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ mov.l @r15+, r10
+ mov.l @r15+, r11
+ rts
+ mov.l @r15+, r12
+
+3:
+ mov.l @r15+, r12
+ rts
+ mov #EINVAL, r0
+# endif
+ cfi_endproc
+
+.L1k:
+ .word 1000
+ .align 2
+.L1g:
+ .long 1000000000
+
+ .size __lll_timedlock_wait,.-__lll_timedlock_wait
+#endif
+
+ .globl __lll_unlock_wake_private
+ .type __lll_unlock_wake_private,@function
+ .hidden __lll_unlock_wake_private
+ .align 5
+ cfi_startproc
+__lll_unlock_wake_private:
+ LOAD_PRIVATE_FUTEX_WAKE (r5, r0, r1)
+ mov #1, r6 /* Wake one thread. */
+ mov #0, r7
+ mov.l r7, @r4 /* Stores 0. */
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+ rts
+ nop
+ cfi_endproc
+ .size __lll_unlock_wake_private,.-__lll_unlock_wake_private
+
+#ifdef NOT_IN_libc
+ .globl __lll_unlock_wake
+ .type __lll_unlock_wake,@function
+ .hidden __lll_unlock_wake
+ .align 5
+ cfi_startproc
+__lll_unlock_wake:
+ LOAD_FUTEX_WAKE (r5, r0, r1)
+ mov #1, r6 /* Wake one thread. */
+ mov #0, r7
+ mov.l r7, @r4 /* Stores 0. */
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+ rts
+ nop
+ cfi_endproc
+ .size __lll_unlock_wake,.-__lll_unlock_wake
+
+ .globl __lll_timedwait_tid
+ .type __lll_timedwait_tid,@function
+ .hidden __lll_timedwait_tid
+ .align 5
+ cfi_startproc
+__lll_timedwait_tid:
+ mov.l r9, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r9, 0)
+ mov.l r8, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r8, 0)
+ mov r4, r8
+ mov r5, r9
+
+ /* Stack frame for the timespec and timeval structs. */
+ add #-8, r15
+ cfi_adjust_cfa_offset(8)
+
+2:
+ /* Get current time. */
+ mov r15, r4
+ mov #0, r5
+ mov #__NR_gettimeofday, r3
+ trapa #0x12
+ SYSCALL_INST_PAD
+
+ /* Compute relative timeout. */
+ mov.l @(4,r15), r0
+ mov.w .L1k2, r1
+ dmulu.l r0, r1 /* Micro seconds to nano seconds. */
+ mov.l @r9, r2
+ mov.l @(4,r9), r3
+ mov.l @r15, r0
+ sts macl, r1
+ sub r0, r2
+ clrt
+ subc r1, r3
+ bf 5f
+ mov.l .L1g2, r1
+ add r1, r3
+ add #-1, r2
+5:
+ cmp/pz r2
+ bf 6f /* Time is already up. */
+
+ mov.l r2, @r15 /* Store relative timeout. */
+ mov.l r3, @(4,r15)
+
+ mov.l @r8, r2
+ tst r2, r2
+ bt 4f
+
+ mov r8, r4
+ /* XXX The kernel so far uses global futex for the wakeup at
+ all times. */
+ mov #0, r5
+ extu.b r5, r5
+ mov r2, r6
+ mov r15, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ mov.l @r8, r2
+ tst r2, r2
+ bf 1f
+4:
+ mov #0, r0
+3:
+ add #8, r15
+ mov.l @r15+, r8
+ rts
+ mov.l @r15+, r9
+1:
+ /* Check whether the time expired. */
+ mov #-ETIMEDOUT, r1
+ cmp/eq r0, r1
+ bf 2b
+6:
+ bra 3b
+ mov #ETIMEDOUT, r0
+ cfi_endproc
+
+.L1k2:
+ .word 1000
+ .align 2
+.L1g2:
+ .long 1000000000
+ .size __lll_timedwait_tid,.-__lll_timedwait_tid
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
new file mode 100644
index 000000000..19ce7fe40
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
@@ -0,0 +1,420 @@
+/* Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H 1
+
+#ifndef __ASSEMBLER__
+#include <time.h>
+#include <sys/param.h>
+#include <bits/pthreadtypes.h>
+#include <bits/kernel-features.h>
+#endif
+
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_CMP_REQUEUE 4
+#define FUTEX_WAKE_OP 5
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_WAIT_BITSET 9
+#define FUTEX_WAKE_BITSET 10
+#define FUTEX_PRIVATE_FLAG 128
+#define FUTEX_CLOCK_REALTIME 256
+
+#define FUTEX_BITSET_MATCH_ANY 0xffffffff
+
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
+ & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
+#ifndef __ASSEMBLER__
+
+/* Initializer for compatibility lock. */
+#define LLL_LOCK_INITIALIZER (0)
+#define LLL_LOCK_INITIALIZER_LOCKED (1)
+#define LLL_LOCK_INITIALIZER_WAITERS (2)
+
+extern int __lll_lock_wait_private (int val, int *__futex)
+ attribute_hidden;
+extern int __lll_lock_wait (int val, int *__futex, int private)
+ attribute_hidden;
+extern int __lll_timedlock_wait (int val, int *__futex,
+ const struct timespec *abstime, int private)
+ attribute_hidden;
+extern int __lll_robust_lock_wait (int val, int *__futex, int private)
+ attribute_hidden;
+extern int __lll_robust_timedlock_wait (int val, int *__futex,
+ const struct timespec *abstime,
+ int private)
+ attribute_hidden;
+extern int __lll_unlock_wake_private (int *__futex) attribute_hidden;
+extern int __lll_unlock_wake (int *__futex, int private) attribute_hidden;
+
+#define lll_trylock(futex) \
+ ({ unsigned char __result; \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%1,r2\n\
+ cmp/eq r2,%3\n\
+ bf 1f\n\
+ mov.l %2,@%1\n\
+ 1: mov r1,r15\n\
+ mov #-1,%0\n\
+ negc %0,%0"\
+ : "=r" (__result) \
+ : "r" (&(futex)), \
+ "r" (LLL_LOCK_INITIALIZER_LOCKED), \
+ "r" (LLL_LOCK_INITIALIZER) \
+ : "r0", "r1", "r2", "t", "memory"); \
+ __result; })
+
+#define lll_robust_trylock(futex, id) \
+ ({ unsigned char __result; \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%1,r2\n\
+ cmp/eq r2,%3\n\
+ bf 1f\n\
+ mov.l %2,@%1\n\
+ 1: mov r1,r15\n\
+ mov #-1,%0\n\
+ negc %0,%0"\
+ : "=r" (__result) \
+ : "r" (&(futex)), \
+ "r" (id), \
+ "r" (LLL_LOCK_INITIALIZER) \
+ : "r0", "r1", "r2", "t", "memory"); \
+ __result; })
+
+#define lll_cond_trylock(futex) \
+ ({ unsigned char __result; \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%1,r2\n\
+ cmp/eq r2,%3\n\
+ bf 1f\n\
+ mov.l %2,@%1\n\
+ 1: mov r1,r15\n\
+ mov #-1,%0\n\
+ negc %0,%0"\
+ : "=r" (__result) \
+ : "r" (&(futex)), \
+ "r" (LLL_LOCK_INITIALIZER_WAITERS), \
+ "r" (LLL_LOCK_INITIALIZER) \
+ : "r0", "r1", "r2", "t", "memory"); \
+ __result; })
+
+#define lll_lock(futex, private) \
+ (void) ({ int __result, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%2,%0\n\
+ tst %0,%0\n\
+ bf 1f\n\
+ mov.l %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (1), "r" (__futex) \
+ : "r0", "r1", "t", "memory"); \
+ if (__result) \
+ { \
+ if (__builtin_constant_p (private) \
+ && (private) == LLL_PRIVATE) \
+ __lll_lock_wait_private (__result, __futex); \
+ else \
+ __lll_lock_wait (__result, __futex, (private)); \
+ } \
+ })
+
+#define lll_robust_lock(futex, id, private) \
+ ({ int __result, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%2,%0\n\
+ tst %0,%0\n\
+ bf 1f\n\
+ mov.l %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (id), "r" (__futex) \
+ : "r0", "r1", "t", "memory"); \
+ if (__result) \
+ __result = __lll_robust_lock_wait (__result, __futex, private); \
+ __result; })
+
+/* Special version of lll_mutex_lock which causes the unlock function to
+ always wakeup waiters. */
+#define lll_cond_lock(futex, private) \
+ (void) ({ int __result, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%2,%0\n\
+ tst %0,%0\n\
+ bf 1f\n\
+ mov.l %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (2), "r" (__futex) \
+ : "r0", "r1", "t", "memory"); \
+ if (__result) \
+ __lll_lock_wait (__result, __futex, private); })
+
+#define lll_robust_cond_lock(futex, id, private) \
+ ({ int __result, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%2,%0\n\
+ tst %0,%0\n\
+ bf 1f\n\
+ mov.l %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (id | FUTEX_WAITERS), "r" (__futex) \
+ : "r0", "r1", "t", "memory"); \
+ if (__result) \
+ __result = __lll_robust_lock_wait (__result, __futex, private); \
+ __result; })
+
+#define lll_timedlock(futex, timeout, private) \
+ ({ int __result, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%2,%0\n\
+ tst %0,%0\n\
+ bf 1f\n\
+ mov.l %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (1), "r" (__futex) \
+ : "r0", "r1", "t", "memory"); \
+ if (__result) \
+ __result = __lll_timedlock_wait (__result, __futex, timeout, private); \
+ __result; })
+
+#define lll_robust_timedlock(futex, timeout, id, private) \
+ ({ int __result, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ nop\n\
+ mov r15,r1\n\
+ mov #-8,r15\n\
+ 0: mov.l @%2,%0\n\
+ tst %0,%0\n\
+ bf 1f\n\
+ mov.l %1,@%2\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (id), "r" (__futex) \
+ : "r0", "r1", "t", "memory"); \
+ if (__result) \
+ __result = __lll_robust_timedlock_wait (__result, __futex, \
+ timeout, private); \
+ __result; })
+
+#define lll_unlock(futex, private) \
+ (void) ({ int __result, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.l @%1,%0\n\
+ add #-1,%0\n\
+ mov.l %0,@%1\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (__futex) \
+ : "r0", "r1", "memory"); \
+ if (__result) \
+ { \
+ if (__builtin_constant_p (private) \
+ && (private) == LLL_PRIVATE) \
+ __lll_unlock_wake_private (__futex); \
+ else \
+ __lll_unlock_wake (__futex, (private)); \
+ } \
+ })
+
+#define lll_robust_unlock(futex, private) \
+ (void) ({ int __result, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.l @%1,%0\n\
+ and %2,%0\n\
+ mov.l %0,@%1\n\
+ 1: mov r1,r15"\
+ : "=&r" (__result) : "r" (__futex), "r" (FUTEX_WAITERS) \
+ : "r0", "r1", "memory"); \
+ if (__result) \
+ __lll_unlock_wake (__futex, private); })
+
+#define lll_robust_dead(futex, private) \
+ (void) ({ int __ignore, *__futex = &(futex); \
+ __asm __volatile ("\
+ .align 2\n\
+ mova 1f,r0\n\
+ mov r15,r1\n\
+ mov #-6,r15\n\
+ 0: mov.l @%1,%0\n\
+ or %2,%0\n\
+ mov.l %0,@%1\n\
+ 1: mov r1,r15"\
+ : "=&r" (__ignore) : "r" (__futex), "r" (FUTEX_OWNER_DIED) \
+ : "r0", "r1", "memory"); \
+ lll_futex_wake (__futex, 1, private); })
+
+# ifdef NEED_SYSCALL_INST_PAD
+# define SYSCALL_WITH_INST_PAD "\
+ trapa #0x14; or r0,r0; or r0,r0; or r0,r0; or r0,r0; or r0,r0"
+# else
+# define SYSCALL_WITH_INST_PAD "\
+ trapa #0x14"
+# endif
+
+#define lll_futex_wait(futex, val, private) \
+ lll_futex_timed_wait (futex, val, NULL, private)
+
+
+#define lll_futex_timed_wait(futex, val, timeout, private) \
+ ({ \
+ int __status; \
+ register unsigned long __r3 __asm ("r3") = SYS_futex; \
+ register unsigned long __r4 __asm ("r4") = (unsigned long) (futex); \
+ register unsigned long __r5 __asm ("r5") \
+ = __lll_private_flag (FUTEX_WAIT, private); \
+ register unsigned long __r6 __asm ("r6") = (unsigned long) (val); \
+ register unsigned long __r7 __asm ("r7") = (timeout); \
+ __asm __volatile (SYSCALL_WITH_INST_PAD \
+ : "=z" (__status) \
+ : "r" (__r3), "r" (__r4), "r" (__r5), \
+ "r" (__r6), "r" (__r7) \
+ : "memory", "t"); \
+ __status; \
+ })
+
+
+#define lll_futex_wake(futex, nr, private) \
+ do { \
+ int __ignore; \
+ register unsigned long __r3 __asm ("r3") = SYS_futex; \
+ register unsigned long __r4 __asm ("r4") = (unsigned long) (futex); \
+ register unsigned long __r5 __asm ("r5") \
+ = __lll_private_flag (FUTEX_WAKE, private); \
+ register unsigned long __r6 __asm ("r6") = (unsigned long) (nr); \
+ register unsigned long __r7 __asm ("r7") = 0; \
+ __asm __volatile (SYSCALL_WITH_INST_PAD \
+ : "=z" (__ignore) \
+ : "r" (__r3), "r" (__r4), "r" (__r5), \
+ "r" (__r6), "r" (__r7) \
+ : "memory", "t"); \
+ } while (0)
+
+
+#define lll_islocked(futex) \
+ (futex != LLL_LOCK_INITIALIZER)
+
+/* The kernel notifies a process with uses CLONE_CLEARTID via futex
+ wakeup when the clone terminates. The memory location contains the
+ thread ID while the clone is running and is reset to zero
+ afterwards. */
+
+#define lll_wait_tid(tid) \
+ do { \
+ __typeof (tid) *__tid = &(tid); \
+ while (*__tid != 0) \
+ lll_futex_wait (__tid, *__tid, LLL_SHARED); \
+ } while (0)
+
+extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
+ attribute_hidden;
+#define lll_timedwait_tid(tid, abstime) \
+ ({ \
+ int __result = 0; \
+ if (tid != 0) \
+ { \
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) \
+ __result = EINVAL; \
+ else \
+ __result = __lll_timedwait_tid (&tid, abstime); \
+ } \
+ __result; })
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* lowlevellock.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S
new file mode 100644
index 000000000..1e05a56c0
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S
@@ -0,0 +1,265 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <lowlevellock.h>
+#include <lowlevelrobustlock.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+#include "lowlevel-atomic.h"
+
+ .text
+
+#define FUTEX_WAITERS 0x80000000
+#define FUTEX_OWNER_DIED 0x40000000
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
+ mov #(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), tmp; \
+ extu.b tmp, tmp; \
+ xor tmp, reg
+#else
+# if FUTEX_WAIT == 0
+# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, tmp2 ; \
+ add tmp2, tmp ; \
+ mov.l @tmp, tmp2 ; \
+ bra 98f ; \
+ mov #FUTEX_PRIVATE_FLAG, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: extu.b tmp, tmp ; \
+ xor tmp, reg ; \
+ and tmp2, reg
+# else
+# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
+ stc gbr, tmp ; \
+ mov.w 99f, tmp2 ; \
+ add tmp2, tmp ; \
+ mov.l @tmp, tmp2 ; \
+ bra 98f ; \
+ mov #FUTEX_PRIVATE_FLAG, tmp ; \
+99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
+98: extu.b tmp, tmp ; \
+ xor tmp, reg ; \
+ and tmp2, reg ; \
+ mov #FUTEX_WAIT, tmp ; \
+ or tmp, reg
+# endif
+#endif
+
+ .globl __lll_robust_lock_wait
+ .type __lll_robust_lock_wait,@function
+ .hidden __lll_robust_lock_wait
+ .align 5
+ cfi_startproc
+__lll_robust_lock_wait:
+ mov.l r8, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r8, 0)
+ mov r5, r8
+ mov #0, r7 /* No timeout. */
+ mov r6, r5
+ LOAD_FUTEX_WAIT (r5, r0, r1)
+
+4:
+ mov r4, r6
+ mov.l .L_FUTEX_WAITERS, r0
+ or r0, r6
+ shlr r0 /* r0 = FUTEX_OWNER_DIED */
+ tst r0, r4
+ bf/s 3f
+ cmp/eq r4, r6
+ bt 1f
+
+ CMPXCHG (r4, @r8, r6, r2)
+ bf 2f
+
+1:
+ mov r8, r4
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ mov.l @r8, r2
+
+2:
+ tst r2, r2
+ bf/s 4b
+ mov r2, r4
+
+ stc gbr, r1
+ mov.w .Ltidoff, r2
+ add r2, r1
+ mov.l @r1, r6
+ mov #0, r3
+ CMPXCHG (r3, @r8, r6, r4)
+ bf 4b
+ mov #0, r4
+
+3:
+ mov.l @r15+, r8
+ ret
+ mov r4, r0
+ cfi_endproc
+ .align 2
+.L_FUTEX_WAITERS:
+ .long FUTEX_WAITERS
+.Ltidoff:
+ .word TID - TLS_PRE_TCB_SIZE
+ .size __lll_robust_lock_wait,.-__lll_robust_lock_wait
+
+
+ .globl __lll_robust_timedlock_wait
+ .type __lll_robust_timedlock_wait,@function
+ .hidden __lll_robust_timedlock_wait
+ .align 5
+ cfi_startproc
+__lll_robust_timedlock_wait:
+ /* Check for a valid timeout value. */
+ mov.l @(4,r6), r1
+ mov.l .L1g, r0
+ cmp/hs r0, r1
+ bt 3f
+
+ mov.l r11, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r11, 0)
+ mov.l r10, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r10, 0)
+ mov.l r9, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r9, 0)
+ mov.l r8, @-r15
+ cfi_adjust_cfa_offset(4)
+ cfi_rel_offset (r8, 0)
+ mov r7, r11
+ mov r4, r10
+ mov r6, r9
+ mov r5, r8
+
+ /* Stack frame for the timespec and timeval structs. */
+ add #-8, r15
+ cfi_adjust_cfa_offset(8)
+
+1:
+ /* Get current time. */
+ mov r15, r4
+ mov #0, r5
+ mov #__NR_gettimeofday, r3
+ trapa #0x12
+ SYSCALL_INST_PAD
+
+ /* Compute relative timeout. */
+ mov.l @(4,r15), r0
+ mov.w .L1k, r1
+ dmulu.l r0, r1 /* Micro seconds to nano seconds. */
+ mov.l @r9, r2
+ mov.l @(4,r9), r3
+ mov.l @r15, r0
+ sts macl, r1
+ sub r0, r2
+ clrt
+ subc r1, r3
+ bf 4f
+ mov.l .L1g, r1
+ add r1, r3
+ add #-1, r2
+4:
+ cmp/pz r2
+ bf 8f /* Time is already up. */
+
+ mov.l r2, @r15 /* Store relative timeout. */
+ mov.l r3, @(4,r15)
+
+ mov r10, r6
+ mov.l .L_FUTEX_WAITERS2, r0
+ or r0, r6
+ shlr r0 /* r0 = FUTEX_OWNER_DIED */
+ tst r0, r4
+ bf/s 6f
+ cmp/eq r4, r6
+ bt 2f
+
+ CMPXCHG (r4, @r8, r6, r2)
+ bf/s 5f
+ mov #0, r5
+
+2:
+ mov r8, r4
+ mov r11, r5
+ LOAD_FUTEX_WAIT (r5, r0, r1)
+ mov r10, r6
+ mov r15, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+ mov r0, r5
+
+ mov.l @r8, r2
+
+5:
+ tst r2, r2
+ bf/s 7f
+ mov r2, r10
+
+ stc gbr, r1
+ mov.w .Ltidoff2, r2
+ add r2, r1
+ mov.l @r1, r4
+ mov #0, r3
+ CMPXCHG (r3, @r8, r4, r10)
+ bf 7f
+ mov #0, r0
+
+6:
+ add #8, r15
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ mov.l @r15+, r10
+ rts
+ mov.l @r15+, r11
+
+7:
+ /* Check whether the time expired. */
+ mov #-ETIMEDOUT, r1
+ cmp/eq r5, r1
+ bf 1b
+
+8:
+ bra 6b
+ mov #ETIMEDOUT, r0
+3:
+ rts
+ mov #EINVAL, r0
+ cfi_endproc
+ .align 2
+.L_FUTEX_WAITERS2:
+ .long FUTEX_WAITERS
+.L1g:
+ .long 1000000000
+.Ltidoff2:
+ .word TID - TLS_PRE_TCB_SIZE
+.L1k:
+ .word 1000
+ .size __lll_robust_timedlock_wait,.-__lll_robust_timedlock_wait
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pt-initfini.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pt-initfini.c
new file mode 100644
index 000000000..82c97c352
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pt-initfini.c
@@ -0,0 +1,126 @@
+/* Special .init and .fini section support for SH. NPTL version.
+ Copyright (C) 2003, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it
+ and/or modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Library General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The Library General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ The GNU C Library is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* This file is compiled into assembly code which is then munged by a sed
+ script into two files: crti.s and crtn.s.
+
+ * crti.s puts a function prologue at the beginning of the
+ .init and .fini sections and defines global symbols for
+ those addresses, so they can be called as functions.
+
+ * crtn.s puts the corresponding function epilogues
+ in the .init and .fini sections. */
+
+__asm__ ("\n\
+\n\
+#include \"defs.h\"\n\
+\n\
+/*@HEADER_ENDS*/\n\
+\n\
+/*@TESTS_BEGIN*/\n\
+\n\
+/*@TESTS_END*/\n\
+\n\
+/*@_init_PROLOG_BEGINS*/\n\
+ .section .init\n\
+ .align 5\n\
+ .global _init\n\
+ .type _init,@function\n\
+_init:\n\
+ mov.l r12,@-r15\n\
+ mov.l r14,@-r15\n\
+ sts.l pr,@-r15\n\
+ mova .L22,r0\n\
+ mov.l .L22,r12\n\
+ add r0,r12\n\
+ mova .L24,r0\n\
+ mov.l .L24,r1\n\
+ add r0,r1\n\
+ jsr @r1\n\
+ mov r15,r14\n\
+ bra 1f\n\
+ nop\n\
+ .align 2\n\
+.L22:\n\
+ .long _GLOBAL_OFFSET_TABLE_\n\
+.L24:\n\
+ .long __pthread_initialize_minimal_internal@PLT\n\
+1:\n\
+ ALIGN\n\
+ END_INIT\n\
+\n\
+/*@_init_PROLOG_ENDS*/\n\
+\n\
+/*@_init_EPILOG_BEGINS*/\n\
+ .section .init\n\
+ mov r14,r15\n\
+ lds.l @r15+,pr\n\
+ mov.l @r15+,r14\n\
+ rts \n\
+ mov.l @r15+,r12\n\
+ END_INIT\n\
+ \n\
+/*@_init_EPILOG_ENDS*/\n\
+\n\
+/*@_fini_PROLOG_BEGINS*/\n\
+ .section .fini\n\
+ .align 5\n\
+ .global _fini\n\
+ .type _fini,@function\n\
+_fini:\n\
+ mov.l r12,@-r15\n\
+ mov.l r14,@-r15\n\
+ sts.l pr,@-r15\n\
+ mova .L27,r0\n\
+ mov.l .L27,r12\n\
+ add r0,r12\n\
+ mov r15,r14\n\
+ ALIGN\n\
+ END_FINI\n\
+ bra 1f\n\
+ nop\n\
+ .align 2\n\
+.L27:\n\
+ .long _GLOBAL_OFFSET_TABLE_\n\
+1:\n\
+/*@_fini_PROLOG_ENDS*/\n\
+\n\
+/*@_fini_EPILOG_BEGINS*/\n\
+ .section .fini\n\
+ mov r14,r15\n\
+ lds.l @r15+,pr\n\
+ mov.l @r15+,r14\n\
+ rts \n\
+ mov.l @r15+,r12\n\
+\n\
+ END_FINI\n\
+ \n\
+/*@_fini_EPILOG_ENDS*/\n\
+\n\
+/*@TRAILER_BEGINS*/\n\
+");
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pt-vfork.S
new file mode 100644
index 000000000..54f2281d7
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pt-vfork.S
@@ -0,0 +1,65 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <tcb-offsets.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+ /* Save the PID value. */
+ stc gbr, r2
+ mov.w .L2, r0
+ mov.l @(r0,r2), r4
+ neg r4, r1
+ mov.l r1, @(r0,r2)
+
+ mov.w .L1, r3
+ trapa #0x10
+ mov r0, r1
+
+ /* Restore the old PID value in the parent. */
+ tst r0, r0
+ bt/s 2f
+ stc gbr, r2
+ mov.w .L2, r0
+ mov.l r4, @(r0,r2)
+ mov r1, r0
+2:
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lpseudo_end
+ SYSCALL_ERROR_HANDLER
+.Lpseudo_end:
+ rts
+ nop
+.L1:
+ .word __NR_vfork
+.L2:
+ .word PID - TLS_PRE_TCB_SIZE
+
+PSEUDO_END (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S
new file mode 100644
index 000000000..4a6059aef
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S
@@ -0,0 +1,216 @@
+/* Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelbarrier.h>
+#include "lowlevel-atomic.h"
+
+ .text
+
+ .globl pthread_barrier_wait
+ .type pthread_barrier_wait,@function
+ .align 5
+pthread_barrier_wait:
+ mov.l r9, @-r15
+ mov.l r8, @-r15
+ sts.l pr, @-r15
+ mov r4, r8
+
+ /* Get the mutex. */
+ mov #0, r3
+ mov #1, r4
+ CMPXCHG (r3, @(MUTEX,r8), r4, r2)
+ bf 1f
+
+ /* One less waiter. If this was the last one needed wake
+ everybody. */
+2:
+ mov.l @(LEFT,r8), r0
+ add #-1, r0
+ mov.l r0, @(LEFT,r8)
+ tst r0, r0
+ bt 3f
+
+ /* There are more threads to come. */
+ mov.l @(CURR_EVENT,r8), r6
+
+ /* Release the mutex. */
+ DEC (@(MUTEX,r8), r2)
+ tst r2, r2
+ bf 6f
+7:
+ /* Wait for the remaining threads. The call will return immediately
+ if the CURR_EVENT memory has meanwhile been changed. */
+ mov r8, r4
+#if CURR_EVENT != 0
+ add #CURR_EVENT, r4
+#endif
+#if FUTEX_WAIT == 0
+ mov.l @(PRIVATE,r8), r5
+#else
+ mov #FUTEX_WAIT, r5
+ mov.l @(PRIVATE,r8), r0
+ or r0, r5
+#endif
+ mov #0, r7
+8:
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ /* Don't return on spurious wakeups. The syscall does not change
+ any register except r0 so there is no need to reload any of
+ them. */
+ mov.l @(CURR_EVENT,r8), r0
+ cmp/eq r0, r6
+ bt 8b
+
+ /* Increment LEFT. If this brings the count back to the
+ initial count unlock the object. */
+ mov #1, r3
+ mov.l @(INIT_COUNT,r8), r4
+ XADD (r3, @(LEFT,r8), r2, r5)
+ add #-1, r4
+ cmp/eq r2, r4
+ bf 10f
+
+ /* Release the mutex. We cannot release the lock before
+ waking the waiting threads since otherwise a new thread might
+ arrive and gets waken up, too. */
+ DEC (@(MUTEX,r8), r2)
+ tst r2, r2
+ bf 9f
+
+10:
+ mov #0, r0 /* != PTHREAD_BARRIER_SERIAL_THREAD */
+ lds.l @r15+, pr
+ mov.l @r15+, r8
+ rts
+ mov.l @r15+, r9
+
+3:
+ /* The necessary number of threads arrived. */
+ mov.l @(CURR_EVENT,r8), r1
+ add #1, r1
+ mov.l r1, @(CURR_EVENT,r8)
+
+ /* Wake up all waiters. The count is a signed number in the kernel
+ so 0x7fffffff is the highest value. */
+ mov.l .Lall, r6
+ mov r8, r4
+#if CURR_EVENT != 0
+ add #CURR_EVENT, r4
+#endif
+ mov #0, r7
+ mov #FUTEX_WAKE, r5
+ mov.l @(PRIVATE,r8), r0
+ or r0, r5
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ /* Increment LEFT. If this brings the count back to the
+ initial count unlock the object. */
+ mov #1, r3
+ mov.l @(INIT_COUNT,r8), r4
+ XADD (r3, @(LEFT,r8), r2, r5)
+ add #-1, r4
+ cmp/eq r2, r4
+ bf 5f
+
+ /* Release the mutex. */
+ DEC (@(MUTEX,r8), r2)
+ tst r2, r2
+ bf 4f
+5:
+ mov #-1, r0 /* == PTHREAD_BARRIER_SERIAL_THREAD */
+ lds.l @r15+, pr
+ mov.l @r15+, r8
+ rts
+ mov.l @r15+, r9
+
+1:
+ mov.l @(PRIVATE,r8), r6
+ mov #LLL_SHARED, r0
+ extu.b r0, r0
+ xor r0, r6
+ mov r2, r4
+ mov r8, r5
+ mov.l .Lwait0, r1
+ bsrf r1
+ add #MUTEX, r5
+.Lwait0b:
+ bra 2b
+ nop
+
+4:
+ mov.l @(PRIVATE,r8), r5
+ mov #LLL_SHARED, r0
+ extu.b r0, r0
+ xor r0, r5
+ mov r8, r4
+ mov.l .Lwake0, r1
+ bsrf r1
+ add #MUTEX, r4
+.Lwake0b:
+ bra 5b
+ nop
+
+6:
+ mov r6, r9
+ mov.l @(PRIVATE,r8), r5
+ mov #LLL_SHARED, r0
+ extu.b r0, r0
+ xor r0, r5
+ mov r8, r4
+ mov.l .Lwake1, r1
+ bsrf r1
+ add #MUTEX, r4
+.Lwake1b:
+ bra 7b
+ mov r9, r6
+
+9:
+ mov r6, r9
+ mov.l @(PRIVATE,r8), r5
+ mov #LLL_SHARED, r0
+ extu.b r0, r0
+ xor r0, r5
+ mov r8, r4
+ mov.l .Lwake2, r1
+ bsrf r1
+ add #MUTEX, r4
+.Lwake2b:
+ bra 10b
+ mov r9, r6
+
+ .align 2
+.Lall:
+ .long 0x7fffffff
+.Lwait0:
+ .long __lll_lock_wait-.Lwait0b
+.Lwake0:
+ .long __lll_unlock_wake-.Lwake0b
+.Lwake1:
+ .long __lll_unlock_wake-.Lwake1b
+.Lwake2:
+ .long __lll_unlock_wake-.Lwake2b
+ .size pthread_barrier_wait,.-pthread_barrier_wait
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
new file mode 100644
index 000000000..233183177
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
@@ -0,0 +1,263 @@
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelcond.h>
+#include <bits/kernel-features.h>
+#include <pthread-pi-defines.h>
+#include <pthread-errnos.h>
+#include <tcb-offsets.h>
+#include "lowlevel-atomic.h"
+
+ .text
+
+ /* int pthread_cond_broadcast (pthread_cond_t *cond) */
+ .globl __pthread_cond_broadcast
+ .type __pthread_cond_broadcast, @function
+ .protected __pthread_cond_broadcast
+ .align 5
+__pthread_cond_broadcast:
+ mov.l r10, @-r15
+ mov.l r9, @-r15
+ mov.l r8, @-r15
+ sts.l pr, @-r15
+ mov r4, r8
+
+ /* Get internal lock. */
+ mov #0, r3
+ mov #1, r4
+#if cond_lock != 0
+ CMPXCHG (r3, @(cond_lock,r8), r4, r2)
+#else
+ CMPXCHG (r3, @r8, r4, r2)
+#endif
+ bf 1f
+2:
+ mov.l @(total_seq+4,r8),r0
+ mov.l @(total_seq,r8),r1
+ mov.l @(wakeup_seq+4,r8), r2
+ cmp/hi r2, r0
+ bt 3f
+ cmp/hi r0, r2
+ bt 4f
+ mov.l @(wakeup_seq,r8), r2
+ cmp/hi r2, r1
+ bf 4f
+
+3:
+ /* Cause all currently waiting threads to recognize they are
+ woken up. */
+ mov.l r1, @(wakeup_seq,r8)
+ mov.l r0, @(wakeup_seq+4,r8)
+ mov.l r1, @(woken_seq,r8)
+ mov.l r0, @(woken_seq+4,r8)
+ mov.l @(broadcast_seq,r8), r2
+ add #1, r2
+ mov.l r2, @(broadcast_seq,r8)
+ add r1, r1
+ mov r1, r10
+ mov.l r10, @(cond_futex,r8)
+
+ /* Get the address of the mutex used. */
+ mov.l @(dep_mutex,r8), r9
+
+ /* Unlock. */
+#if cond_lock != 0
+ DEC (@(cond_lock,r8), r2)
+#else
+ DEC (@r8, r2)
+#endif
+ tst r2, r2
+ bf 7f
+
+8:
+ /* Don't use requeue for pshared condvars. */
+ mov #-1, r0
+ cmp/eq r0, r9
+ mov r8, r4
+ bt/s 9f
+ add #cond_futex, r4
+
+ /* XXX: The kernel only supports FUTEX_CMP_REQUEUE to the same
+ type of futex (private resp. shared). */
+ mov.l @(MUTEX_KIND,r9), r0
+ tst #(PI_BIT|PS_BIT), r0
+ bf 9f
+
+ /* Wake up all threads. */
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_CMP_REQUEUE, r0
+ or r0, r5
+#endif
+ mov #1, r6
+ mov #-1, r7
+ shlr r7 /* r7 = 0x7fffffff */
+ mov r9, r0
+# if MUTEX_FUTEX != 0
+ add #MUTEX_FUTEX, r0
+# endif
+ mov r10, r1
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x16
+ SYSCALL_INST_PAD
+
+ /* For any kind of error, which mainly is EAGAIN, we try again
+ with WAKE. The general test also covers running on old
+ kernels. */
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1
+ tst r1, r1
+ mov r8, r4
+ bt/s 9f
+ add #cond_futex, r4
+
+10:
+ mov #0, r0
+ lds.l @r15+, pr
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ rts
+ mov.l @r15+, r10
+
+4:
+ /* Unlock. */
+#if cond_lock != 0
+ DEC (@(cond_lock,r8), r2)
+#else
+ DEC (@r8, r2)
+#endif
+ tst r2, r2
+ bf 5f
+6:
+ mov #0, r0
+ lds.l @r15+, pr
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ rts
+ mov.l @r15+, r10
+
+1:
+ /* Initial locking failed. */
+ mov r8, r5
+#if cond_lock != 0
+ add #cond_lock, r5
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait5, r1
+ bsrf r1
+ mov r2, r4
+.Lwait5b:
+ bra 2b
+ nop
+
+5:
+ /* Unlock in loop requires wakeup. */
+ mov r8, r4
+#if cond_lock != 0
+ add #cond_lock, r4
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake5, r1
+ bsrf r1
+ extu.b r5, r5
+.Lwake5b:
+ bra 6b
+ nop
+
+7:
+ /* Unlock in loop requires wakeup. */
+ mov r8, r4
+#if cond_lock != 0
+ add #cond_lock, r4
+#endif
+ mov #-1, r0
+ cmp/eq r0, r9
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake6, r1
+ bsrf r1
+ extu.b r5, r5
+.Lwake6b:
+ bra 8b
+ nop
+
+9:
+ mov #-1, r0
+ cmp/eq r0, r9
+ bt/s 99f
+ mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+99:
+ mov #-1, r6
+ shlr r6 /* r6 = 0x7fffffff */
+ mov #0, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+ bra 10b
+ nop
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+
+ .align 2
+.Lwait5:
+ .long __lll_lock_wait-.Lwait5b
+.Lwake5:
+ .long __lll_unlock_wake-.Lwake5b
+.Lwake6:
+ .long __lll_unlock_wake-.Lwake6b
+ .size __pthread_cond_broadcast, .-__pthread_cond_broadcast
+weak_alias (__pthread_cond_broadcast, pthread_cond_broadcast)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S
new file mode 100644
index 000000000..ca87336d9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S
@@ -0,0 +1,190 @@
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelcond.h>
+#include <bits/kernel-features.h>
+#include <pthread-errnos.h>
+#include <tcb-offsets.h>
+#include "lowlevel-atomic.h"
+
+ .text
+
+ /* int pthread_cond_signal (pthread_cond_t *cond) */
+ .globl __pthread_cond_signal
+ .type __pthread_cond_signal, @function
+ .protected __pthread_cond_signal
+ .align 5
+__pthread_cond_signal:
+ mov.l r8, @-r15
+ sts.l pr, @-r15
+ mov r4, r8
+
+ /* Get internal lock. */
+ mov #0, r3
+ mov #1, r4
+#if cond_lock != 0
+ CMPXCHG (r3, @(cond_lock,r8), r4, r2)
+#else
+ CMPXCHG (r3, @r8, r4, r2)
+#endif
+ bf 1f
+2:
+ mov.l @(total_seq+4,r8),r0
+ mov.l @(total_seq,r8),r1
+ mov.l @(wakeup_seq+4,r8), r2
+ cmp/hi r2, r0
+ bt 3f
+ cmp/hi r0, r2
+ bt 4f
+ mov.l @(wakeup_seq,r8), r2
+ cmp/hi r2, r1
+ bf 4f
+
+3:
+ /* Bump the wakeup number. */
+ mov #1, r2
+ mov #0, r3
+ clrt
+ mov.l @(wakeup_seq,r8),r0
+ mov.l @(wakeup_seq+4,r8),r1
+ addc r2, r0
+ addc r3, r1
+ mov.l r0,@(wakeup_seq,r8)
+ mov.l r1,@(wakeup_seq+4,r8)
+ mov.l @(cond_futex,r8),r0
+ add r2, r0
+ mov.l r0,@(cond_futex,r8)
+
+ /* Wake up one thread. */
+ mov r8, r4
+ add #cond_futex, r4
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAKE_OP, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE_OP, r0
+ or r0, r5
+#endif
+99:
+ mov #1, r6
+ mov #0, r7
+ mov r8, r0
+ add #cond_lock, r0
+ mov.l .Lfutexop, r1
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ /* For any kind of error, we try again with WAKE.
+ The general test also covers running on old kernels. */
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1
+ tst r1, r1
+ bt 7f
+
+6:
+ mov #0, r0
+ lds.l @r15+, pr
+ rts
+ mov.l @r15+, r8
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+ .align 2
+.Lfutexop:
+ .long FUTEX_OP_CLEAR_WAKE_IF_GT_ONE
+
+7:
+ /* r5 should be either FUTEX_WAKE_OP or
+ FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG from the previous syscall. */
+ mov #(FUTEX_WAKE ^ FUTEX_WAKE_OP), r0
+ xor r0, r5
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+4:
+ /* Unlock. */
+#if cond_lock != 0
+ DEC (@(cond_lock,r8), r2)
+#else
+ DEC (@r8, r2)
+#endif
+ tst r2, r2
+ bt 6b
+
+5:
+ /* Unlock in loop requires wakeup. */
+ mov r8, r4
+#if cond_lock != 0
+ add #cond_lock, r4
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake4, r1
+ bsrf r1
+ extu.b r5, r5
+.Lwake4b:
+ bra 6b
+ nop
+
+1:
+ /* Initial locking failed. */
+ mov r8, r5
+#if cond_lock != 0
+ add #cond_lock, r5
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait4, r1
+ bsrf r1
+ mov r2, r4
+.Lwait4b:
+ bra 2b
+ nop
+
+ .align 2
+.Lwait4:
+ .long __lll_lock_wait-.Lwait4b
+.Lwake4:
+ .long __lll_unlock_wake-.Lwake4b
+ .size __pthread_cond_signal, .-__pthread_cond_signal
+weak_alias (__pthread_cond_signal, pthread_cond_signal)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
new file mode 100644
index 000000000..cacb037d8
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
@@ -0,0 +1,861 @@
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelcond.h>
+#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+#include "lowlevel-atomic.h"
+
+ .text
+
+/* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
+ const struct timespec *abstime) */
+ .globl __pthread_cond_timedwait
+ .type __pthread_cond_timedwait, @function
+ .protected __pthread_cond_timedwait
+ .align 5
+__pthread_cond_timedwait:
+.LSTARTCODE:
+ mov.l r8, @-r15
+.Lpush_r8:
+ mov.l r9, @-r15
+.Lpush_r9:
+ mov.l r10, @-r15
+.Lpush_r10:
+ mov.l r11, @-r15
+.Lpush_r11:
+ mov.l r12, @-r15
+.Lpush_r12:
+ mov.l r13, @-r15
+.Lpush_r13:
+ sts.l pr, @-r15
+.Lpush_pr:
+ add #-64, r15
+.Lalloc:
+ mov r4, r8
+ mov r5, r9
+ mov r6, r13
+#ifdef __PIC__
+ mova .Lgot0, r0
+ mov.l .Lgot0, r12
+ add r0, r12
+#endif
+
+ mov.l @(4,r13), r0
+ mov.l .L1g, r1
+ cmp/hs r1, r0
+ bf 0f
+ bra 18f
+ mov #EINVAL, r0
+0:
+ /* Get internal lock. */
+ mov #0, r3
+ mov #1, r4
+#if cond_lock != 0
+ CMPXCHG (r3, @(cond_lock,r8), r4, r2)
+#else
+ CMPXCHG (r3, @r8, r4, r2)
+#endif
+ bt 2f
+ bra 1f
+ nop
+#ifdef __PIC__
+ .align 2
+.Lgot0:
+ .long _GLOBAL_OFFSET_TABLE_
+#endif
+
+2:
+ /* Store the reference to the mutex. If there is already a
+ different value in there this is a bad user bug. */
+ mov.l @(dep_mutex,r8),r0
+ cmp/eq #-1, r0
+ bt 17f
+ mov.l r9, @(dep_mutex,r8)
+
+17:
+ /* Unlock the mutex. */
+ mov.l .Lmunlock1, r1
+ mov #0, r5
+ bsrf r1
+ mov r9, r4
+.Lmunlock1b:
+
+ tst r0, r0
+ bt 0f
+ bra 16f
+ nop
+0:
+ mov #1, r2
+ mov #0, r3
+
+ clrt
+ mov.l @(total_seq,r8),r0
+ mov.l @(total_seq+4,r8),r1
+ addc r2, r0
+ addc r3, r1
+ mov.l r0,@(total_seq,r8)
+ mov.l r1,@(total_seq+4,r8)
+ mov.l @(cond_futex,r8), r0
+ add r2, r0
+ mov.l r0, @(cond_futex,r8)
+ mov #(1 << nwaiters_shift), r2
+ mov.l @(cond_nwaiters,r8), r0
+ add r2, r0
+ mov.l r0, @(cond_nwaiters,r8)
+
+ /* Get and store current wakeup_seq value. */
+ mov.l @(wakeup_seq,r8), r10
+ mov.l @(wakeup_seq+4,r8), r11
+ mov.l @(broadcast_seq,r8), r0
+ mov.l r0, @(4,r15)
+
+8:
+ /* Get current time. */
+#ifdef __NR_clock_gettime
+ /* Get the clock number. */
+ mov.l @(cond_nwaiters,r8), r4
+ mov #((1 << nwaiters_shift) - 1), r0
+ and r0, r4
+ /* Only clocks 0 and 1 are allowed. Both are handled in the
+ kernel. */
+ mov r15, r5
+ add #16, r5
+ mov.w .L__NR_clock_gettime, r3
+ trapa #0x12
+ SYSCALL_INST_PAD
+# ifndef __ASSUME_POSIX_TIMERS
+ cmp/eq #-ENOSYS, r0
+ bt 19f
+# endif
+
+ /* Compute relative timeout. */
+ mov.l @r13, r2
+ mov.l @(4,r13), r3
+ mov.l @(16,r15), r0
+ bra 0f
+ mov.l @(20,r15), r1
+.L__NR_clock_gettime:
+ .word __NR_clock_gettime
+
+# ifndef __ASSUME_POSIX_TIMERS
+19:
+ mov r15, r4
+ add #16, r4
+ mov #0, r5
+ mov #__NR_gettimeofday, r3
+ trapa #0x12
+ SYSCALL_INST_PAD
+
+ /* Compute relative timeout. */
+ mov.l @(20,r15), r0
+ mov.w .L1k, r1
+ dmulu.l r0, r1 /* Micro seconds to nano seconds. */
+ mov.l @r13, r2
+ mov.l @(4,r13), r3
+ mov.l @(16,r15), r0
+ sts macl, r1
+#endif
+0:
+#else
+ mov r15, r4
+ add #16, r4
+ mov #0, r5
+ mov #__NR_gettimeofday, r3
+ trapa #0x12
+ SYSCALL_INST_PAD
+
+ /* Compute relative timeout. */
+ mov.l @(20,r15), r0
+ mov.w .L1k, r1
+ dmulu.l r0, r1 /* Micro seconds to nano seconds. */
+ mov.l @r13, r2
+ mov.l @(4,r13), r3
+ mov.l @(16,r15), r0
+ sts macl, r1
+#endif
+ sub r0, r2
+ clrt
+ subc r1, r3
+ bf 12f
+ mov.l .L1g, r1
+ add r1, r3
+ add #-1, r2
+12:
+ mov #-ETIMEDOUT, r1
+ mov.l r1, @(12,r15)
+ cmp/pz r2
+ bf 6f /* Time is already up. */
+
+ /* Store relative timeout. */
+ mov.l r2, @(16,r15)
+ mov.l r3, @(20,r15)
+ mov.l @(cond_futex,r8), r1
+ mov.l r1, @(8,r15)
+
+ /* Unlock. */
+#if cond_lock != 0
+ DEC (@(cond_lock,r8), r2)
+#else
+ DEC (@r8, r2)
+#endif
+ tst r2, r2
+ bt 4f
+ bra 3f
+ nop
+4:
+.LcleanupSTART:
+ mov.l .Lenable1, r1
+ bsrf r1
+ nop
+.Lenable1b:
+ mov.l r0, @r15
+
+ mov r15, r7
+ add #16, r7
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAIT, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+#endif
+99:
+ mov.l @(8,r15), r6
+ mov r8, r4
+ add #cond_futex, r4
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+ mov.l r0, @(12,r15)
+
+ mov.l .Ldisable1, r1
+ bsrf r1
+ mov.l @r15, r4
+.Ldisable1b:
+.LcleanupEND:
+
+ /* Lock. */
+ mov #0, r3
+ mov #1, r4
+#if cond_lock != 0
+ CMPXCHG (r3, @(cond_lock,r8), r4, r2)
+#else
+ CMPXCHG (r3, @r8, r4, r2)
+#endif
+ bf 5f
+6:
+ mov.l @(broadcast_seq,r8), r0
+ mov.l @(4,r15), r1
+ cmp/eq r0, r1
+ bf 23f
+
+ mov.l @(woken_seq,r8), r0
+ mov.l @(woken_seq+4,r8), r1
+
+ mov.l @(wakeup_seq,r8), r2
+ mov.l @(wakeup_seq+4,r8), r3
+
+ cmp/eq r3, r11
+ bf 7f
+ cmp/eq r2, r10
+ bt 15f
+7:
+ cmp/eq r1, r3
+ bf 9f
+ cmp/eq r0, r2
+ bf 9f
+15:
+ mov.l @(12,r15),r0
+ cmp/eq #-ETIMEDOUT, r0
+ bf 8b
+
+ mov #1, r2
+ mov #0, r3
+
+ clrt
+ mov.l @(wakeup_seq,r8),r0
+ mov.l @(wakeup_seq+4,r8),r1
+ addc r2, r0
+ addc r3, r1
+ mov.l r0,@(wakeup_seq,r8)
+ mov.l r1,@(wakeup_seq+4,r8)
+ mov.l @(cond_futex,r8),r0
+ add r2, r0
+ mov.l r0,@(cond_futex,r8)
+ mov #ETIMEDOUT, r0
+ bra 14f
+ mov.l r0, @(24,r15)
+
+23:
+ mov #0, r0
+ bra 24f
+ mov.l r0, @(24,r15)
+
+9:
+ mov #0, r0
+ mov.l r0, @(24,r15)
+14:
+ mov #1, r2
+ mov #0, r3
+
+ clrt
+ mov.l @(woken_seq,r8),r0
+ mov.l @(woken_seq+4,r8),r1
+ addc r2, r0
+ addc r3, r1
+ mov.l r0,@(woken_seq,r8)
+ mov.l r1,@(woken_seq+4,r8)
+
+24:
+ mov #(1 << nwaiters_shift), r2
+ mov.l @(cond_nwaiters,r8),r0
+ sub r2, r0
+ mov.l r0,@(cond_nwaiters,r8)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ mov.l @(total_seq,r8),r0
+ mov.l @(total_seq+4,r8),r1
+ and r1, r0
+ not r0, r0
+ cmp/eq #0, r0
+ bf/s 25f
+ mov #((1 << nwaiters_shift) - 1), r1
+ not r1, r1
+ mov.l @(cond_nwaiters,r8),r0
+ tst r1, r0
+ bf 25f
+
+ mov r8, r4
+ add #cond_nwaiters, r4
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+99:
+ mov #1, r6
+ mov #0, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+25:
+#if cond_lock != 0
+ DEC (@(cond_lock,r8), r2)
+#else
+ DEC (@r8, r2)
+#endif
+ tst r2, r2
+ bf 10f
+
+11:
+ mov r9, r4
+ mov.l .Lmlocki1, r1
+ bsrf r1
+ nop
+.Lmlocki1b:
+
+ /* We return the result of the mutex_lock operation if it failed. */
+ tst r0, r0
+ bf 18f
+ mov.l @(24,r15), r0
+
+18:
+ add #64, r15
+ lds.l @r15+, pr
+ mov.l @r15+, r13
+ mov.l @r15+, r12
+ mov.l @r15+, r11
+ mov.l @r15+, r10
+ mov.l @r15+, r9
+ rts
+ mov.l @r15+, r8
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+.L1k:
+ .word 1000
+ .align 2
+.Lmunlock1:
+ .long __pthread_mutex_unlock_usercnt-.Lmunlock1b
+.Lenable1:
+ .long __pthread_enable_asynccancel-.Lenable1b
+.Ldisable1:
+ .long __pthread_disable_asynccancel-.Ldisable1b
+.Lmlocki1:
+ .long __pthread_mutex_cond_lock-.Lmlocki1b
+.L1g:
+ .long 1000000000
+
+1:
+ /* Initial locking failed. */
+ mov r8, r5
+#if cond_lock != 0
+ add #cond_lock, r5
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait2, r1
+ bsrf r1
+ mov r2, r4
+.Lwait2b:
+ bra 2b
+ nop
+
+3:
+ /* Unlock in loop requires wakeup. */
+ mov r8, r4
+#if cond_lock != 0
+ add #cond_lock, r4
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lmwait2, r1
+ bsrf r1
+ extu.b r5, r5
+.Lmwait2b:
+ bra 4b
+ nop
+
+5:
+ /* Locking in loop failed. */
+ mov r8, r5
+#if cond_lock != 0
+ add #cond_lock, r5
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait3, r1
+ bsrf r1
+ mov r2, r4
+.Lwait3b:
+ bra 6b
+ nop
+
+10:
+ /* Unlock after loop requires wakeup. */
+ mov r8, r4
+#if cond_lock != 0
+ add #cond_lock, r4
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lmwait3, r1
+ bsrf r1
+ extu.b r5, r5
+.Lmwait3b:
+ bra 11b
+ nop
+
+16:
+ /* The initial unlocking of the mutex failed. */
+ mov.l r0, @(24,r15)
+#if cond_lock != 0
+ DEC (@(cond_lock,r8), r2)
+#else
+ DEC (@r8, r2)
+#endif
+ tst r2, r2
+ bf 17f
+
+ mov r8, r4
+#if cond_lock != 0
+ add #cond_lock, r4
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lmwait4, r1
+ bsrf r1
+ extu.b r5, r5
+.Lmwait4b:
+17:
+ bra 18b
+ mov.l @(24,r15), r0
+
+ .align 2
+.Lwait2:
+ .long __lll_lock_wait-.Lwait2b
+.Lmwait2:
+ .long __lll_unlock_wake-.Lmwait2b
+.Lwait3:
+ .long __lll_lock_wait-.Lwait3b
+.Lmwait3:
+ .long __lll_unlock_wake-.Lmwait3b
+.Lmwait4:
+ .long __lll_unlock_wake-.Lmwait4b
+ .size __pthread_cond_timedwait, .-__pthread_cond_timedwait
+weak_alias (__pthread_cond_timedwait, pthread_cond_timedwait)
+
+
+ .type __condvar_tw_cleanup, @function
+__condvar_tw_cleanup:
+ mov r4, r11
+
+ /* Get internal lock. */
+ mov #0, r3
+ mov #1, r4
+#if cond_lock != 0
+ CMPXCHG (r3, @(cond_lock,r8), r4, r2)
+#else
+ CMPXCHG (r3, @r8, r4, r2)
+#endif
+ bt 1f
+ nop
+
+ mov r8, r5
+#if cond_lock != 0
+ add #cond_lock, r5
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait5, r1
+ bsrf r1
+ mov r2, r4
+.Lwait5b:
+
+1:
+ mov.l @(broadcast_seq,r8), r0
+ mov.l @(4,r15), r1
+ cmp/eq r0, r1
+ bf 3f
+
+ mov #1, r2
+ mov #0, r3
+
+ /* We increment the wakeup_seq counter only if it is lower than
+ total_seq. If this is not the case the thread was woken and
+ then canceled. In this case we ignore the signal. */
+ mov.l @(total_seq+4,r8), r0
+ mov.l @(wakeup_seq+4,r8), r1
+ cmp/hi r1, r0
+ bt/s 6f
+ cmp/hi r0, r1
+ bt 7f
+ mov.l @(total_seq,r8), r0
+ mov.l @(wakeup_seq,r8), r1
+ cmp/hs r0, r1
+ bt 7f
+
+6:
+ clrt
+ mov.l @(wakeup_seq,r8),r0
+ mov.l @(wakeup_seq+4,r8),r1
+ addc r2, r0
+ addc r3, r1
+ mov.l r0,@(wakeup_seq,r8)
+ mov.l r1,@(wakeup_seq+4,r8)
+ mov.l @(cond_futex,r8),r0
+ add r2, r0
+ mov.l r0,@(cond_futex,r8)
+
+7:
+ clrt
+ mov.l @(woken_seq,r8),r0
+ mov.l @(woken_seq+4,r8),r1
+ addc r2, r0
+ addc r3, r1
+ mov.l r0,@(woken_seq,r8)
+ mov.l r1,@(woken_seq+4,r8)
+
+3:
+ mov #(1 << nwaiters_shift), r2
+ mov.l @(cond_nwaiters,r8),r0
+ sub r2, r0
+ mov.l r0,@(cond_nwaiters,r8)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ mov #0, r10
+ mov.l @(total_seq,r8),r0
+ mov.l @(total_seq+4,r8),r1
+ and r1, r0
+ not r0, r0
+ cmp/eq #0, r0
+ bf/s 4f
+ mov #((1 << nwaiters_shift) - 1), r1
+ not r1, r1
+ mov.l @(cond_nwaiters,r8),r0
+ tst r1, r0
+ bf 4f
+
+ mov r8, r4
+ add #cond_nwaiters, r4
+ mov #FUTEX_WAKE, r5
+ mov #1, r6
+ mov #0, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+ mov #1, r10
+
+4:
+#if cond_lock != 0
+ DEC (@(cond_lock,r8), r2)
+#else
+ DEC (@r8, r2)
+#endif
+ tst r2, r2
+ bt 2f
+
+ mov r8, r4
+#if cond_lock != 0
+ add #cond_lock, r4
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lmwait5, r1
+ bsrf r1
+ extu.b r5, r5
+.Lmwait5b:
+
+2:
+ /* Wake up all waiters to make sure no signal gets lost. */
+ tst r10, r10
+ bf/s 5f
+ mov r8, r4
+ add #cond_futex, r4
+ mov #FUTEX_WAKE, r5
+ mov #-1, r6
+ shlr r6 /* r6 = 0x7fffffff */
+ mov #0, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+5:
+ mov.l .Lmlocki5, r1
+ bsrf r1
+ mov r9, r4
+.Lmlocki5b:
+
+.LcallUR:
+ mov.l .Lresume, r1
+#ifdef __PIC__
+ add r12, r1
+#endif
+ jsr @r1
+ mov r11, r4
+ sleep
+
+ .align 2
+.Lwait5:
+ .long __lll_lock_wait-.Lwait5b
+.Lmwait5:
+ .long __lll_unlock_wake-.Lmwait5b
+.Lmlocki5:
+ .long __pthread_mutex_cond_lock-.Lmlocki5b
+.Lresume:
+#ifdef __PIC__
+ .long _Unwind_Resume@GOTOFF
+#else
+ .long _Unwind_Resume
+#endif
+.LENDCODE:
+ .size __condvar_tw_cleanup, .-__condvar_tw_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff ! @LPStart format (omit)
+ .byte 0xff ! @TType format (omit)
+ .byte 0x0b ! call-site format
+ ! DW_EH_PE_sdata4
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .ualong .LcleanupSTART-.LSTARTCODE
+ .ualong .LcleanupEND-.LcleanupSTART
+ .ualong __condvar_tw_cleanup-.LSTARTCODE
+ .uleb128 0
+ .ualong .LcallUR-.LSTARTCODE
+ .ualong .LENDCODE-.LcallUR
+ .ualong 0
+ .uleb128 0
+.Lcstend:
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+ .ualong .LENDCIE-.LSTARTCIE ! Length of the CIE.
+.LSTARTCIE:
+ .ualong 0 ! CIE ID.
+ .byte 1 ! Version number.
+#ifdef SHARED
+ .string "zPLR" ! NUL-terminated augmentation
+ ! string.
+#else
+ .string "zPL" ! NUL-terminated augmentation
+ ! string.
+#endif
+ .uleb128 1 ! Code alignment factor.
+ .sleb128 -4 ! Data alignment factor.
+ .byte 0x11 ! Return address register
+ ! column.
+#ifdef SHARED
+ .uleb128 7 ! Augmentation value length.
+ .byte 0x9b ! Personality: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4
+ ! + DW_EH_PE_indirect
+ .ualong DW.ref.__gcc_personality_v0-.
+ .byte 0x1b ! LSDA Encoding: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4.
+ .byte 0x1b ! FDE Encoding: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4.
+#else
+ .uleb128 6 ! Augmentation value length.
+ .byte 0x0 ! Personality: absolute
+ .ualong __gcc_personality_v0
+ .byte 0x0 ! LSDA Encoding: absolute
+#endif
+ .byte 0x0c ! DW_CFA_def_cfa
+ .uleb128 0xf
+ .uleb128 0
+ .align 2
+.LENDCIE:
+
+ .ualong .LENDFDE-.LSTARTFDE ! Length of the FDE.
+.LSTARTFDE:
+ .ualong .LSTARTFDE-.LSTARTFRAME ! CIE pointer.
+#ifdef SHARED
+ .ualong .LSTARTCODE-. ! PC-relative start address
+ ! of the code.
+#else
+ .ualong .LSTARTCODE ! Start address of the code.
+#endif
+ .ualong .LENDCODE-.LSTARTCODE ! Length of the code.
+ .uleb128 4 ! Augmentation size
+#ifdef SHARED
+ .ualong .LexceptSTART-.
+#else
+ .ualong .LexceptSTART
+#endif
+ .byte 0x4
+ .ualong .Lpush_r8-.LSTARTCODE
+ .byte 0xe
+ .uleb128 4
+ .byte 0x88
+ .uleb128 1
+ .byte 0x4
+ .ualong .Lpush_r9-.Lpush_r8
+ .byte 0xe
+ .uleb128 8
+ .byte 0x89
+ .uleb128 2
+ .byte 0x4
+ .ualong .Lpush_r10-.Lpush_r9
+ .byte 0xe
+ .uleb128 12
+ .byte 0x8a
+ .uleb128 3
+ .byte 0x4
+ .ualong .Lpush_r11-.Lpush_r10
+ .byte 0xe
+ .uleb128 16
+ .byte 0x8b
+ .uleb128 4
+ .byte 0x4
+ .ualong .Lpush_r12-.Lpush_r11
+ .byte 0xe
+ .uleb128 20
+ .byte 0x8c
+ .uleb128 5
+ .byte 0x4
+ .ualong .Lpush_r13-.Lpush_r12
+ .byte 0xe
+ .uleb128 24
+ .byte 0x8d
+ .uleb128 6
+ .byte 0x4
+ .ualong .Lpush_pr-.Lpush_r13
+ .byte 0xe
+ .uleb128 28
+ .byte 0x91
+ .uleb128 7
+ .byte 0x4
+ .ualong .Lalloc-.Lpush_pr
+ .byte 0xe
+ .uleb128 92
+ .align 2
+.LENDFDE:
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
new file mode 100644
index 000000000..b0a4e9888
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
@@ -0,0 +1,754 @@
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelcond.h>
+#include <tcb-offsets.h>
+#include <bits/kernel-features.h>
+#include "lowlevel-atomic.h"
+
+ .text
+
+/* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
+ .globl __pthread_cond_wait
+ .type __pthread_cond_wait, @function
+ .protected __pthread_cond_wait
+ .align 5
+__pthread_cond_wait:
+.LSTARTCODE:
+ mov.l r8, @-r15
+.Lpush_r8:
+ mov.l r9, @-r15
+.Lpush_r9:
+ mov.l r10, @-r15
+.Lpush_r10:
+ mov.l r11, @-r15
+.Lpush_r11:
+ mov.l r12, @-r15
+.Lpush_r12:
+ sts.l pr, @-r15
+.Lpush_pr:
+ add #-48, r15
+.Lalloc:
+ mov r4, r8
+ mov r5, r9
+#ifdef __PIC__
+ mova .Lgot0, r0
+ mov.l .Lgot0, r12
+ add r0, r12
+#endif
+
+ /* Get internal lock. */
+ mov #0, r3
+ mov #1, r4
+#if cond_lock != 0
+ CMPXCHG (r3, @(cond_lock,r8), r4, r2)
+#else
+ CMPXCHG (r3, @r8, r4, r2)
+#endif
+ bt 2f
+ bra 1f
+ nop
+#ifdef __PIC__
+ .align 2
+.Lgot0:
+ .long _GLOBAL_OFFSET_TABLE_
+#endif
+
+2:
+ /* Store the reference to the mutex. If there is already a
+ different value in there this is a bad user bug. */
+ mov.l @(dep_mutex,r8),r0
+ cmp/eq #-1, r0
+ bt 15f
+ mov.l r9, @(dep_mutex,r8)
+
+15:
+ /* Unlock the mutex. */
+ mov.l .Lmunlock0, r1
+ mov #0, r5
+ bsrf r1
+ mov r9, r4
+.Lmunlock0b:
+
+ tst r0, r0
+ bt 0f
+ bra 12f
+ nop
+0:
+ mov #1, r2
+ mov #0, r3
+
+ clrt
+ mov.l @(total_seq,r8),r0
+ mov.l @(total_seq+4,r8),r1
+ addc r2, r0
+ addc r3, r1
+ mov.l r0,@(total_seq,r8)
+ mov.l r1,@(total_seq+4,r8)
+ mov.l @(cond_futex,r8),r0
+ add r2, r0
+ mov.l r0,@(cond_futex,r8)
+ mov #(1 << nwaiters_shift), r2
+ mov.l @(cond_nwaiters,r8), r0
+ add r2, r0
+ mov.l r0, @(cond_nwaiters,r8)
+
+ /* Get and store current wakeup_seq value. */
+ mov.l @(wakeup_seq,r8), r10
+ mov.l @(wakeup_seq+4,r8), r11
+ mov.l @(broadcast_seq,r8), r0
+ mov.l r0, @(4,r15)
+
+8:
+ mov.l @(cond_futex,r8),r0
+ mov.l r0, @(8,r15)
+
+ /* Unlock. */
+#if cond_lock != 0
+ DEC (@(cond_lock,r8), r2)
+#else
+ DEC (@r8, r2)
+#endif
+ tst r2, r2
+ bf 3f
+4:
+.LcleanupSTART:
+ mov.l .Lenable0, r1
+ bsrf r1
+ nop
+.Lenable0b:
+ mov.l r0, @r15
+
+ mov #0, r7
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAIT, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff0, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+#endif
+99:
+ mov.l @(8,r15), r6
+ mov r8, r4
+ add #cond_futex, r4
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ mov.l .Ldisable0, r1
+ bsrf r1
+ mov.l @r15, r4
+.Ldisable0b:
+.LcleanupEND:
+
+ /* Lock. */
+ mov #0, r3
+ mov #1, r4
+#if cond_lock != 0
+ CMPXCHG (r3, @(cond_lock,r8), r4, r2)
+#else
+ CMPXCHG (r3, @r8, r4, r2)
+#endif
+ bf 5f
+6:
+ mov.l @(broadcast_seq,r8), r0
+ mov.l @(4,r15), r1
+ cmp/eq r0, r1
+ bf 16f
+
+ mov.l @(woken_seq,r8), r0
+ mov.l @(woken_seq+4,r8), r1
+
+ mov.l @(wakeup_seq,r8), r2
+ mov.l @(wakeup_seq+4,r8), r3
+
+ cmp/eq r3, r11
+ bf 7f
+ cmp/eq r2, r10
+ bt 8b
+7:
+ cmp/eq r1, r3
+ bf 9f
+ cmp/eq r0, r2
+ bt 8b
+9:
+ mov #1, r2
+ mov #0, r3
+
+ clrt
+ mov.l @(woken_seq,r8),r0
+ mov.l @(woken_seq+4,r8),r1
+ addc r2, r0
+ addc r3, r1
+ mov.l r0,@(woken_seq,r8)
+ mov.l r1,@(woken_seq+4,r8)
+
+16:
+ mov #(1 << nwaiters_shift), r2
+ mov.l @(cond_nwaiters,r8),r0
+ sub r2, r0
+ mov.l r0,@(cond_nwaiters,r8)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ mov.l @(total_seq,r8),r0
+ mov.l @(total_seq+4,r8),r1
+ and r1, r0
+ not r0, r0
+ cmp/eq #0, r0
+ bf/s 17f
+ mov #((1 << nwaiters_shift) - 1), r1
+ not r1, r1
+ mov.l @(cond_nwaiters,r8),r0
+ tst r1, r0
+ bf 17f
+
+ mov r8, r4
+ add #cond_nwaiters, r4
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff0, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+99:
+ mov #1, r6
+ mov #0, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+17:
+#if cond_lock != 0
+ DEC (@(cond_lock,r8), r2)
+#else
+ DEC (@r8, r2)
+#endif
+ tst r2, r2
+ bf 10f
+
+11:
+ mov.l .Lmlocki0, r1
+ bsrf r1
+ mov r9, r4
+.Lmlocki0b:
+ /* We return the result of the mutex_lock operation. */
+
+14:
+ add #48, r15
+ lds.l @r15+, pr
+ mov.l @r15+, r12
+ mov.l @r15+, r11
+ mov.l @r15+, r10
+ mov.l @r15+, r9
+ rts
+ mov.l @r15+, r8
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff0:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+ .align 2
+.Lmunlock0:
+ .long __pthread_mutex_unlock_usercnt-.Lmunlock0b
+.Lenable0:
+ .long __pthread_enable_asynccancel-.Lenable0b
+.Ldisable0:
+ .long __pthread_disable_asynccancel-.Ldisable0b
+.Lmlocki0:
+ .long __pthread_mutex_cond_lock-.Lmlocki0b
+
+1:
+ /* Initial locking failed. */
+ mov r8, r5
+#if cond_lock != 0
+ add #cond_lock, r5
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait0, r1
+ bsrf r1
+ mov r2, r4
+.Lwait0b:
+ bra 2b
+ nop
+3:
+ /* Unlock in loop requires waekup. */
+ mov r8, r4
+#if cond_lock != 0
+ add #cond_lock, r4
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake0, r1
+ bsrf r1
+ extu.b r5, r5
+.Lwake0b:
+ bra 4b
+ nop
+
+5:
+ /* Locking in loop failed. */
+ mov r8, r5
+#if cond_lock != 0
+ add #cond_lock, r5
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait1, r1
+ bsrf r1
+ mov r2, r4
+.Lwait1b:
+ bra 6b
+ nop
+
+10:
+ /* Unlock after loop requires wakeup. */
+ mov r8, r4
+#if cond_lock != 0
+ add #cond_lock, r4
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake1, r1
+ bsrf r1
+ extu.b r5, r5
+.Lwake1b:
+ bra 11b
+ nop
+
+12:
+ /* The initial unlocking of the mutex failed. */
+ mov.l r0, @(12,r15)
+#if cond_lock != 0
+ DEC (@(cond_lock,r8), r2)
+#else
+ DEC (@r8, r2)
+#endif
+ tst r2, r2
+ bf 13f
+
+ mov r8, r4
+#if cond_lock != 0
+ add #cond_lock, r4
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake2, r1
+ bsrf r1
+ extu.b r5, r5
+.Lwake2b:
+
+13:
+ bra 14b
+ mov.l @(12,r15), r0
+
+ .align 2
+.Lwait0:
+ .long __lll_lock_wait-.Lwait0b
+.Lwake0:
+ .long __lll_unlock_wake-.Lwake0b
+.Lwait1:
+ .long __lll_lock_wait-.Lwait1b
+.Lwake1:
+ .long __lll_unlock_wake-.Lwake1b
+.Lwake2:
+ .long __lll_unlock_wake-.Lwake2b
+ .size __pthread_cond_wait, .-__pthread_cond_wait
+weak_alias (__pthread_cond_wait, pthread_cond_wait)
+
+
+ .type __condvar_w_cleanup, @function
+__condvar_w_cleanup:
+ mov r4, r11
+
+ /* Get internal lock. */
+ mov #0, r3
+ mov #1, r4
+#if cond_lock != 0
+ CMPXCHG (r3, @(cond_lock,r8), r4, r2)
+#else
+ CMPXCHG (r3, @r8, r4, r2)
+#endif
+ bt 1f
+ nop
+
+ mov r8, r5
+#if cond_lock != 0
+ add #cond_lock, r5
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait3, r1
+ bsrf r1
+ mov r2, r4
+.Lwait3b:
+
+1:
+ mov.l @(broadcast_seq,r8), r0
+ mov.l @(4,r15), r1
+ cmp/eq r0, r1
+ bf 3f
+
+ mov #1, r2
+ mov #0, r3
+
+ /* We increment the wakeup_seq counter only if it is lower than
+ total_seq. If this is not the case the thread was woken and
+ then canceled. In this case we ignore the signal. */
+ mov.l @(total_seq+4,r8), r0
+ mov.l @(wakeup_seq+4,r8), r1
+ cmp/hi r1, r0
+ bt/s 6f
+ cmp/hi r0, r1
+ bt 7f
+ mov.l @(total_seq,r8), r0
+ mov.l @(wakeup_seq,r8), r1
+ cmp/hs r0, r1
+ bt 7f
+
+6:
+ clrt
+ mov.l @(wakeup_seq,r8),r0
+ mov.l @(wakeup_seq+4,r8),r1
+ addc r2, r0
+ addc r3, r1
+ mov.l r0,@(wakeup_seq,r8)
+ mov.l r1,@(wakeup_seq+4,r8)
+ mov.l @(cond_futex,r8),r0
+ add r2, r0
+ mov.l r0,@(cond_futex,r8)
+
+7:
+ clrt
+ mov.l @(woken_seq,r8),r0
+ mov.l @(woken_seq+4,r8),r1
+ addc r2, r0
+ addc r3, r1
+ mov.l r0,@(woken_seq,r8)
+ mov.l r1,@(woken_seq+4,r8)
+
+3:
+ mov #(1 << nwaiters_shift), r2
+ mov.l @(cond_nwaiters,r8),r0
+ sub r2, r0
+ mov.l r0,@(cond_nwaiters,r8)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ mov #0, r10
+ mov.l @(total_seq,r8),r0
+ mov.l @(total_seq+4,r8),r1
+ and r1, r0
+ not r0, r0
+ cmp/eq #0, r0
+ bf/s 4f
+ mov #((1 << nwaiters_shift) - 1), r1
+ not r1, r1
+ mov.l @(cond_nwaiters,r8),r0
+ tst r1, r0
+ bf 4f
+
+ mov r8, r4
+ add #cond_nwaiters, r4
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff1, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+99:
+ mov #1, r6
+ mov #0, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+ mov #1, r10
+
+4:
+#if cond_lock != 0
+ DEC (@(cond_lock,r8), r2)
+#else
+ DEC (@r8, r2)
+#endif
+ tst r2, r2
+ bt 2f
+
+ mov r8, r4
+#if cond_lock != 0
+ add #cond_lock, r4
+#endif
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake3, r1
+ bsrf r1
+ extu.b r5, r5
+.Lwake3b:
+
+2:
+ /* Wake up all waiters to make sure no signal gets lost. */
+ tst r10, r10
+ bf/s 5f
+ mov r8, r4
+ add #cond_futex, r4
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff1, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+99:
+ mov #-1, r6
+ shlr r6 /* r6 = 0x7fffffff */
+ mov #0, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+5:
+ mov.l .Lmlocki3, r1
+ bsrf r1
+ mov r9, r4
+.Lmlocki3b:
+
+.LcallUR:
+ mov.l .Lresume, r1
+#ifdef __PIC__
+ add r12, r1
+#endif
+ jsr @r1
+ mov r11, r4
+ sleep
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff1:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+ .align 2
+.Lwait3:
+ .long __lll_lock_wait-.Lwait3b
+.Lwake3:
+ .long __lll_unlock_wake-.Lwake3b
+.Lmlocki3:
+ .long __pthread_mutex_cond_lock-.Lmlocki3b
+.Lresume:
+#ifdef __PIC__
+ .long _Unwind_Resume@GOTOFF
+#else
+ .long _Unwind_Resume
+#endif
+.LENDCODE:
+ .size __condvar_w_cleanup, .-__condvar_w_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff ! @LPStart format (omit)
+ .byte 0xff ! @TType format (omit)
+ .byte 0x0b ! call-site format
+ ! DW_EH_PE_sdata4
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .ualong .LcleanupSTART-.LSTARTCODE
+ .ualong .LcleanupEND-.LcleanupSTART
+ .ualong __condvar_w_cleanup-.LSTARTCODE
+ .uleb128 0
+ .ualong .LcallUR-.LSTARTCODE
+ .ualong .LENDCODE-.LcallUR
+ .ualong 0
+ .uleb128 0
+.Lcstend:
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+ .ualong .LENDCIE-.LSTARTCIE ! Length of the CIE.
+.LSTARTCIE:
+ .ualong 0 ! CIE ID.
+ .byte 1 ! Version number.
+#ifdef SHARED
+ .string "zPLR" ! NUL-terminated augmentation
+ ! string.
+#else
+ .string "zPL" ! NUL-terminated augmentation
+ ! string.
+#endif
+ .uleb128 1 ! Code alignment factor.
+ .sleb128 -4 ! Data alignment factor.
+ .byte 0x11 ! Return address register
+ ! column.
+#ifdef SHARED
+ .uleb128 7 ! Augmentation value length.
+ .byte 0x9b ! Personality: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4
+ ! + DW_EH_PE_indirect
+ .ualong DW.ref.__gcc_personality_v0-.
+ .byte 0x1b ! LSDA Encoding: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4.
+ .byte 0x1b ! FDE Encoding: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4.
+#else
+ .uleb128 6 ! Augmentation value length.
+ .byte 0x0 ! Personality: absolute
+ .ualong __gcc_personality_v0
+ .byte 0x0 ! LSDA Encoding: absolute
+#endif
+ .byte 0x0c ! DW_CFA_def_cfa
+ .uleb128 0xf
+ .uleb128 0
+ .align 2
+.LENDCIE:
+
+ .ualong .LENDFDE-.LSTARTFDE ! Length of the FDE.
+.LSTARTFDE:
+ .ualong .LSTARTFDE-.LSTARTFRAME ! CIE pointer.
+#ifdef SHARED
+ .ualong .LSTARTCODE-. ! PC-relative start address
+ ! of the code.
+#else
+ .ualong .LSTARTCODE ! Start address of the code.
+#endif
+ .ualong .LENDCODE-.LSTARTCODE ! Length of the code.
+ .uleb128 4 ! Augmentation size
+#ifdef SHARED
+ .ualong .LexceptSTART-.
+#else
+ .ualong .LexceptSTART
+#endif
+ .byte 0x4
+ .ualong .Lpush_r8-.LSTARTCODE
+ .byte 0xe
+ .uleb128 4
+ .byte 0x88
+ .uleb128 1
+ .byte 0x4
+ .ualong .Lpush_r9-.Lpush_r8
+ .byte 0xe
+ .uleb128 8
+ .byte 0x89
+ .uleb128 2
+ .byte 0x4
+ .ualong .Lpush_r10-.Lpush_r9
+ .byte 0xe
+ .uleb128 12
+ .byte 0x8a
+ .uleb128 3
+ .byte 0x4
+ .ualong .Lpush_r11-.Lpush_r10
+ .byte 0xe
+ .uleb128 16
+ .byte 0x8b
+ .uleb128 4
+ .byte 0x4
+ .ualong .Lpush_r12-.Lpush_r11
+ .byte 0xe
+ .uleb128 20
+ .byte 0x8c
+ .uleb128 5
+ .byte 0x4
+ .ualong .Lpush_pr-.Lpush_r12
+ .byte 0xe
+ .uleb128 24
+ .byte 0x91
+ .uleb128 6
+ .byte 0x4
+ .ualong .Lalloc-.Lpush_pr
+ .byte 0xe
+ .uleb128 72
+ .align 2
+.LENDFDE:
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
new file mode 100644
index 000000000..46234459a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
@@ -0,0 +1,263 @@
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <unwindbuf.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+#include <lowlevellock.h>
+#include <tcb-offsets.h>
+#include "lowlevel-atomic.h"
+
+
+ .comm __fork_generation, 4, 4
+
+ .text
+ .globl __pthread_once
+ .type __pthread_once,@function
+ .protected __pthread_once
+ .align 5
+ cfi_startproc
+__pthread_once:
+ mov.l @r4, r0
+ tst #2, r0
+ bt 1f
+ rts
+ mov #0, r0
+
+1:
+ mov.l r12, @-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (r12, 0)
+ mov.l r9, @-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (r9, 0)
+ mov.l r8, @-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (r8, 0)
+ sts.l pr, @-r15
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (pr, 0)
+ mov r5, r8
+ mov r4, r9
+
+ /* Not yet initialized or initialization in progress.
+ Get the fork generation counter now. */
+6:
+ mov.l @r4, r1
+ mova .Lgot, r0
+ mov.l .Lgot, r12
+ add r0, r12
+
+5:
+ mov r1, r0
+
+ tst #2, r0
+ bf 4f
+
+ and #3, r0
+ mov.l .Lfgen, r2
+#ifdef __PIC__
+ add r12, r2
+#endif
+ mov.l @r2, r3
+ or r3, r0
+ or #1, r0
+ mov r0, r3
+ mov r1, r5
+
+ CMPXCHG (r5, @r4, r3, r2)
+ bf 5b
+
+ /* Check whether another thread already runs the initializer. */
+ mov r2, r0
+ tst #1, r0
+ bt 3f /* No -> do it. */
+
+ /* Check whether the initializer execution was interrupted
+ by a fork. */
+ xor r3, r0
+ mov #-4, r1 /* -4 = 0xfffffffc */
+ tst r1, r0
+ bf 3f /* Different for generation -> run initializer. */
+
+ /* Somebody else got here first. Wait. */
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+# if FUTEX_WAIT != 0
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+# endif
+#endif
+ mov r3, r6
+ mov #0, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+ bra 6b
+ nop
+
+ .align 2
+.Lgot:
+ .long _GLOBAL_OFFSET_TABLE_
+#ifdef __PIC__
+.Lfgen:
+ .long __fork_generation@GOTOFF
+#else
+.Lfgen:
+ .long __fork_generation
+#endif
+
+3:
+ /* Call the initializer function after setting up the
+ cancellation handler. Note that it is not possible here
+ to use the unwind-based cleanup handling. This would require
+ that the user-provided function and all the code it calls
+ is compiled with exceptions. Unfortunately this cannot be
+ guaranteed. */
+ add #-UNWINDBUFSIZE, r15
+ cfi_adjust_cfa_offset (UNWINDBUFSIZE)
+
+ mov.l .Lsigsetjmp, r1
+ mov #UWJMPBUF, r4
+ add r15, r4
+ bsrf r1
+ mov #0, r5
+.Lsigsetjmp0:
+ tst r0, r0
+ bf 7f
+
+ mov.l .Lcpush, r1
+ bsrf r1
+ mov r15, r4
+.Lcpush0:
+
+ /* Call the user-provided initialization function. */
+ jsr @r8
+ nop
+
+ /* Pop the cleanup handler. */
+ mov.l .Lcpop, r1
+ bsrf r1
+ mov r15, r4
+.Lcpop0:
+
+ add #UNWINDBUFSIZE, r15
+ cfi_adjust_cfa_offset (-UNWINDBUFSIZE)
+
+ /* Sucessful run of the initializer. Signal that we are done. */
+ INC (@r9, r2)
+ /* Wake up all other threads. */
+ mov r9, r4
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+ mov #-1, r6
+ shlr r6 /* r6 = 0x7fffffff */
+ mov #0, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+4:
+ lds.l @r15+, pr
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (pr)
+ mov.l @r15+, r8
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (r8)
+ mov.l @r15+, r9
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (r9)
+ mov.l @r15+, r12
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (r12)
+ rts
+ mov #0, r0
+
+7:
+ /* __sigsetjmp returned for the second time. */
+ cfi_adjust_cfa_offset (UNWINDBUFSIZE+16)
+ cfi_offset (r12, -4)
+ cfi_offset (r9, -8)
+ cfi_offset (r8, -12)
+ cfi_offset (pr, -16)
+ mov #0, r7
+ mov.l r7, @r9
+ mov r9, r4
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+ extu.b r5, r5
+ mov #-1, r6
+ shlr r6 /* r6 = 0x7fffffff */
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ mov.l .Lunext, r1
+ bsrf r1
+ mov r15, r4
+.Lunext0:
+ /* NOTREACHED */
+ sleep
+ cfi_endproc
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+ .align 2
+.Lsigsetjmp:
+ .long __sigsetjmp@PLT-(.Lsigsetjmp0-.)
+.Lcpush:
+ .long HIDDEN_JUMPTARGET(__pthread_register_cancel)-.Lcpush0
+.Lcpop:
+ .long HIDDEN_JUMPTARGET(__pthread_unregister_cancel)-.Lcpop0
+.Lunext:
+ .long HIDDEN_JUMPTARGET(__pthread_unwind_next)-.Lunext0
+ .size __pthread_once,.-__pthread_once
+
+ .globl __pthread_once_internal
+__pthread_once_internal = __pthread_once
+
+ .globl pthread_once
+pthread_once = __pthread_once
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
new file mode 100644
index 000000000..21e05e192
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
@@ -0,0 +1,255 @@
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <pthread-errnos.h>
+#include <tcb-offsets.h>
+#include <bits/kernel-features.h>
+#include "lowlevel-atomic.h"
+
+
+ .text
+
+ .globl __pthread_rwlock_rdlock
+ .type __pthread_rwlock_rdlock,@function
+ .protected __pthread_rwlock_rdlock
+ .align 5
+__pthread_rwlock_rdlock:
+ mov.l r12, @-r15
+ mov.l r9, @-r15
+ mov.l r8, @-r15
+ sts.l pr, @-r15
+ mov r4, r8
+
+ /* Get the lock. */
+ mov #0, r3
+ mov #1, r4
+#if MUTEX == 0
+ CMPXCHG (r3, @r8, r4, r2)
+#else
+ CMPXCHG (r3, @(MUTEX,r8), r4, r2)
+#endif
+ bf 1f
+2:
+ mov.l @(WRITER,r8), r0
+ tst r0, r0
+ bf 14f
+ mov.l @(WRITERS_QUEUED,r8), r0
+ tst r0, r0
+ bt 5f
+ mov #FLAGS, r0
+ mov.b @(r0,r8), r0
+ tst r0, r0
+ bt 5f
+3:
+ mov.l @(READERS_QUEUED,r8), r0
+ add #1, r0
+ mov.l r0, @(READERS_QUEUED,r8)
+ tst r0, r0
+ bt 4f
+
+ mov.l @(READERS_WAKEUP,r8), r9
+
+#if MUTEX == 0
+ DEC (@r8, r2)
+#else
+ DEC (@(MUTEX,r8), r2)
+#endif
+ tst r2, r2
+ bf 10f
+11:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
+ xor r0, r5
+ extu.b r5, r5
+#else
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+# if FUTEX_WAIT != 0
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+# endif
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r0
+ xor r0, r5
+#endif
+ mov r8, r4
+ add #READERS_WAKEUP, r4
+ mov r9, r6
+ mov #0, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ /* Reget the lock. */
+ mov #0, r3
+ mov #1, r4
+#if MUTEX == 0
+ CMPXCHG (r3, @r8, r4, r2)
+#else
+ CMPXCHG (r3, @(MUTEX,r8), r4, r2)
+#endif
+ bf 12f
+13:
+ mov.l @(READERS_QUEUED,r8), r0
+ add #-1, r0
+ bra 2b
+ mov.l r0, @(READERS_QUEUED,r8)
+
+5:
+ mov #0, r3
+ mov.l @(NR_READERS,r8), r0
+ add #1, r0
+ mov.l r0, @(NR_READERS,r8)
+ tst r0, r0
+ bt 8f
+
+9:
+#if MUTEX == 0
+ DEC (@r8, r2)
+#else
+ DEC (@(MUTEX,r8), r2)
+#endif
+ tst r2, r2
+ bf 6f
+7:
+ lds.l @r15+, pr
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ mov.l @r15+, r12
+ rts
+ mov r3, r0
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+
+1:
+ mov r8, r5
+#if MUTEX != 0
+ add #MUTEX, r5
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
+ mov.l .Lwait0, r1
+ bsrf r1
+ mov r2, r4
+.Lwait0b:
+ bra 2b
+ nop
+14:
+ stc gbr, r1
+ mov.w .Ltidoff, r2
+ add r2, r1
+ mov.l @r1, r1
+ cmp/eq r1, r0
+ bf 3b
+ /* Deadlock detected. */
+ bra 9b
+ mov #EDEADLK, r3
+
+.Ltidoff:
+ .word TID - TLS_PRE_TCB_SIZE
+
+6:
+ mov r8, r4
+#if MUTEX != 0
+ add #MUTEX, r4
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+ mov.l .Lwake0, r1
+ bsrf r1
+ nop
+.Lwake0b:
+ bra 7b
+ mov #0, r3
+
+8:
+ /* Overflow. */
+ mov.l @(NR_READERS,r8), r1
+ add #-1, r1
+ mov.l r1, @(NR_READERS,r8)
+ bra 9b
+ mov #EAGAIN, r3
+
+4:
+ /* Overflow. */
+ mov.l @(READERS_QUEUED,r8), r1
+ add #-1, r1
+ mov.l r1, @(READERS_QUEUED,r8)
+ bra 9b
+ mov #EAGAIN, r3
+
+10:
+ mov r8, r4
+#if MUTEX != 0
+ add #MUTEX, r4
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+ mov.l .Lwake1, r1
+ bsrf r1
+ nop
+.Lwake1b:
+ bra 11b
+ nop
+
+12:
+ mov r8, r5
+#if MUTEX != 0
+ add #MUTEX, r5
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
+ mov.l .Lwait1, r1
+ bsrf r1
+ mov r2, r4
+.Lwait1b:
+ bra 13b
+ nop
+
+ .align 2
+.Lwait0:
+ .long __lll_lock_wait-.Lwait0b
+.Lwake0:
+ .long __lll_unlock_wake-.Lwake0b
+.Lwait1:
+ .long __lll_lock_wait-.Lwait1b
+.Lwake1:
+ .long __lll_unlock_wake-.Lwake1b
+ .size __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
+
+ .globl pthread_rwlock_rdlock
+pthread_rwlock_rdlock = __pthread_rwlock_rdlock
+
+ .globl __pthread_rwlock_rdlock_internal
+__pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
new file mode 100644
index 000000000..6e7af21e9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
@@ -0,0 +1,314 @@
+/* Copyright (C) 2003, 2007, 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <pthread-errnos.h>
+#include <tcb-offsets.h>
+#include <bits/kernel-features.h>
+#include "lowlevel-atomic.h"
+
+
+ .text
+
+ .globl pthread_rwlock_timedrdlock
+ .type pthread_rwlock_timedrdlock,@function
+ .align 5
+pthread_rwlock_timedrdlock:
+ mov.l r12, @-r15
+ mov.l r10, @-r15
+ mov.l r9, @-r15
+ mov.l r8, @-r15
+ sts.l pr, @-r15
+ add #-8, r15
+ mov r4, r8
+ mov r5, r9
+
+ /* Get the lock. */
+ mov #0, r3
+ mov #1, r4
+#if MUTEX == 0
+ CMPXCHG (r3, @r8, r4, r2)
+#else
+ CMPXCHG (r3, @(MUTEX,r8), r4, r2)
+#endif
+ bf 1f
+2:
+ mov.l @(WRITER,r8), r0
+ tst r0, r0
+ bf 14f
+ mov.l @(WRITERS_QUEUED,r8), r0
+ tst r0, r0
+ bt 5f
+ mov #FLAGS, r0
+ mov.b @(r0,r8), r0
+ tst r0, r0
+ bt 5f
+3:
+ /* Check the value of the timeout parameter. */
+ mov.l .L1g0, r1
+ mov.l @(4,r9), r0
+ cmp/hs r1, r0
+ bt 19f
+
+ mov.l @(READERS_QUEUED,r8), r0
+ add #1, r0
+ mov.l r0, @(READERS_QUEUED,r8)
+ tst r0, r0
+ bt 4f
+
+ mov.l @(READERS_WAKEUP,r8), r10
+
+#if MUTEX == 0
+ DEC (@r8, r2)
+#else
+ DEC (@(MUTEX,r8), r2)
+#endif
+ tst r2, r2
+ bf 10f
+
+11:
+ /* Get current time. */
+ mov r15, r4
+ mov #0, r5
+ mov #__NR_gettimeofday, r3
+ trapa #0x12
+ SYSCALL_INST_PAD
+
+ mov.l @(4,r15), r0
+ mov.w .L1k0, r1
+ dmulu.l r0, r1 /* Milli seconds to nano seconds. */
+ mov.l @r9, r2
+ mov.l @(4,r9), r3
+ mov.l @r15, r0
+ sts macl, r1
+ sub r0, r2
+ clrt
+ subc r1, r3
+ bf 15f
+ mov.l .L1g0, r1
+ add r1, r3
+ add #-1, r2
+15:
+ cmp/pz r2
+ bf 16f /* Time is already up. */
+
+ /* Store relative timeout. */
+ mov.l r2, @r15
+ mov.l r3, @(4,r15)
+
+ /* Futex call. */
+ mov r15, r7
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
+ xor r0, r5
+ extu.b r5, r5
+#else
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+# if FUTEX_WAIT != 0
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+# endif
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r0
+ xor r0, r5
+#endif
+ mov r10, r6
+ mov r8, r4
+ add #READERS_WAKEUP, r4
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+ mov r0, r3
+
+17:
+ /* Reget the lock. */
+ mov #0, r5
+ mov #1, r4
+#if MUTEX == 0
+ CMPXCHG (r5, @r8, r4, r2)
+#else
+ CMPXCHG (r5, @(MUTEX,r8), r4, r2)
+#endif
+ bf 12f
+
+13:
+ mov.l @(READERS_QUEUED,r8), r0
+ add #-1, r0
+ mov.l r0, @(READERS_QUEUED,r8)
+ mov #-ETIMEDOUT, r0
+ cmp/eq r0, r3
+ bf 2b
+
+18:
+ bra 9f
+ mov #ETIMEDOUT, r3
+
+5:
+ mov #0, r3
+ mov.l @(NR_READERS,r8), r0
+ add #1, r0
+ mov.l r0, @(NR_READERS,r8)
+ tst r0, r0
+ bt 8f
+
+9:
+#if MUTEX == 0
+ DEC (@r8, r2)
+#else
+ DEC (@(MUTEX,r8), r2)
+#endif
+ tst r2, r2
+ bf 6f
+7:
+ add #8,r15
+ lds.l @r15+, pr
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ mov.l @r15+, r10
+ mov.l @r15+, r12
+ rts
+ mov r3, r0
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+ .align 2
+.L1k0:
+ .long 1000
+.L1g0:
+ .long 1000000000
+
+1:
+ mov r8, r5
+#if MUTEX != 0
+ add #MUTEX, r5
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
+ mov.l .Lwait2, r1
+ bsrf r1
+ mov r2, r4
+.Lwait2b:
+ bra 2b
+ nop
+14:
+ stc gbr, r1
+ mov.w .Ltidoff, r2
+ add r2, r1
+ mov.l @r1, r1
+ cmp/eq r1, r0
+ bf 3b
+ /* Deadlock detected. */
+ bra 9b
+ mov #EDEADLK, r3
+
+.Ltidoff:
+ .word TID - TLS_PRE_TCB_SIZE
+
+6:
+ mov r3, r10
+ mov r8, r4
+#if MUTEX != 0
+ add #MUTEX, r4
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+ mov.l .Lwake2, r1
+ bsrf r1
+ nop
+.Lwake2b:
+ bra 7b
+ mov r10, r3
+
+8:
+ /* Overflow. */
+ mov.l @(NR_READERS,r8), r1
+ add #-1, r1
+ mov.l r1, @(NR_READERS,r8)
+ bra 9b
+ mov #EAGAIN, r3
+
+4:
+ /* Overflow. */
+ mov.l @(READERS_QUEUED,r8), r1
+ add #-1, r1
+ mov.l r1, @(READERS_QUEUED,r8)
+ bra 9b
+ mov #EAGAIN, r3
+
+10:
+ mov r8, r4
+#if MUTEX != 0
+ add #MUTEX, r4
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+ mov.l .Lwake3, r1
+ bsrf r1
+ nop
+.Lwake3b:
+ bra 11b
+ nop
+
+12:
+ mov r3, r10
+ mov r8, r5
+#if MUTEX != 0
+ add #MUTEX, r5
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
+ mov.l .Lwait3, r1
+ bsrf r1
+ mov r2, r4
+.Lwait3b:
+ bra 13b
+ mov r10, r3
+
+16:
+ bra 17b
+ mov #-ETIMEDOUT, r3
+
+19:
+ bra 9b
+ mov #EINVAL, r3
+
+ .align 2
+.Lwait2:
+ .long __lll_lock_wait-.Lwait2b
+.Lwake2:
+ .long __lll_unlock_wake-.Lwake2b
+.Lwait3:
+ .long __lll_lock_wait-.Lwait3b
+.Lwake3:
+ .long __lll_unlock_wake-.Lwake3b
+ .size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
new file mode 100644
index 000000000..1cb7cbdde
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
@@ -0,0 +1,298 @@
+/* Copyright (C) 2003, 2007, 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <pthread-errnos.h>
+#include <tcb-offsets.h>
+#include <bits/kernel-features.h>
+#include "lowlevel-atomic.h"
+
+
+ .text
+
+ .globl pthread_rwlock_timedwrlock
+ .type pthread_rwlock_timedwrlock,@function
+ .align 5
+pthread_rwlock_timedwrlock:
+ mov.l r12, @-r15
+ mov.l r10, @-r15
+ mov.l r9, @-r15
+ mov.l r8, @-r15
+ sts.l pr, @-r15
+ add #-8, r15
+ mov r4, r8
+ mov r5, r9
+
+ /* Get the lock. */
+ mov #0, r3
+ mov #1, r4
+#if MUTEX == 0
+ CMPXCHG (r3, @r8, r4, r2)
+#else
+ CMPXCHG (r3, @(MUTEX,r8), r4, r2)
+#endif
+ bf 1f
+2:
+ mov.l @(WRITER,r8), r0
+ tst r0, r0
+ bf 14f
+ mov.l @(NR_READERS,r8), r0
+ tst r0, r0
+ bt 5f
+3:
+ /* Check the value of the timeout parameter. */
+ mov.l .L1g1, r1
+ mov.l @(4,r9), r0
+ cmp/hs r1, r0
+ bt 19f
+
+ mov.l @(WRITERS_QUEUED,r8), r0
+ add #1, r0
+ mov.l r0, @(WRITERS_QUEUED,r8)
+ tst r0, r0
+ bt 4f
+
+ mov.l @(WRITERS_WAKEUP,r8), r10
+
+#if MUTEX == 0
+ DEC (@r8, r2)
+#else
+ DEC (@(MUTEX,r8), r2)
+#endif
+ tst r2, r2
+ bf 10f
+
+11:
+ /* Get current time. */
+ mov r15, r4
+ mov #0, r5
+ mov #__NR_gettimeofday, r3
+ trapa #0x12
+ SYSCALL_INST_PAD
+
+ mov.l @(4,r15), r0
+ mov.w .L1k1, r1
+ dmulu.l r0, r1 /* Milli seconds to nano seconds. */
+ mov.l @r9, r2
+ mov.l @(4,r9), r3
+ mov.l @r15, r0
+ sts macl, r1
+ sub r0, r2
+ clrt
+ subc r1, r3
+ bf 15f
+ mov.l .L1g1, r1
+ add r1, r3
+ add #-1, r2
+15:
+ cmp/pz r2
+ bf 16f /* Time is already up. */
+
+ /* Store relative timeout. */
+ mov.l r2, @r15
+ mov.l r3, @(4,r15)
+
+ /* Futex call. */
+ mov r15, r7
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
+ xor r0, r5
+ extu.b r5, r5
+#else
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+# if FUTEX_WAIT != 0
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+# endif
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r0
+ xor r0, r5
+#endif
+ mov r10, r6
+ mov r8, r4
+ add #WRITERS_WAKEUP, r4
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+ mov r0, r3
+
+17:
+ /* Reget the lock. */
+ mov #0, r5
+ mov #1, r4
+#if MUTEX == 0
+ CMPXCHG (r5, @r8, r4, r2)
+#else
+ CMPXCHG (r5, @(MUTEX,r8), r4, r2)
+#endif
+ bf 12f
+
+13:
+ mov.l @(WRITERS_QUEUED,r8), r0
+ add #-1, r0
+ mov.l r0, @(WRITERS_QUEUED,r8)
+ mov #-ETIMEDOUT, r0
+ cmp/eq r0, r3
+ bf 2b
+
+18:
+ bra 9f
+ mov #ETIMEDOUT, r3
+
+19:
+ bra 9f
+ mov #EINVAL, r3
+
+5:
+ mov #0, r3
+ stc gbr, r0
+ mov.w .Ltidoff, r1
+ mov.l @(r0,r1), r0
+ mov.l r0, @(WRITER,r8)
+9:
+#if MUTEX == 0
+ DEC (@r8, r2)
+#else
+ DEC (@(MUTEX,r8), r2)
+#endif
+ tst r2, r2
+ bf 6f
+7:
+ add #8,r15
+ lds.l @r15+, pr
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ mov.l @r15+, r10
+ mov.l @r15+, r12
+ rts
+ mov r3, r0
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+.L1k1:
+ .word 1000
+ .align 2
+.L1g1:
+ .long 1000000000
+
+1:
+ mov r8, r5
+#if MUTEX != 0
+ add #MUTEX, r5
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
+ mov.l .Lwait6, r1
+ bsrf r1
+ mov r2, r4
+.Lwait6b:
+ bra 2b
+ nop
+14:
+ stc gbr, r1
+ mov.w .Ltidoff, r2
+ add r2, r1
+ mov.l @r1, r1
+ cmp/eq r1, r0
+ bf 3b
+ bra 9b
+ mov #EDEADLK, r3
+6:
+ mov r3, r10
+ mov r8, r4
+#if MUTEX != 0
+ add #MUTEX, r4
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+ mov.l .Lwake6, r1
+ bsrf r1
+ nop
+.Lwake6b:
+ bra 7b
+ mov r10, r3
+
+.Ltidoff:
+ .word TID - TLS_PRE_TCB_SIZE
+
+4:
+ /* Overflow. */
+ mov.l @(WRITERS_QUEUED,r8), r1
+ add #-1, r1
+ mov.l r1, @(WRITERS_QUEUED,r8)
+ bra 9b
+ mov #EAGAIN, r3
+
+10:
+ mov r8, r4
+#if MUTEX != 0
+ add #MUTEX, r4
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+ mov.l .Lwake7, r1
+ bsrf r1
+ nop
+.Lwake7b:
+ bra 11b
+ nop
+
+12:
+ mov r3, r10
+ mov r8, r5
+#if MUTEX != 0
+ add #MUTEX, r5
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
+ mov.l .Lwait7, r1
+ bsrf r1
+ mov r2, r4
+.Lwait7b:
+ bra 13b
+ mov r10, r3
+
+16:
+ bra 17b
+ mov #-ETIMEDOUT, r3
+
+ .align 2
+.Lwait6:
+ .long __lll_lock_wait-.Lwait6b
+.Lwake6:
+ .long __lll_unlock_wake-.Lwake6b
+.Lwait7:
+ .long __lll_lock_wait-.Lwait7b
+.Lwake7:
+ .long __lll_unlock_wake-.Lwake7b
+ .size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S
new file mode 100644
index 000000000..1f6c1d812
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S
@@ -0,0 +1,199 @@
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+#include "lowlevel-atomic.h"
+
+
+ .text
+
+ .globl __pthread_rwlock_unlock
+ .type __pthread_rwlock_unlock,@function
+ .protected __pthread_rwlock_unlock
+ .align 5
+__pthread_rwlock_unlock:
+ mov.l r12, @-r15
+ mov.l r8, @-r15
+ sts.l pr, @-r15
+ mov r4, r8
+
+ /* Get the lock. */
+ mov #0, r3
+ mov #1, r4
+#if MUTEX == 0
+ CMPXCHG (r3, @r8, r4, r2)
+#else
+ CMPXCHG (r3, @(MUTEX,r8), r4, r2)
+#endif
+ bf 1f
+2:
+ mov.l @(WRITER,r8), r0
+ tst r0, r0
+ bf 5f
+ mov.l @(NR_READERS,r8), r0
+ add #-1, r0
+ mov.l r0, @(NR_READERS,r8)
+ tst r0, r0
+ bf 6f
+5:
+ mov #0, r0
+ mov.l r0, @(WRITER,r8)
+ mov #1, r6
+ mov r8, r4
+ add #WRITERS_WAKEUP, r4
+ mov.l @(WRITERS_QUEUED,r8), r0
+ tst r0, r0
+ bf 0f
+
+ /* If also no readers waiting nothing to do. */
+ mov.l @(READERS_QUEUED,r8), r0
+ tst r0, r0
+ bt 6f
+
+ mov #-1, r6
+ shlr r6 /* r6 = 0x7fffffff */
+ mov r8, r4
+ add #READERS_WAKEUP, r4
+
+0:
+ mov.l @r4, r0
+ add #1, r0
+ mov.l r0, @r4
+#if MUTEX == 0
+ DEC (@r8, r2)
+#else
+ DEC (@(MUTEX,r8), r2)
+#endif
+ tst r2, r2
+ bf 7f
+
+8:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r0
+ xor r0, r5
+ extu.b r5, r5
+#else
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r0
+ xor r0, r5
+#endif
+ mov #SYS_futex, r3
+ mov #0, r7
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ lds.l @r15+, pr
+ mov.l @r15+, r8
+ mov.l @r15+, r12
+ rts
+ mov #0, r0
+6:
+#if MUTEX == 0
+ DEC (@r8, r2)
+#else
+ DEC (@(MUTEX,r8), r2)
+#endif
+ tst r2, r2
+ bf 3f
+4:
+ lds.l @r15+, pr
+ mov.l @r15+, r8
+ mov.l @r15+, r12
+ rts
+ mov #0, r0
+
+1:
+ mov r8, r5
+#if MUTEX != 0
+ add #MUTEX, r5
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
+ mov.l .Lwait8, r1
+ bsrf r1
+ mov r2, r4
+.Lwait8b:
+ bra 2b
+ nop
+3:
+ mov r8, r4
+#if MUTEX != 0
+ add #MUTEX, r4
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+ mov.l .Lwake8, r1
+ bsrf r1
+ nop
+.Lwake8b:
+ bra 4b
+ nop
+
+7:
+ mov.l r4, @-r15
+ mov.l r6, @-r15
+ mov r8, r4
+#if MUTEX != 0
+ add #MUTEX, r4
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+ mov.l .Lwake9, r1
+ bsrf r1
+ nop
+.Lwake9b:
+
+ mov.l @r15+, r6
+ bra 8b
+ mov.l @r15+, r4
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+ .align 2
+.Lwait8:
+ .long __lll_lock_wait-.Lwait8b
+.Lwake8:
+ .long __lll_unlock_wake-.Lwake8b
+.Lwake9:
+ .long __lll_unlock_wake-.Lwake9b
+ .size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
+
+ .globl pthread_rwlock_unlock
+pthread_rwlock_unlock = __pthread_rwlock_unlock
+
+ .globl __pthread_rwlock_unlock_internal
+__pthread_rwlock_unlock_internal = __pthread_rwlock_unlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
new file mode 100644
index 000000000..e7bfe0d09
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
@@ -0,0 +1,235 @@
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <pthread-errnos.h>
+#include <tcb-offsets.h>
+#include <bits/kernel-features.h>
+#include "lowlevel-atomic.h"
+
+
+ .text
+
+ .globl __pthread_rwlock_wrlock
+ .type __pthread_rwlock_wrlock,@function
+ .protected __pthread_rwlock_wrlock
+ .align 5
+__pthread_rwlock_wrlock:
+ mov.l r12, @-r15
+ mov.l r9, @-r15
+ mov.l r8, @-r15
+ sts.l pr, @-r15
+ mov r4, r8
+
+ /* Get the lock. */
+ mov #0, r3
+ mov #1, r4
+#if MUTEX == 0
+ CMPXCHG (r3, @r8, r4, r2)
+#else
+ CMPXCHG (r3, @(MUTEX,r8), r4, r2)
+#endif
+ bf 1f
+2:
+ mov.l @(WRITER,r8), r0
+ tst r0, r0
+ bf 14f
+ mov.l @(NR_READERS,r8), r0
+ tst r0, r0
+ bt 5f
+3:
+ mov.l @(WRITERS_QUEUED,r8), r0
+ add #1, r0
+ mov.l r0, @(WRITERS_QUEUED,r8)
+ tst r0, r0
+ bt 4f
+
+ mov.l @(WRITERS_WAKEUP,r8), r9
+
+#if MUTEX == 0
+ DEC (@r8, r2)
+#else
+ DEC (@(MUTEX,r8), r2)
+#endif
+ tst r2, r2
+ bf 10f
+11:
+ mov r8, r4
+ add #WRITERS_WAKEUP, r4
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
+ xor r0, r5
+ extu.b r5, r5
+#else
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+# if FUTEX_WAIT != 0
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+# endif
+ stc gbr, r1
+ mov.w .Lpfoff, r2
+ add r2, r1
+ mov.l @r1, r0
+ xor r0, r5
+#endif
+ mov r9, r6
+ mov #0, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ /* Reget the lock. */
+ mov #0, r3
+ mov #1, r4
+#if MUTEX == 0
+ CMPXCHG (r3, @r8, r4, r2)
+#else
+ CMPXCHG (r3, @(MUTEX,r8), r4, r2)
+#endif
+ bf 12f
+13:
+ mov.l @(WRITERS_QUEUED,r8), r0
+ add #-1, r0
+ bra 2b
+ mov.l r0, @(WRITERS_QUEUED,r8)
+
+5:
+ mov #0, r3
+ stc gbr, r0
+ mov.w .Ltidoff, r1
+ mov.l @(r0,r1), r0
+ mov.l r0, @(WRITER,r8)
+9:
+#if MUTEX == 0
+ DEC (@r8, r2)
+#else
+ DEC (@(MUTEX,r8), r2)
+#endif
+ tst r2, r2
+ bf 6f
+7:
+ lds.l @r15+, pr
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ mov.l @r15+, r12
+ rts
+ mov r3, r0
+
+1:
+ mov r8, r5
+#if MUTEX != 0
+ add #MUTEX, r5
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
+ mov.l .Lwait4, r1
+ bsrf r1
+ mov r2, r4
+.Lwait4b:
+ bra 2b
+ nop
+14:
+ stc gbr, r1
+ mov.w .Ltidoff, r2
+ add r2, r1
+ mov.l @r1, r1
+ cmp/eq r1, r0
+ bf 3b
+ bra 9b
+ mov #EDEADLK, r3
+6:
+ mov r8, r4
+#if MUTEX != 0
+ add #MUTEX, r4
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+ mov.l .Lwake4, r1
+ bsrf r1
+ nop
+.Lwake4b:
+ bra 7b
+ mov #0, r3
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
+.Ltidoff:
+ .word TID - TLS_PRE_TCB_SIZE
+
+4:
+ mov.l @(WRITERS_QUEUED,r8), r1
+ add #-1, r1
+ mov.l r1, @(WRITERS_QUEUED,r8)
+ bra 9b
+ mov #EAGAIN, r3
+
+10:
+ mov r8, r4
+#if MUTEX != 0
+ add #MUTEX, r4
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r5
+ extu.b r5, r5
+ mov.l .Lwake5, r1
+ bsrf r1
+ nop
+.Lwake5b:
+ bra 11b
+ nop
+
+12:
+ mov r8, r5
+#if MUTEX != 0
+ add #MUTEX, r5
+#endif
+ mov #PSHARED, r0
+ mov.b @(r0,r8), r6
+ extu.b r6, r6
+ mov.l .Lwait5, r1
+ bsrf r1
+ mov r2, r4
+.Lwait5b:
+ bra 13b
+ nop
+
+ .align 2
+.Lwait4:
+ .long __lll_lock_wait-.Lwait4b
+.Lwake4:
+ .long __lll_unlock_wake-.Lwake4b
+.Lwait5:
+ .long __lll_lock_wait-.Lwait5b
+.Lwake5:
+ .long __lll_unlock_wake-.Lwake5b
+ .globl pthread_rwlock_wrlock
+pthread_rwlock_wrlock = __pthread_rwlock_wrlock
+
+ .globl __pthread_rwlock_wrlock_internal
+__pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
new file mode 100644
index 000000000..f71cd930d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
@@ -0,0 +1,110 @@
+/* Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <structsem.h>
+#include <lowlevellock.h>
+#include "lowlevel-atomic.h"
+
+
+ .text
+
+ .globl __new_sem_post
+ .type __new_sem_post,@function
+ .align 5
+__new_sem_post:
+ mov.l @(VALUE,r4), r2
+0:
+ mov.l .Lmax, r1
+ cmp/eq r1, r2
+ bt/s 3f
+ mov r2, r3
+ mov r3, r5
+ add #1, r5
+ CMPXCHG (r3, @(VALUE,r4), r5, r2)
+ bf 0b
+ mov.l @(NWAITERS,r4), r2
+ tst r2, r2
+ bt 2f
+ mov #FUTEX_WAKE, r5
+ mov.l @(PRIVATE,r4), r1
+ or r1, r5
+ mov #1, r6
+ mov #0, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ cmp/pz r0
+ bf 1f
+2:
+ rts
+ mov #0, r0
+
+1:
+ bra 4f
+ mov #EINVAL, r2
+
+3:
+ mov #EOVERFLOW, r2
+4:
+ mov.l r12, @-r15
+ mov.l r8, @-r15
+ sts.l pr, @-r15
+ mova .Lgot3, r0
+ mov.l .Lgot3, r12
+ add r0, r12
+
+#if USE___THREAD
+ mov.l .Lerrno3, r0
+ stc gbr, r1
+ mov.l @(r0, r12), r0
+ bra .Lexit
+ add r1, r0
+ .align 2
+.Lerrno3:
+ .long errno@GOTTPOFF
+.Lexit:
+ mov.l r2, @r0
+#else
+ mov r2, r8
+ mov.l .Lerrloc3, r1
+ bsrf r1
+ nop
+.Lerrloc3b:
+ mov r8, @r0
+#endif
+ lds.l @r15+, pr
+ mov.l @r15+, r8
+ mov.l @r15+, r12
+ rts
+ mov #-1, r0
+
+ .align 2
+.Lmax:
+ .long SEM_VALUE_MAX
+.Lgot3:
+ .long _GLOBAL_OFFSET_TABLE_
+#if !USE___THREAD
+.Lerrloc3:
+ .long __errno_location@PLT-(.Lerrloc3b-.)
+#endif
+ .size __new_sem_post,.-__new_sem_post
+ weak_alias(__new_sem_post, sem_post)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
new file mode 100644
index 000000000..7fb61b273
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
@@ -0,0 +1,358 @@
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <tcb-offsets.h>
+#include <structsem.h>
+#include <lowlevellock.h>
+#include "lowlevel-atomic.h"
+
+
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
+
+ .text
+
+ .globl sem_timedwait
+ .type sem_timedwait,@function
+ .align 5
+sem_timedwait:
+.LSTARTCODE:
+ mov.l @r4, r0
+2:
+ tst r0, r0
+ bt 1f
+ mov r0, r3
+ mov r0, r6
+ add #-1, r3
+ CMPXCHG (r6, @r4, r3, r2)
+ bf/s 2b
+ mov r2, r0
+ rts
+ mov #0, r0
+
+1:
+ /* Check whether the timeout value is valid. */
+ mov.l r8, @-r15
+.Lpush_r8:
+ mov.l r9, @-r15
+.Lpush_r9:
+ mov.l r10, @-r15
+.Lpush_r10:
+ mov.l r12, @-r15
+.Lpush_r12:
+ sts.l pr, @-r15
+.Lpush_pr:
+ add #-8, r15
+.Lalloc:
+ mov r4, r8
+ mov r5, r9
+
+ /* Check for invalid nanosecond field. */
+ mov.l @(4,r9), r0
+ mov.l .L1g, r1
+ cmp/hs r1, r0
+ bt/s 6f
+ mov #EINVAL, r0
+ INC (@(NWAITERS,r8),r2)
+
+7:
+ /* Compute relative timeout. */
+ mov r15, r4
+ mov #0, r5
+ mov #__NR_gettimeofday, r3
+ trapa #0x12
+ SYSCALL_INST_PAD
+
+ mov.l @(4,r15), r0
+ mov.w .L1k, r1
+ dmulu.l r0, r1 /* Milli seconds to nano seconds. */
+ mov.l @r9, r2
+ mov.l @(4,r9), r3
+ mov.l @r15, r0
+ sts macl, r1
+ sub r0, r2
+ clrt
+ subc r1, r3
+ bf 5f
+ mov.l .L1g, r1
+ add r1, r3
+ add #-1, r2
+5:
+ cmp/pz r2
+ bf/s 6f /* Time is already up. */
+ mov #ETIMEDOUT, r0
+
+ /* Store relative timeout. */
+ mov.l r2, @r15
+ mov.l r3, @(4,r15)
+
+.LcleanupSTART:
+ mov.l .Lenable0, r1
+ bsrf r1
+ nop
+.Lenable0b:
+ mov r0, r10
+
+ mov r8, r4
+#if FUTEX_WAIT == 0
+ mov.l @(PRIVATE,r8), r5
+#else
+ mov.l @(PRIVATE,r8), r5
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+#endif
+ mov #0, r6
+ mov r15, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ mov.l .Ldisable0, r1
+ mov r10, r4
+ bsrf r1
+ mov r0, r10
+.Ldisable0b:
+ mov r10, r0
+.LcleanupEND:
+
+ tst r0, r0
+ bt 9f
+ cmp/eq #-EWOULDBLOCK, r0
+ bf 3f
+9:
+ mov.l @r8, r0
+8:
+ tst r0, r0
+ bt 7b
+
+ mov r0, r3
+ mov r0, r4
+ add #-1, r3
+ CMPXCHG (r4, @r8, r3, r2)
+ bf/s 8b
+ mov r2, r0
+
+ DEC (@(NWAITERS,r8), r2)
+ mov #0, r0
+
+10:
+ add #8, r15
+ lds.l @r15+, pr
+ mov.l @r15+, r12
+ mov.l @r15+, r10
+ mov.l @r15+, r9
+ mov.l @r15+, r8
+ rts
+ nop
+
+3:
+ neg r0, r0
+6:
+ mov r0, r10
+ mova .Lgot2, r0
+ mov.l .Lgot2, r12
+ add r0, r12
+
+#if USE___THREAD
+ mov.l .Lerrno2, r0
+ stc gbr, r1
+ mov.l @(r0, r12), r0
+ bra .Lexit
+ add r1, r0
+ .align 2
+.Lerrno2:
+ .long errno@GOTTPOFF
+.Lexit:
+#else
+ mov.l .Lerrloc2, r1
+ bsrf r1
+ nop
+.Lerrloc2b:
+#endif
+ mov.l r10, @r0
+ DEC (@(NWAITERS,r8), r2)
+ bra 10b
+ mov #-1, r0
+
+.L1k:
+ .word 1000
+ .align 2
+.L1g:
+ .long 1000000000
+.Lgot2:
+ .long _GLOBAL_OFFSET_TABLE_
+#if !USE___THREAD
+.Lerrloc2:
+ .long __errno_location@PLT-(.Lerrloc2b-.)
+#endif
+.Lenable0:
+ .long __pthread_enable_asynccancel-.Lenable0b
+.Ldisable0:
+ .long __pthread_disable_asynccancel-.Ldisable0b
+ .size sem_timedwait,.-sem_timedwait
+
+ .type sem_wait_cleanup,@function
+sem_wait_cleanup:
+ DEC (@(NWAITERS,r8), r2)
+.LcallUR:
+ mov.l .Lresume, r1
+#ifdef __PIC__
+ add r12, r1
+#endif
+ jsr @r1
+ nop
+ sleep
+
+ .align 2
+.Lresume:
+#ifdef __PIC__
+ .long _Unwind_Resume@GOTOFF
+#else
+ .long _Unwind_Resume
+#endif
+.LENDCODE:
+ .size sem_wait_cleanup,.-sem_wait_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff ! @LPStart format (omit)
+ .byte 0xff ! @TType format (omit)
+ .byte 0x01 ! call-site format
+ ! DW_EH_PE_uleb128
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 sem_wait_cleanup-.LSTARTCODE
+ .uleb128 0
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+ .ualong .LENDCIE-.LSTARTCIE ! Length of the CIE.
+.LSTARTCIE:
+ .ualong 0 ! CIE ID.
+ .byte 1 ! Version number.
+#ifdef SHARED
+ .string "zPLR" ! NUL-terminated augmentation
+ ! string.
+#else
+ .string "zPL" ! NUL-terminated augmentation
+ ! string.
+#endif
+ .uleb128 1 ! Code alignment factor.
+ .sleb128 -4 ! Data alignment factor.
+ .byte 0x11 ! Return address register
+ ! column.
+#ifdef SHARED
+ .uleb128 7 ! Augmentation value length.
+ .byte 0x9b ! Personality: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4
+ ! + DW_EH_PE_indirect
+ .ualong DW.ref.__gcc_personality_v0-.
+ .byte 0x1b ! LSDA Encoding: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4.
+ .byte 0x1b ! FDE Encoding: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4.
+#else
+ .uleb128 6 ! Augmentation value length.
+ .byte 0x0 ! Personality: absolute
+ .ualong __gcc_personality_v0
+ .byte 0x0 ! LSDA Encoding: absolute
+#endif
+ .byte 0x0c ! DW_CFA_def_cfa
+ .uleb128 0xf
+ .uleb128 0
+ .align 4
+.LENDCIE:
+
+ .ualong .LENDFDE-.LSTARTFDE ! Length of the FDE.
+.LSTARTFDE:
+ .ualong .LSTARTFDE-.LSTARTFRAME ! CIE pointer.
+#ifdef SHARED
+ .ualong .LSTARTCODE-. ! PC-relative start address
+ ! of the code.
+#else
+ .ualong .LSTARTCODE ! Start address of the code.
+#endif
+ .ualong .LENDCODE-.LSTARTCODE ! Length of the code.
+ .uleb128 4 ! Augmentation size
+#ifdef SHARED
+ .ualong .LexceptSTART-.
+#else
+ .ualong .LexceptSTART
+#endif
+
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r8-.LSTARTCODE
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 4
+ .byte 0x88 ! DW_CFA_offset r8
+ .uleb128 1
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r9-.Lpush_r8
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0x89 ! DW_CFA_offset r9
+ .uleb128 2
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r10-.Lpush_r9
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 12
+ .byte 0x8a ! DW_CFA_offset r10
+ .uleb128 3
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r12-.Lpush_r10
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0x8c ! DW_CFA_offset r12
+ .uleb128 4
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_pr-.Lpush_r12
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 20
+ .byte 0x91 ! DW_CFA_offset pr
+ .uleb128 5
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lalloc-.Lpush_pr
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 28
+ .align 4
+.LENDFDE:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
new file mode 100644
index 000000000..b46eb1a56
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
@@ -0,0 +1,90 @@
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <lowlevellock.h>
+#include "lowlevel-atomic.h"
+
+
+ .text
+
+ .globl __new_sem_trywait
+ .type __new_sem_trywait,@function
+ .align 5
+__new_sem_trywait:
+ mov.l r12, @-r15
+ mov.l r8, @-r15
+ sts.l pr, @-r15
+ mov r4, r8
+ mov.l @r8, r0
+2:
+ tst r0, r0
+ bt 1f
+
+ mov r0, r3
+ mov r0, r4
+ add #-1, r3
+ CMPXCHG (r4, @r8, r3, r2)
+ bf/s 2b
+ mov r2, r0
+
+ lds.l @r15+, pr
+ mov.l @r15+, r8
+ mov.l @r15+, r12
+ rts
+ mov #0, r0
+
+1:
+ mov #EAGAIN, r8
+ mova .Lgot1, r0
+ mov.l .Lgot1, r12
+ add r0, r12
+
+#if USE___THREAD
+ mov.l .Lerrno1, r0
+ stc gbr, r1
+ mov.l @(r0, r12), r0
+ bra .Lexit
+ add r1, r0
+ .align 2
+.Lerrno1:
+ .long errno@GOTTPOFF
+.Lexit:
+#else
+ mov.l .Lerrloc1, r1
+ bsrf r1
+ nop
+.Lerrloc1b:
+#endif
+ mov.l r8, @r0
+ lds.l @r15+, pr
+ mov.l @r15+, r8
+ mov.l @r15+, r12
+ rts
+ mov #-1, r0
+
+ .align 2
+.Lgot1:
+ .long _GLOBAL_OFFSET_TABLE_
+#if !USE___THREAD
+.Lerrloc1:
+ .long __errno_location@PLT-(.Lerrloc1b-.)
+#endif
+ .size __new_sem_trywait,.-__new_sem_trywait
+ weak_alias(__new_sem_trywait, sem_trywait)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
new file mode 100644
index 000000000..00a125bc5
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
@@ -0,0 +1,303 @@
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <tcb-offsets.h>
+#include <structsem.h>
+#include <lowlevellock.h>
+#include "lowlevel-atomic.h"
+
+
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
+
+ .text
+
+ .globl __new_sem_wait
+ .type __new_sem_wait,@function
+ .align 5
+__new_sem_wait:
+.LSTARTCODE:
+ mov.l r8, @-r15
+.Lpush_r8:
+ mov.l r10, @-r15
+.Lpush_r10:
+ mov.l r12, @-r15
+.Lpush_r12:
+ sts.l pr, @-r15
+.Lpush_pr:
+ mov r4, r8
+
+ mov.l @r8, r0
+2:
+ tst r0, r0
+ bt 1f
+ mov r0, r3
+ mov r0, r4
+ add #-1, r3
+ CMPXCHG (r4, @r8, r3, r2)
+ bf/s 2b
+ mov r2, r0
+7:
+ mov #0, r0
+9:
+ lds.l @r15+, pr
+ mov.l @r15+, r12
+ mov.l @r15+, r10
+ rts
+ mov.l @r15+, r8
+
+.Lafter_ret:
+1:
+ INC (@(NWAITERS,r8),r2)
+
+.LcleanupSTART:
+6:
+ mov.l .Lenable0, r1
+ bsrf r1
+ nop
+.Lenable0b:
+ mov r0, r10
+
+ mov r8, r4
+#if FUTEX_WAIT == 0
+ mov.l @(PRIVATE,r8), r5
+#else
+ mov.l @(PRIVATE,r8), r5
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+#endif
+ mov #0, r6
+ mov #0, r7
+ mov #SYS_futex, r3
+ extu.b r3, r3
+ trapa #0x14
+ SYSCALL_INST_PAD
+
+ mov.l .Ldisable0, r1
+ mov r10, r4
+ bsrf r1
+ mov r0, r10
+.Ldisable0b:
+ mov r10, r0
+.LcleanupEND:
+
+ tst r0, r0
+ bt 3f
+ cmp/eq #-EWOULDBLOCK, r0
+ bf 4f
+
+3:
+ mov.l @r8, r0
+5:
+ tst r0, r0
+ bt 6b
+
+ mov r0, r3
+ mov r0, r4
+ add #-1, r3
+ CMPXCHG (r4, @r8, r3, r2)
+ bf/s 5b
+ mov r2, r0
+
+ DEC (@(NWAITERS,r8), r2)
+ bra 7b
+ nop
+
+4:
+ neg r0, r0
+ mov r0, r4
+ DEC (@(NWAITERS,r8), r2)
+ mov r4, r8
+ mova .Lgot0, r0
+ mov.l .Lgot0, r12
+ add r0, r12
+
+#if USE___THREAD
+ mov.l .Lerrno0, r0
+ stc gbr, r1
+ mov.l @(r0, r12), r0
+ bra .Lexit
+ add r1, r0
+ .align 2
+.Lerrno0:
+ .long errno@GOTTPOFF
+.Lexit:
+#else
+ mov.l .Lerrloc0, r1
+ bsrf r1
+ nop
+.Lerrloc0b:
+#endif
+ mov.l r8, @r0
+ bra 9b
+ mov #-1, r0
+
+ .align 2
+.Lgot0:
+ .long _GLOBAL_OFFSET_TABLE_
+#if !USE___THREAD
+.Lerrloc0:
+ .long __errno_location@PLT-(.Lerrloc0b-.)
+#endif
+.Lenable0:
+ .long __pthread_enable_asynccancel-.Lenable0b
+.Ldisable0:
+ .long __pthread_disable_asynccancel-.Ldisable0b
+ .size __new_sem_wait,.-__new_sem_wait
+ weak_alias(__new_sem_wait, sem_wait)
+
+
+ .type sem_wait_cleanup,@function
+sem_wait_cleanup:
+ DEC (@(NWAITERS,r8), r2)
+.LcallUR:
+ mov.l .Lresume, r1
+#ifdef __PIC__
+ add r12, r1
+#endif
+ jsr @r1
+ nop
+ sleep
+
+ .align 2
+.Lresume:
+#ifdef __PIC__
+ .long _Unwind_Resume@GOTOFF
+#else
+ .long _Unwind_Resume
+#endif
+.LENDCODE:
+ .size sem_wait_cleanup,.-sem_wait_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff ! @LPStart format (omit)
+ .byte 0xff ! @TType format (omit)
+ .byte 0x01 ! call-site format
+ ! DW_EH_PE_uleb128
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 sem_wait_cleanup-.LSTARTCODE
+ .uleb128 0
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+ .ualong .LENDCIE-.LSTARTCIE ! Length of the CIE.
+.LSTARTCIE:
+ .ualong 0 ! CIE ID.
+ .byte 1 ! Version number.
+#ifdef SHARED
+ .string "zPLR" ! NUL-terminated augmentation
+ ! string.
+#else
+ .string "zPL" ! NUL-terminated augmentation
+ ! string.
+#endif
+ .uleb128 1 ! Code alignment factor.
+ .sleb128 -4 ! Data alignment factor.
+ .byte 0x11 ! Return address register
+ ! column.
+#ifdef SHARED
+ .uleb128 7 ! Augmentation value length.
+ .byte 0x9b ! Personality: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4
+ ! + DW_EH_PE_indirect
+ .ualong DW.ref.__gcc_personality_v0-.
+ .byte 0x1b ! LSDA Encoding: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4.
+ .byte 0x1b ! FDE Encoding: DW_EH_PE_pcrel
+ ! + DW_EH_PE_sdata4.
+#else
+ .uleb128 6 ! Augmentation value length.
+ .byte 0x0 ! Personality: absolute
+ .ualong __gcc_personality_v0
+ .byte 0x0 ! LSDA Encoding: absolute
+#endif
+ .byte 0x0c ! DW_CFA_def_cfa
+ .uleb128 0xf
+ .uleb128 0
+ .align 4
+.LENDCIE:
+
+ .ualong .LENDFDE-.LSTARTFDE ! Length of the FDE.
+.LSTARTFDE:
+ .ualong .LSTARTFDE-.LSTARTFRAME ! CIE pointer.
+#ifdef SHARED
+ .ualong .LSTARTCODE-. ! PC-relative start address
+ ! of the code.
+#else
+ .ualong .LSTARTCODE ! Start address of the code.
+#endif
+ .ualong .LENDCODE-.LSTARTCODE ! Length of the code.
+ .uleb128 4 ! Augmentation size
+#ifdef SHARED
+ .ualong .LexceptSTART-.
+#else
+ .ualong .LexceptSTART
+#endif
+
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r8-.LSTARTCODE
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 4
+ .byte 0x88 ! DW_CFA_offset r8
+ .uleb128 1
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r10-.Lpush_r8
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0x8a ! DW_CFA_offset r10
+ .uleb128 2
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_r12-.Lpush_r10
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 12
+ .byte 0x8c ! DW_CFA_offset r12
+ .uleb128 3
+ .byte 4 ! DW_CFA_advance_loc4
+ .ualong .Lpush_pr-.Lpush_r12
+ .byte 14 ! DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0x91 ! DW_CFA_offset pr
+ .uleb128 4
+ .align 4
+.LENDFDE:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h
new file mode 100644
index 000000000..8cdcac556
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h
@@ -0,0 +1,4 @@
+/* 4 instruction cycles not accessing cache and TLB are needed after
+ trapa instruction to avoid an SH-4 silicon bug. */
+#define NEED_SYSCALL_INST_PAD
+#include <sysdeps/unix/sysv/linux/sh/lowlevellock.h>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/smp.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/smp.h
new file mode 100644
index 000000000..2c0cbe99a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/smp.h
@@ -0,0 +1,24 @@
+/* Determine whether the host has multiple processors. SH version.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+static inline int
+is_smp_system (void)
+{
+ return 0;
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
new file mode 100644
index 000000000..ad2ca40ac
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
@@ -0,0 +1,169 @@
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <tls.h>
+#include <sysdep.h>
+#ifndef __ASSEMBLER__
+# include <pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# define _IMM12 #-12
+# define _IMM16 #-16
+# define _IMP16 #16
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name); \
+ .Lpseudo_start: \
+ SINGLE_THREAD_P; \
+ bf .Lpseudo_cancel; \
+ .type __##syscall_name##_nocancel,@function; \
+ .globl __##syscall_name##_nocancel; \
+ __##syscall_name##_nocancel: \
+ DO_CALL (syscall_name, args); \
+ mov r0,r1; \
+ mov _IMM12,r2; \
+ shad r2,r1; \
+ not r1,r1; \
+ tst r1,r1; \
+ bt .Lsyscall_error; \
+ bra .Lpseudo_end; \
+ nop; \
+ .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
+ .Lpseudo_cancel: \
+ sts.l pr,@-r15; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (pr, 0); \
+ add _IMM16,r15; \
+ cfi_adjust_cfa_offset (16); \
+ SAVE_ARGS_##args; \
+ CENABLE; \
+ LOAD_ARGS_##args; \
+ add _IMP16,r15; \
+ cfi_adjust_cfa_offset (-16); \
+ lds.l @r15+,pr; \
+ cfi_adjust_cfa_offset (-4); \
+ cfi_restore (pr); \
+ DO_CALL(syscall_name, args); \
+ SYSCALL_INST_PAD; \
+ sts.l pr,@-r15; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (pr, 0); \
+ mov.l r0,@-r15; \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (r0, 0); \
+ CDISABLE; \
+ mov.l @r15+,r0; \
+ cfi_adjust_cfa_offset (-4); \
+ lds.l @r15+,pr; \
+ cfi_adjust_cfa_offset (-4); \
+ cfi_restore (pr); \
+ mov r0,r1; \
+ mov _IMM12,r2; \
+ shad r2,r1; \
+ not r1,r1; \
+ tst r1,r1; \
+ bf .Lpseudo_end; \
+ .Lsyscall_error: \
+ SYSCALL_ERROR_HANDLER; \
+ .Lpseudo_end:
+
+# undef PSEUDO_END
+# define PSEUDO_END(sym) \
+ END (sym)
+
+# define SAVE_ARGS_0 /* Nothing. */
+# define SAVE_ARGS_1 SAVE_ARGS_0; mov.l r4,@(0,r15); cfi_offset (r4,-4)
+# define SAVE_ARGS_2 SAVE_ARGS_1; mov.l r5,@(4,r15); cfi_offset (r5,-8)
+# define SAVE_ARGS_3 SAVE_ARGS_2; mov.l r6,@(8,r15); cfi_offset (r6,-12)
+# define SAVE_ARGS_4 SAVE_ARGS_3; mov.l r7,@(12,r15); cfi_offset (r7,-16)
+# define SAVE_ARGS_5 SAVE_ARGS_4
+# define SAVE_ARGS_6 SAVE_ARGS_5
+
+# define LOAD_ARGS_0 /* Nothing. */
+# define LOAD_ARGS_1 LOAD_ARGS_0; mov.l @(0,r15),r4
+# define LOAD_ARGS_2 LOAD_ARGS_1; mov.l @(4,r15),r5
+# define LOAD_ARGS_3 LOAD_ARGS_2; mov.l @(8,r15),r6
+# define LOAD_ARGS_4 LOAD_ARGS_3; mov.l @(12,r15),r7
+# define LOAD_ARGS_5 LOAD_ARGS_4
+# define LOAD_ARGS_6 LOAD_ARGS_5
+
+# ifdef IS_IN_libpthread
+# define __local_enable_asynccancel __pthread_enable_asynccancel
+# define __local_disable_asynccancel __pthread_disable_asynccancel
+# elif !defined NOT_IN_libc
+# define __local_enable_asynccancel __libc_enable_asynccancel
+# define __local_disable_asynccancel __libc_disable_asynccancel
+# elif defined IS_IN_librt
+# define __local_enable_asynccancel __librt_enable_asynccancel
+# define __local_disable_asynccancel __librt_disable_asynccancel
+# else
+# error Unsupported library
+# endif
+
+# define CENABLE \
+ mov.l 1f,r0; \
+ bsrf r0; \
+ nop; \
+ 0: bra 2f; \
+ mov r0,r2; \
+ .align 2; \
+ 1: .long __local_enable_asynccancel - 0b; \
+ 2:
+
+# define CDISABLE \
+ mov.l 1f,r0; \
+ bsrf r0; \
+ mov r2,r4; \
+ 0: bra 2f; \
+ nop; \
+ .align 2; \
+ 1: .long __local_disable_asynccancel - 0b; \
+ 2:
+
+# ifndef __ASSEMBLER__
+# define SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+# else
+# define SINGLE_THREAD_P \
+ stc gbr,r0; \
+ mov.w 0f,r1; \
+ sub r1,r0; \
+ mov.l @(MULTIPLE_THREADS_OFFSET,r0),r0; \
+ bra 1f; \
+ tst r0,r0; \
+ 0: .word TLS_PRE_TCB_SIZE; \
+ 1:
+
+# endif
+
+#elif !defined __ASSEMBLER__
+
+# define SINGLE_THREAD_P (1)
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/vfork.S
new file mode 100644
index 000000000..a45c09fd6
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/vfork.S
@@ -0,0 +1,71 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <tcb-offsets.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+ /* Save the PID value. */
+ stc gbr, r2
+ mov.w .L2, r0
+ mov.l @(r0,r2), r4
+ neg r4, r1
+ tst r1, r1
+ bf 1f
+ mov #1, r1
+ rotr r1
+1:
+ mov.l r1, @(r0,r2)
+
+ mov.w .L1, r3
+ trapa #0x10
+ mov r0, r1
+
+ /* Restore the old PID value in the parent. */
+ tst r0, r0
+ bt.s 2f
+ stc gbr, r2
+ mov.w .L2, r0
+ mov.l r4, @(r0,r2)
+ mov r1, r0
+2:
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lpseudo_end
+ SYSCALL_ERROR_HANDLER
+.Lpseudo_end:
+ rts
+ nop
+.L1:
+ .word __NR_vfork
+.L2:
+ .word PID - TLS_PRE_TCB_SIZE
+ .align 2
+PSEUDO_END (__vfork)
+hidden_def (vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sigtimedwait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sigtimedwait.c
new file mode 100644
index 000000000..5159bf9b8
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sigtimedwait.c
@@ -0,0 +1,88 @@
+/* Copyright (C) 1997,1998,2000,2002,2003,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <pthreadP.h>
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_rt_sigtimedwait
+
+static int
+do_sigtimedwait (const sigset_t *set, siginfo_t *info,
+ const struct timespec *timeout)
+{
+#ifdef SIGCANCEL
+ sigset_t tmpset;
+ if (set != NULL
+ && (__builtin_expect (__sigismember (set, SIGCANCEL), 0)
+# ifdef SIGSETXID
+ || __builtin_expect (__sigismember (set, SIGSETXID), 0)
+# endif
+ ))
+ {
+ /* Create a temporary mask without the bit for SIGCANCEL set. */
+ // We are not copying more than we have to.
+ memcpy (&tmpset, set, _NSIG / 8);
+ __sigdelset (&tmpset, SIGCANCEL);
+# ifdef SIGSETXID
+ __sigdelset (&tmpset, SIGSETXID);
+# endif
+ set = &tmpset;
+ }
+#endif
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ int result = INLINE_SYSCALL (rt_sigtimedwait, 4, set,
+ info, timeout, _NSIG / 8);
+
+ /* The kernel generates a SI_TKILL code in si_code in case tkill is
+ used. tkill is transparently used in raise(). Since having
+ SI_TKILL as a code is useful in general we fold the results
+ here. */
+ if (result != -1 && info != NULL && info->si_code == SI_TKILL)
+ info->si_code = SI_USER;
+
+ return result;
+}
+
+
+/* Return any pending signal or wait for one for the given time. */
+int attribute_hidden
+__sigtimedwait (const sigset_t *set, siginfo_t *info,
+ const struct timespec *timeout)
+{
+ if (SINGLE_THREAD_P)
+ return do_sigtimedwait (set, info, timeout);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ int result = do_sigtimedwait (set, info, timeout);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+weak_alias (__sigtimedwait, sigtimedwait)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sigwait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sigwait.c
new file mode 100644
index 000000000..bde0a9292
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sigwait.c
@@ -0,0 +1,2 @@
+#include <pthreadP.h>
+#include "../../../../../../libc/signal/sigwait.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sigwaitinfo.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sigwaitinfo.c
new file mode 100644
index 000000000..6c47fdee6
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sigwaitinfo.c
@@ -0,0 +1,88 @@
+/* Copyright (C) 1997,1998,2000,2002,2003,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <pthreadP.h>
+#include <errno.h>
+#include <signal.h>
+#define __need_NULL
+#include <stddef.h>
+#include <string.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_rt_sigtimedwait
+
+static int
+do_sigwaitinfo (const sigset_t *set, siginfo_t *info)
+{
+#ifdef SIGCANCEL
+ sigset_t tmpset;
+ if (set != NULL
+ && (__builtin_expect (__sigismember (set, SIGCANCEL), 0)
+# ifdef SIGSETXID
+ || __builtin_expect (__sigismember (set, SIGSETXID), 0)
+# endif
+ ))
+ {
+ /* Create a temporary mask without the bit for SIGCANCEL set. */
+ // We are not copying more than we have to.
+ memcpy (&tmpset, set, _NSIG / 8);
+ __sigdelset (&tmpset, SIGCANCEL);
+# ifdef SIGSETXID
+ __sigdelset (&tmpset, SIGSETXID);
+# endif
+ set = &tmpset;
+ }
+#endif
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ int result = INLINE_SYSCALL (rt_sigtimedwait, 4, set,
+ info, NULL, _NSIG / 8);
+
+ /* The kernel generates a SI_TKILL code in si_code in case tkill is
+ used. tkill is transparently used in raise(). Since having
+ SI_TKILL as a code is useful in general we fold the results
+ here. */
+ if (result != -1 && info != NULL && info->si_code == SI_TKILL)
+ info->si_code = SI_USER;
+
+ return result;
+}
+
+
+/* Return any pending signal or wait for one for the given time. */
+int
+__sigwaitinfo (const sigset_t *set, siginfo_t *info)
+{
+ if (SINGLE_THREAD_P)
+ return do_sigwaitinfo (set, info);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ int result = do_sigwaitinfo (set, info);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
+}
+weak_alias (__sigwaitinfo, sigwaitinfo)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sleep.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sleep.c
new file mode 100644
index 000000000..9e948adce
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sleep.c
@@ -0,0 +1,2 @@
+#include <pthreadP.h>
+#include <../../../../../../libc/unistd/sleep.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/smp.h b/libpthread/nptl/sysdeps/unix/sysv/linux/smp.h
new file mode 100644
index 000000000..fcc34f768
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/smp.h
@@ -0,0 +1,28 @@
+/* Determine whether the host has multiple processors. Linux version.
+ Copyright (C) 1996, 2002, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Test whether the machine has more than one processor. This is not the
+ best test but good enough. More complicated tests would require `malloc'
+ which is not available at that time. */
+static inline int
+is_smp_system (void)
+{
+ /* Assume all machines are SMP and/or CMT and/or SMT. */
+ return 1;
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile
new file mode 100644
index 000000000..43a6fad84
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile
@@ -0,0 +1,13 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../../../../../
+top_builddir=../../../../../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.arch
+include $(top_srcdir)Makerules
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch
new file mode 100644
index 000000000..1e4f54488
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch
@@ -0,0 +1,67 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+libpthread_SSRC = pt-vfork.S clone.S
+libpthread_CSRC = pthread_once.c lowlevellock.c \
+ pthread_barrier_init.c pthread_barrier_wait.c pthread_barrier_destroy.c
+
+libc_a_CSRC = fork.c libc-lowlevellock.c
+libc_a_SSRC = clone.S vfork.S
+
+CFLAGS-OMIT-fork.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-libc-lowlevellock.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
+ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y)
+CFLAGS-fork.c = -D__USE_STDIO_FUTEXES__
+endif
+
+ASFLAGS-pt-vfork.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+
+CFLAGS-pthread_once.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-lowlevellock.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
+
+ASFLAGS-clone.S = -D_LIBC_REENTRANT
+ASFLAGS-vfork.S = -D_LIBC_REENTRANT
+
+ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y)
+#Needed to use the correct SYSCALL_ERROR_HANDLER
+ASFLAGS-clone.S += -DUSE___THREAD
+ASFLAGS-vfork.S += -DUSE___THREAD
+ASFLAGS-pt-vfork.S += -DUSE___THREAD
+endif
+
+CFLAGS += $(SSP_ALL_CFLAGS)
+#CFLAGS:=$(CFLAGS:-O1=-O2)
+
+LINUX_ARCH_DIR:=$(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/sparc
+LINUX_ARCH_OUT:=$(top_builddir)libpthread/nptl/sysdeps/unix/sysv/linux/sparc
+
+LINUX_ARCH_OBJ:=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libpthread_SSRC))
+LINUX_ARCH_OBJ+=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libpthread_CSRC))
+
+ifeq ($(DOPIC),y)
+libpthread-a-y += $(LINUX_ARCH_OBJ:.o=.os)
+else
+libpthread-a-y += $(LINUX_ARCH_OBJ)
+endif
+libpthread-so-y += $(LINUX_ARCH_OBJ:.o=.oS)
+
+libpthread-nomulti-y+=$(LINUX_ARCH_OBJS)
+
+LIBC_LINUX_ARCH_OBJ:=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libc_a_CSRC))
+LIBC_LINUX_ARCH_OBJ+=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libc_a_SSRC))
+
+libc-static-y+=$(LIBC_LINUX_ARCH_OBJ)
+libc-shared-y+=$(LIBC_LINUX_ARCH_OBJ:.o=.oS)
+
+libc-nomulti-y+=$(LIBC_LINUX_ARCH_OBJ)
+
+objclean-y+=nptl_linux_arch_clean
+
+nptl_linux_arch_clean:
+ $(do_rm) $(addprefix $(LINUX_ARCH_OUT)/*., o os oS)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h
new file mode 100644
index 000000000..6e356031d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h
@@ -0,0 +1,100 @@
+/* Minimum guaranteed maximum values for system limits. Linux/SPARC version.
+ Copyright (C) 1993-1998,2000,2002-2004,2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* The kernel header pollutes the namespace with the NR_OPEN symbol
+ and defines LINK_MAX although filesystems have different maxima. A
+ similar thing is true for OPEN_MAX: the limit can be changed at
+ runtime and therefore the macro must not be defined. Remove this
+ after including the header if necessary. */
+#ifndef NR_OPEN
+# define __undef_NR_OPEN
+#endif
+#ifndef LINK_MAX
+# define __undef_LINK_MAX
+#endif
+#ifndef OPEN_MAX
+# define __undef_OPEN_MAX
+#endif
+#ifndef ARG_MAX
+# define __undef_ARG_MAX
+#endif
+
+/* The kernel sources contain a file with all the needed information. */
+#include <linux/limits.h>
+
+/* Have to remove NR_OPEN? */
+#ifdef __undef_NR_OPEN
+# undef NR_OPEN
+# undef __undef_NR_OPEN
+#endif
+/* Have to remove LINK_MAX? */
+#ifdef __undef_LINK_MAX
+# undef LINK_MAX
+# undef __undef_LINK_MAX
+#endif
+/* Have to remove OPEN_MAX? */
+#ifdef __undef_OPEN_MAX
+# undef OPEN_MAX
+# undef __undef_OPEN_MAX
+#endif
+/* Have to remove ARG_MAX? */
+#ifdef __undef_ARG_MAX
+# undef ARG_MAX
+# undef __undef_ARG_MAX
+#endif
+
+/* The number of data keys per process. */
+#define _POSIX_THREAD_KEYS_MAX 128
+/* This is the value this implementation supports. */
+#define PTHREAD_KEYS_MAX 1024
+
+/* Controlling the iterations of destructors for thread-specific data. */
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+/* Number of iterations this implementation does. */
+#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS
+
+/* The number of threads per process. */
+#define _POSIX_THREAD_THREADS_MAX 64
+/* We have no predefined limit on the number of threads. */
+#undef PTHREAD_THREADS_MAX
+
+/* Maximum amount by which a process can descrease its asynchronous I/O
+ priority level. */
+#define AIO_PRIO_DELTA_MAX 20
+
+/* Minimum size for a thread. We are free to choose a reasonable value. */
+#define PTHREAD_STACK_MIN 24576
+
+/* Maximum number of timer expiration overruns. */
+#define DELAYTIMER_MAX 2147483647
+
+/* Maximum tty name length. */
+#define TTY_NAME_MAX 32
+
+/* Maximum login name length. This is arbitrary. */
+#define LOGIN_NAME_MAX 256
+
+/* Maximum host name length. */
+#define HOST_NAME_MAX 64
+
+/* Maximum message queue priority level. */
+#define MQ_PRIO_MAX 32768
+
+/* Maximum value the semaphore can have. */
+#define SEM_VALUE_MAX (2147483647)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h
new file mode 100644
index 000000000..faf058486
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h
@@ -0,0 +1,221 @@
+/* Machine-specific pthread type layouts. SPARC version.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H 1
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+# define __SIZEOF_PTHREAD_ATTR_T 56
+# define __SIZEOF_PTHREAD_MUTEX_T 40
+# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+# define __SIZEOF_PTHREAD_COND_T 48
+# define __SIZEOF_PTHREAD_CONDATTR_T 4
+# define __SIZEOF_PTHREAD_RWLOCK_T 56
+# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+# define __SIZEOF_PTHREAD_BARRIER_T 32
+# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+#else
+# define __SIZEOF_PTHREAD_ATTR_T 36
+# define __SIZEOF_PTHREAD_MUTEX_T 24
+# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+# define __SIZEOF_PTHREAD_COND_T 48
+# define __SIZEOF_PTHREAD_CONDATTR_T 4
+# define __SIZEOF_PTHREAD_RWLOCK_T 32
+# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+# define __SIZEOF_PTHREAD_BARRIER_T 20
+# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+#endif
+
+
+/* Thread identifiers. The structure of the attribute type is
+ deliberately not exposed. */
+typedef unsigned long int pthread_t;
+
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_ATTR_T];
+ long int __align;
+} pthread_attr_t;
+
+
+#if __WORDSIZE == 64
+typedef struct __pthread_internal_list
+{
+ struct __pthread_internal_list *__prev;
+ struct __pthread_internal_list *__next;
+} __pthread_list_t;
+#else
+typedef struct __pthread_internal_slist
+{
+ struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+#endif
+
+
+/* Data structures for mutex handling. The structure of the attribute
+ type is deliberately not exposed. */
+typedef union
+{
+ struct __pthread_mutex_s
+ {
+ int __lock;
+ unsigned int __count;
+ int __owner;
+#if __WORDSIZE == 64
+ unsigned int __nusers;
+#endif
+ /* KIND must stay at this position in the structure to maintain
+ binary compatibility. */
+ int __kind;
+#if __WORDSIZE == 64
+ int __spins;
+ __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV 1
+#else
+ unsigned int __nusers;
+ __extension__ union
+ {
+ int __spins;
+ __pthread_slist_t __list;
+ };
+#endif
+ } __data;
+ char __size[__SIZEOF_PTHREAD_MUTEX_T];
+ long int __align;
+} pthread_mutex_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+ int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling. The structure of
+ the attribute type is deliberately not exposed. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned int __futex;
+ __extension__ unsigned long long int __total_seq;
+ __extension__ unsigned long long int __wakeup_seq;
+ __extension__ unsigned long long int __woken_seq;
+ void *__mutex;
+ unsigned int __nwaiters;
+ unsigned int __broadcast_seq;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_COND_T];
+ __extension__ long long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+ int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Data structure for read-write lock variable handling. The
+ structure of the attribute type is deliberately not exposed. */
+typedef union
+{
+# if __WORDSIZE == 64
+ struct
+ {
+ int __lock;
+ unsigned int __nr_readers;
+ unsigned int __readers_wakeup;
+ unsigned int __writer_wakeup;
+ unsigned int __nr_readers_queued;
+ unsigned int __nr_writers_queued;
+ int __writer;
+ int __shared;
+ unsigned long int __pad1;
+ unsigned long int __pad2;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned int __flags;
+ } __data;
+# else
+ struct
+ {
+ int __lock;
+ unsigned int __nr_readers;
+ unsigned int __readers_wakeup;
+ unsigned int __writer_wakeup;
+ unsigned int __nr_readers_queued;
+ unsigned int __nr_writers_queued;
+ unsigned char __pad1;
+ unsigned char __pad2;
+ unsigned char __shared;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned char __flags;
+ int __writer;
+ } __data;
+# endif
+ char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+ long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+ long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type. */
+typedef volatile int pthread_spinlock_t;
+
+
+/* POSIX barriers data type. The structure of the type is
+ deliberately not exposed. */
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIER_T];
+ long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+ int __align;
+} pthread_barrierattr_t;
+#endif
+
+
+#endif /* bits/pthreadtypes.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h
new file mode 100644
index 000000000..8fd7d344e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/bits/semaphore.h
@@ -0,0 +1,41 @@
+/* Machine-specific POSIX semaphore type layouts. SPARC version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+# define __SIZEOF_SEM_T 32
+#else
+# define __SIZEOF_SEM_T 16
+#endif
+
+/* Value returned if `sem_open' failed. */
+#define SEM_FAILED ((sem_t *) 0)
+
+
+typedef union
+{
+ char __size[__SIZEOF_SEM_T];
+ long int __align;
+} sem_t;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/clone.S
new file mode 100644
index 000000000..dfc5e8261
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/clone.S
@@ -0,0 +1,5 @@
+#if defined(__arch64__)
+#include "./sparc64/clone.S"
+#else
+#include "./sparc32/clone.S"
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/fork.c
new file mode 100644
index 000000000..1cd79110a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/fork.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sched.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+
+#define ARCH_FORK() \
+ INLINE_CLONE_SYSCALL (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \
+ 0, NULL, NULL, &THREAD_SELF->tid)
+
+#include "../fork.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/internaltypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/internaltypes.h
new file mode 100644
index 000000000..4f400a3fe
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/internaltypes.h
@@ -0,0 +1,34 @@
+#ifndef _INTERNALTYPES_H
+#include "../internaltypes.h"
+
+union sparc_pthread_barrier
+{
+ struct pthread_barrier b;
+ struct sparc_pthread_barrier_s
+ {
+ unsigned int curr_event;
+ int lock;
+ unsigned int left;
+ unsigned int init_count;
+ unsigned char left_lock;
+ unsigned char pshared;
+ } s;
+};
+
+struct sparc_new_sem
+{
+ unsigned int value;
+ unsigned char lock;
+ unsigned char private;
+ unsigned char pad[2];
+ unsigned long int nwaiters;
+};
+
+struct sparc_old_sem
+{
+ unsigned int value;
+ unsigned char lock;
+ unsigned char private;
+};
+
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/libc-lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/libc-lowlevellock.c
new file mode 100644
index 000000000..b19282281
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/libc-lowlevellock.c
@@ -0,0 +1,21 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* No difference to lowlevellock.c, except we lose a couple of functions. */
+#include "lowlevellock.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c
new file mode 100644
index 000000000..0471d1f79
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c
@@ -0,0 +1,133 @@
+/* low level locking for pthread library. SPARC version.
+ Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <sys/time.h>
+#include <tls.h>
+
+
+void
+__lll_lock_wait_private (int *futex)
+{
+ do
+ {
+ int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1);
+ if (oldval != 0)
+ lll_futex_wait (futex, 2, LLL_PRIVATE);
+ }
+ while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0);
+}
+
+
+/* These functions don't get included in libc.so */
+#ifdef IS_IN_libpthread
+void
+__lll_lock_wait (int *futex, int private)
+{
+ do
+ {
+ int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1);
+ if (oldval != 0)
+ lll_futex_wait (futex, 2, private);
+ }
+ while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0);
+}
+
+
+int
+__lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
+{
+ /* Reject invalid timeouts. */
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+ return EINVAL;
+
+ do
+ {
+ struct timeval tv;
+ struct timespec rt;
+
+ /* Get the current time. */
+ (void) gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+ rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+ if (rt.tv_nsec < 0)
+ {
+ rt.tv_nsec += 1000000000;
+ --rt.tv_sec;
+ }
+
+ /* Already timed out? */
+ if (rt.tv_sec < 0)
+ return ETIMEDOUT;
+
+ /* Wait. */
+ int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1);
+ if (oldval != 0)
+ lll_futex_timed_wait (futex, 2, &rt, private);
+ }
+ while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0);
+
+ return 0;
+}
+
+
+int
+__lll_timedwait_tid (int *tidp, const struct timespec *abstime)
+{
+ int tid;
+
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+ return EINVAL;
+
+ /* Repeat until thread terminated. */
+ while ((tid = *tidp) != 0)
+ {
+ struct timeval tv;
+ struct timespec rt;
+
+ /* Get the current time. */
+ (void) gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+ rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+ if (rt.tv_nsec < 0)
+ {
+ rt.tv_nsec += 1000000000;
+ --rt.tv_sec;
+ }
+
+ /* Already timed out? */
+ if (rt.tv_sec < 0)
+ return ETIMEDOUT;
+
+ /* Wait until thread terminates. The kernel so far does not use
+ the private futex operations for this. */
+ if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT)
+ return ETIMEDOUT;
+ }
+
+ return 0;
+}
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
new file mode 100644
index 000000000..d8fe9be35
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
@@ -0,0 +1,297 @@
+/* Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Libr \ary; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H 1
+
+#include <time.h>
+#include <sys/param.h>
+#include <bits/pthreadtypes.h>
+#include <atomic.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+
+
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_REQUEUE 3
+#define FUTEX_CMP_REQUEUE 4
+#define FUTEX_WAKE_OP 5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_WAIT_BITSET 9
+#define FUTEX_WAKE_BITSET 10
+#define FUTEX_PRIVATE_FLAG 128
+#define FUTEX_CLOCK_REALTIME 256
+
+#define FUTEX_BITSET_MATCH_ANY 0xffffffff
+
+
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
+ & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
+
+#define lll_futex_wait(futexp, val, private) \
+ lll_futex_timed_wait (futexp, val, NULL, private)
+
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAIT, private), \
+ (val), (timespec)); \
+ __ret; \
+ })
+
+#define lll_futex_wake(futexp, nr, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAKE, private), \
+ (nr), 0); \
+ __ret; \
+ })
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+ (nr_wake), (nr_move), (mutex), (val)); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+#define lll_robust_dead(futexv, private) \
+ do \
+ { \
+ int *__futexp = &(futexv); \
+ atomic_or (__futexp, FUTEX_OWNER_DIED); \
+ lll_futex_wake (__futexp, 1, private); \
+ } \
+ while (0)
+
+/* Returns non-zero if error happened, zero if success. */
+#ifdef __sparc32_atomic_do_lock
+/* Avoid FUTEX_WAKE_OP if supporting pre-v9 CPUs. */
+# define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) 1
+#else
+# define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_WAKE_OP, private), \
+ (nr_wake), (nr_wake2), (futexp2), \
+ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+#endif
+
+static inline int
+__attribute__ ((always_inline))
+__lll_trylock (int *futex)
+{
+ return atomic_compare_and_exchange_val_24_acq (futex, 1, 0) != 0;
+}
+#define lll_trylock(futex) __lll_trylock (&(futex))
+
+static inline int
+__attribute__ ((always_inline))
+__lll_cond_trylock (int *futex)
+{
+ return atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0;
+}
+#define lll_cond_trylock(futex) __lll_cond_trylock (&(futex))
+
+static inline int
+__attribute__ ((always_inline))
+__lll_robust_trylock (int *futex, int id)
+{
+ return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0;
+}
+#define lll_robust_trylock(futex, id) \
+ __lll_robust_trylock (&(futex), id)
+
+
+extern void __lll_lock_wait_private (int *futex) attribute_hidden;
+extern void __lll_lock_wait (int *futex, int private) attribute_hidden;
+extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden;
+
+static inline void
+__attribute__ ((always_inline))
+__lll_lock (int *futex, int private)
+{
+ int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0);
+
+ if (__builtin_expect (val != 0, 0))
+ {
+ if (__builtin_constant_p (private) && private == LLL_PRIVATE)
+ __lll_lock_wait_private (futex);
+ else
+ __lll_lock_wait (futex, private);
+ }
+}
+#define lll_lock(futex, private) __lll_lock (&(futex), private)
+
+static inline int
+__attribute__ ((always_inline))
+__lll_robust_lock (int *futex, int id, int private)
+{
+ int result = 0;
+ if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+ result = __lll_robust_lock_wait (futex, private);
+ return result;
+}
+#define lll_robust_lock(futex, id, private) \
+ __lll_robust_lock (&(futex), id, private)
+
+static inline void
+__attribute__ ((always_inline))
+__lll_cond_lock (int *futex, int private)
+{
+ int val = atomic_compare_and_exchange_val_24_acq (futex, 2, 0);
+
+ if (__builtin_expect (val != 0, 0))
+ __lll_lock_wait (futex, private);
+}
+#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
+
+#define lll_robust_cond_lock(futex, id, private) \
+ __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS, private)
+
+
+extern int __lll_timedlock_wait (int *futex, const struct timespec *,
+ int private) attribute_hidden;
+extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
+ int private) attribute_hidden;
+
+static inline int
+__attribute__ ((always_inline))
+__lll_timedlock (int *futex, const struct timespec *abstime, int private)
+{
+ int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0);
+ int result = 0;
+
+ if (__builtin_expect (val != 0, 0))
+ result = __lll_timedlock_wait (futex, abstime, private);
+ return result;
+}
+#define lll_timedlock(futex, abstime, private) \
+ __lll_timedlock (&(futex), abstime, private)
+
+static inline int
+__attribute__ ((always_inline))
+__lll_robust_timedlock (int *futex, const struct timespec *abstime,
+ int id, int private)
+{
+ int result = 0;
+ if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+ result = __lll_robust_timedlock_wait (futex, abstime, private);
+ return result;
+}
+#define lll_robust_timedlock(futex, abstime, id, private) \
+ __lll_robust_timedlock (&(futex), abstime, id, private)
+
+#define lll_unlock(lock, private) \
+ ((void) ({ \
+ int *__futex = &(lock); \
+ int __val = atomic_exchange_24_rel (__futex, 0); \
+ if (__builtin_expect (__val > 1, 0)) \
+ lll_futex_wake (__futex, 1, private); \
+ }))
+
+#define lll_robust_unlock(lock, private) \
+ ((void) ({ \
+ int *__futex = &(lock); \
+ int __val = atomic_exchange_rel (__futex, 0); \
+ if (__builtin_expect (__val & FUTEX_WAITERS, 0)) \
+ lll_futex_wake (__futex, 1, private); \
+ }))
+
+#define lll_islocked(futex) \
+ (futex != 0)
+
+/* Initializers for lock. */
+#define LLL_LOCK_INITIALIZER (0)
+#define LLL_LOCK_INITIALIZER_LOCKED (1)
+
+/* The kernel notifies a process with uses CLONE_CLEARTID via futex
+ wakeup when the clone terminates. The memory location contains the
+ thread ID while the clone is running and is reset to zero
+ afterwards. */
+#define lll_wait_tid(tid) \
+ do \
+ { \
+ __typeof (tid) __tid; \
+ while ((__tid = (tid)) != 0) \
+ lll_futex_wait (&(tid), __tid, LLL_SHARED); \
+ } \
+ while (0)
+
+extern int __lll_timedwait_tid (int *, const struct timespec *)
+ attribute_hidden;
+
+#define lll_timedwait_tid(tid, abstime) \
+ ({ \
+ int __res = 0; \
+ if ((tid) != 0) \
+ __res = __lll_timedwait_tid (&(tid), (abstime)); \
+ __res; \
+ })
+
+#endif /* lowlevellock.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pt-vfork.S
new file mode 100644
index 000000000..e8705c54b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pt-vfork.S
@@ -0,0 +1,5 @@
+#if defined(__arch64__)
+#include "sparc64/pt-vfork.S"
+#else
+#include "sparc32/pt-vfork.S"
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_destroy.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_destroy.c
new file mode 100644
index 000000000..ca96379c9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_destroy.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+int
+pthread_barrier_destroy (
+ pthread_barrier_t *barrier)
+{
+ union sparc_pthread_barrier *ibarrier;
+ int result = EBUSY;
+
+ ibarrier = (union sparc_pthread_barrier *) barrier;
+
+ int private = ibarrier->s.pshared ? LLL_SHARED : LLL_PRIVATE;
+
+ lll_lock (ibarrier->b.lock, private);
+
+ if (__builtin_expect (ibarrier->b.left == ibarrier->b.init_count, 1))
+ /* The barrier is not used anymore. */
+ result = 0;
+ else
+ /* Still used, return with an error. */
+ lll_unlock (ibarrier->b.lock, private);
+
+ return result;
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_init.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_init.c
new file mode 100644
index 000000000..8182f1cef
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_init.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 2002, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+int
+pthread_barrier_init (
+ pthread_barrier_t *barrier,
+ const pthread_barrierattr_t *attr,
+ unsigned int count)
+{
+ union sparc_pthread_barrier *ibarrier;
+
+ if (__builtin_expect (count == 0, 0))
+ return EINVAL;
+
+ struct pthread_barrierattr *iattr = (struct pthread_barrierattr *) attr;
+ if (iattr != NULL)
+ {
+ if (iattr->pshared != PTHREAD_PROCESS_PRIVATE
+ && __builtin_expect (iattr->pshared != PTHREAD_PROCESS_SHARED, 0))
+ /* Invalid attribute. */
+ return EINVAL;
+ }
+
+ ibarrier = (union sparc_pthread_barrier *) barrier;
+
+ /* Initialize the individual fields. */
+ ibarrier->b.lock = LLL_LOCK_INITIALIZER;
+ ibarrier->b.left = count;
+ ibarrier->b.init_count = count;
+ ibarrier->b.curr_event = 0;
+ ibarrier->s.left_lock = 0;
+ ibarrier->s.pshared = (iattr && iattr->pshared == PTHREAD_PROCESS_SHARED);
+
+ return 0;
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_wait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_wait.c
new file mode 100644
index 000000000..73eaa695e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_barrier_wait.c
@@ -0,0 +1 @@
+#include "sparc32/pthread_barrier_wait.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c
new file mode 100644
index 000000000..24b74aca6
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c
@@ -0,0 +1,95 @@
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+
+unsigned long int __fork_generation attribute_hidden;
+
+
+static void
+clear_once_control (void *arg)
+{
+ pthread_once_t *once_control = (pthread_once_t *) arg;
+
+ *once_control = 0;
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+}
+
+
+int
+attribute_protected
+__pthread_once (once_control, init_routine)
+ pthread_once_t *once_control;
+ void (*init_routine) (void);
+{
+ while (1)
+ {
+ int oldval, val, newval;
+
+ val = *once_control;
+ do
+ {
+ /* Check if the initialized has already been done. */
+ if ((val & 2) != 0)
+ return 0;
+
+ oldval = val;
+ newval = (oldval & 3) | __fork_generation | 1;
+ val = atomic_compare_and_exchange_val_acq (once_control, newval,
+ oldval);
+ }
+ while (__builtin_expect (val != oldval, 0));
+
+ /* Check if another thread already runs the initializer. */
+ if ((oldval & 1) != 0)
+ {
+ /* Check whether the initializer execution was interrupted
+ by a fork. */
+ if (((oldval ^ newval) & -4) == 0)
+ {
+ /* Same generation, some other thread was faster. Wait. */
+ lll_futex_wait (once_control, newval, LLL_PRIVATE);
+ continue;
+ }
+ }
+
+ /* This thread is the first here. Do the initialization.
+ Register a cleanup handler so that in case the thread gets
+ interrupted the initialization can be restarted. */
+ pthread_cleanup_push (clear_once_control, once_control);
+
+ init_routine ();
+
+ pthread_cleanup_pop (0);
+
+
+ /* Add one to *once_control. */
+ atomic_increment (once_control);
+
+ /* Wake up all other threads. */
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+ break;
+ }
+
+ return 0;
+}
+weak_alias (__pthread_once, pthread_once)
+strong_alias (__pthread_once, __pthread_once_internal)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c
new file mode 100644
index 000000000..f694b5e93
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <string.h>
+#include <semaphore.h>
+#include <lowlevellock.h>
+#include "semaphoreP.h"
+#include <bits/kernel-features.h>
+
+
+int
+__new_sem_init (sem, pshared, value)
+ sem_t *sem;
+ int pshared;
+ unsigned int value;
+{
+ /* Parameter sanity check. */
+ if (__builtin_expect (value > SEM_VALUE_MAX, 0))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* Map to the internal type. */
+ struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
+
+ /* Use the values the user provided. */
+ memset (isem, '\0', sizeof (*isem));
+ isem->value = value;
+#ifdef __ASSUME_PRIVATE_FUTEX
+ isem->private = pshared ? 0 : FUTEX_PRIVATE_FLAG;
+#else
+ isem->private = pshared ? 0 : THREAD_GETMEM (THREAD_SELF,
+ header.private_futex);
+#endif
+
+ return 0;
+}
+weak_alias(__new_sem_init, sem_init)
+
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
new file mode 100644
index 000000000..a6142aafe
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S
@@ -0,0 +1,2 @@
+#define RESET_PID
+#include <libc/sysdeps/linux/sparc/clone.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S
new file mode 100644
index 000000000..fb01242b5
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pt-vfork.S
@@ -0,0 +1,45 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tcb-offsets.h>
+
+ .text
+ .globl __syscall_error
+ENTRY(__vfork)
+ ld [%g7 + PID], %o5
+ sub %g0, %o5, %o4
+ st %o4, [%g7 + PID]
+
+ LOADSYSCALL(vfork)
+ ta 0x10
+ bcc 2f
+ mov %o7, %g1
+ st %o5, [%g7 + PID]
+ call __syscall_error
+ mov %g1, %o7
+2: sub %o1, 1, %o1
+ andcc %o0, %o1, %o0
+ bne,a 1f
+ st %o5, [%g7 + PID]
+1: retl
+ nop
+END(__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c
new file mode 100644
index 000000000..302d1b371
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/pthread_barrier_wait.c
@@ -0,0 +1,94 @@
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <pthreadP.h>
+
+/* Wait on barrier. */
+int
+pthread_barrier_wait (
+ pthread_barrier_t *barrier)
+{
+ union sparc_pthread_barrier *ibarrier
+ = (union sparc_pthread_barrier *) barrier;
+ int result = 0;
+ int private = ibarrier->s.pshared ? LLL_SHARED : LLL_PRIVATE;
+
+ /* Make sure we are alone. */
+ lll_lock (ibarrier->b.lock, private);
+
+ /* One more arrival. */
+ --ibarrier->b.left;
+
+ /* Are these all? */
+ if (ibarrier->b.left == 0)
+ {
+ /* Yes. Increment the event counter to avoid invalid wake-ups and
+ tell the current waiters that it is their turn. */
+ ++ibarrier->b.curr_event;
+
+ /* Wake up everybody. */
+ lll_futex_wake (&ibarrier->b.curr_event, INT_MAX, private);
+
+ /* This is the thread which finished the serialization. */
+ result = PTHREAD_BARRIER_SERIAL_THREAD;
+ }
+ else
+ {
+ /* The number of the event we are waiting for. The barrier's event
+ number must be bumped before we continue. */
+ unsigned int event = ibarrier->b.curr_event;
+
+ /* Before suspending, make the barrier available to others. */
+ lll_unlock (ibarrier->b.lock, private);
+
+ /* Wait for the event counter of the barrier to change. */
+ do
+ lll_futex_wait (&ibarrier->b.curr_event, event, private);
+ while (event == ibarrier->b.curr_event);
+ }
+
+ /* Make sure the init_count is stored locally or in a register. */
+ unsigned int init_count = ibarrier->b.init_count;
+
+ /* If this was the last woken thread, unlock. */
+ if (__atomic_is_v9 || ibarrier->s.pshared == 0)
+ {
+ if (atomic_increment_val (&ibarrier->b.left) == init_count)
+ /* We are done. */
+ lll_unlock (ibarrier->b.lock, private);
+ }
+ else
+ {
+ unsigned int left;
+ /* Slightly more complicated. On pre-v9 CPUs, atomic_increment_val
+ is only atomic for threads within the same process, not for
+ multiple processes. */
+ __sparc32_atomic_do_lock24 (&ibarrier->s.left_lock);
+ left = ++ibarrier->b.left;
+ __sparc32_atomic_do_unlock24 (&ibarrier->s.left_lock);
+ if (left == init_count)
+ /* We are done. */
+ lll_unlock (ibarrier->b.lock, private);
+ }
+
+ return result;
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c
new file mode 100644
index 000000000..940728eeb
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c
@@ -0,0 +1,55 @@
+/* sem_post -- post to a POSIX semaphore. SPARC version.
+ Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+
+int
+__new_sem_post (sem_t *sem)
+{
+ struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
+ int nr;
+
+ if (__atomic_is_v9)
+ nr = atomic_increment_val (&isem->value);
+ else
+ {
+ __sparc32_atomic_do_lock24 (&isem->lock);
+ nr = ++(isem->value);
+ __sparc32_atomic_do_unlock24 (&isem->lock);
+ }
+ atomic_full_barrier ();
+ if (isem->nwaiters > 0)
+ {
+ int err = lll_futex_wake (&isem->value, 1,
+ isem->private ^ FUTEX_PRIVATE_FLAG);
+ if (__builtin_expect (err, 0) < 0)
+ {
+ __set_errno (-err);
+ return -1;
+ }
+ }
+ return 0;
+}
+weak_alias(__new_sem_post, sem_post)
+
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c
new file mode 100644
index 000000000..aa5bd80ed
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c
@@ -0,0 +1,148 @@
+/* sem_timedwait -- wait on a semaphore. SPARC version.
+ Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+
+#include <pthreadP.h>
+
+
+extern void __sem_wait_cleanup (void *arg) attribute_hidden;
+
+
+int
+sem_timedwait (sem_t *sem, const struct timespec *abstime)
+{
+ struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
+ int err;
+ int val;
+
+ if (__atomic_is_v9)
+ val = atomic_decrement_if_positive (&isem->value);
+ else
+ {
+ __sparc32_atomic_do_lock24 (&isem->lock);
+ val = isem->value;
+ if (val > 0)
+ isem->value = val - 1;
+ __sparc32_atomic_do_unlock24 (&isem->lock);
+ }
+
+ if (val > 0)
+ return 0;
+
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ if (__atomic_is_v9)
+ atomic_increment (&isem->nwaiters);
+ else
+ {
+ __sparc32_atomic_do_lock24 (&isem->lock);
+ isem->nwaiters++;
+ __sparc32_atomic_do_unlock24 (&isem->lock);
+ }
+
+ pthread_cleanup_push (__sem_wait_cleanup, isem);
+
+ while (1)
+ {
+ struct timeval tv;
+ struct timespec rt;
+ int sec, nsec;
+
+ /* Get the current time. */
+ __gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ sec = abstime->tv_sec - tv.tv_sec;
+ nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+ if (nsec < 0)
+ {
+ nsec += 1000000000;
+ --sec;
+ }
+
+ /* Already timed out? */
+ err = -ETIMEDOUT;
+ if (sec < 0)
+ {
+ __set_errno (ETIMEDOUT);
+ err = -1;
+ break;
+ }
+
+ /* Do wait. */
+ rt.tv_sec = sec;
+ rt.tv_nsec = nsec;
+
+ /* Enable asynchronous cancellation. Required by the standard. */
+ int oldtype = __pthread_enable_asynccancel ();
+
+ err = lll_futex_timed_wait (&isem->value, 0, &rt,
+ isem->private ^ FUTEX_PRIVATE_FLAG);
+
+ /* Disable asynchronous cancellation. */
+ __pthread_disable_asynccancel (oldtype);
+
+ if (err != 0 && err != -EWOULDBLOCK)
+ {
+ __set_errno (-err);
+ err = -1;
+ break;
+ }
+
+ if (__atomic_is_v9)
+ val = atomic_decrement_if_positive (&isem->value);
+ else
+ {
+ __sparc32_atomic_do_lock24 (&isem->lock);
+ val = isem->value;
+ if (val > 0)
+ isem->value = val - 1;
+ __sparc32_atomic_do_unlock24 (&isem->lock);
+ }
+
+ if (val > 0)
+ {
+ err = 0;
+ break;
+ }
+ }
+
+ pthread_cleanup_pop (0);
+
+ if (__atomic_is_v9)
+ atomic_decrement (&isem->nwaiters);
+ else
+ {
+ __sparc32_atomic_do_lock24 (&isem->lock);
+ isem->nwaiters--;
+ __sparc32_atomic_do_unlock24 (&isem->lock);
+ }
+
+ return err;
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c
new file mode 100644
index 000000000..d4e893805
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c
@@ -0,0 +1,54 @@
+/* sem_trywait -- wait on a semaphore. SPARC version.
+ Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+
+
+int
+__new_sem_trywait (sem_t *sem)
+{
+ struct sparc_old_sem *isem = (struct sparc_old_sem *) sem;
+ int val;
+
+ if (isem->value > 0)
+ {
+ if (__atomic_is_v9)
+ val = atomic_decrement_if_positive (&isem->value);
+ else
+ {
+ __sparc32_atomic_do_lock24 (&isem->lock);
+ val = isem->value;
+ if (val > 0)
+ isem->value = val - 1;
+ __sparc32_atomic_do_unlock24 (&isem->lock);
+ }
+ if (val > 0)
+ return 0;
+ }
+
+ __set_errno (EAGAIN);
+ return -1;
+}
+weak_alias(__new_sem_trywait, sem_trywait)
+
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c
new file mode 100644
index 000000000..cfe04a802
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c
@@ -0,0 +1,127 @@
+/* sem_wait -- wait on a semaphore. Generic futex-using version.
+ Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+
+#include <pthreadP.h>
+
+
+void
+attribute_hidden
+__sem_wait_cleanup (void *arg)
+{
+ struct sparc_new_sem *isem = (struct sparc_new_sem *) arg;
+
+ if (__atomic_is_v9)
+ atomic_decrement (&isem->nwaiters);
+ else
+ {
+ __sparc32_atomic_do_lock24 (&isem->lock);
+ isem->nwaiters--;
+ __sparc32_atomic_do_unlock24 (&isem->lock);
+ }
+}
+
+
+int
+__new_sem_wait (sem_t *sem)
+{
+ struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
+ int err;
+ int val;
+
+ if (__atomic_is_v9)
+ val = atomic_decrement_if_positive (&isem->value);
+ else
+ {
+ __sparc32_atomic_do_lock24 (&isem->lock);
+ val = isem->value;
+ if (val > 0)
+ isem->value = val - 1;
+ else
+ isem->nwaiters++;
+ __sparc32_atomic_do_unlock24 (&isem->lock);
+ }
+
+ if (val > 0)
+ return 0;
+
+ if (__atomic_is_v9)
+ atomic_increment (&isem->nwaiters);
+ else
+ /* Already done above while still holding isem->lock. */;
+
+ pthread_cleanup_push (__sem_wait_cleanup, isem);
+
+ while (1)
+ {
+ /* Enable asynchronous cancellation. Required by the standard. */
+ int oldtype = __pthread_enable_asynccancel ();
+
+ err = lll_futex_wait (&isem->value, 0,
+ isem->private ^ FUTEX_PRIVATE_FLAG);
+
+ /* Disable asynchronous cancellation. */
+ __pthread_disable_asynccancel (oldtype);
+
+ if (err != 0 && err != -EWOULDBLOCK)
+ {
+ __set_errno (-err);
+ err = -1;
+ break;
+ }
+
+ if (__atomic_is_v9)
+ val = atomic_decrement_if_positive (&isem->value);
+ else
+ {
+ __sparc32_atomic_do_lock24 (&isem->lock);
+ val = isem->value;
+ if (val > 0)
+ isem->value = val - 1;
+ __sparc32_atomic_do_unlock24 (&isem->lock);
+ }
+
+ if (val > 0)
+ {
+ err = 0;
+ break;
+ }
+ }
+
+ pthread_cleanup_pop (0);
+
+ if (__atomic_is_v9)
+ atomic_decrement (&isem->nwaiters);
+ else
+ {
+ __sparc32_atomic_do_lock24 (&isem->lock);
+ isem->nwaiters--;
+ __sparc32_atomic_do_unlock24 (&isem->lock);
+ }
+
+ return err;
+}
+weak_alias(__new_sem_wait, sem_wait)
+
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
new file mode 100644
index 000000000..1f55bd623
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
@@ -0,0 +1,112 @@
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <tls.h>
+#include <sysdep.h>
+#ifndef __ASSEMBLER__
+# include <pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .text; \
+ .globl __syscall_error; \
+ENTRY(name) \
+ ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;\
+ cmp %g1, 0; \
+ bne 1f; \
+.type __##syscall_name##_nocancel,@function; \
+.globl __##syscall_name##_nocancel; \
+__##syscall_name##_nocancel: \
+ mov SYS_ify(syscall_name), %g1; \
+ ta 0x10; \
+ bcc 8f; \
+ mov %o7, %g1; \
+ call __syscall_error; \
+ mov %g1, %o7; \
+8: jmpl %o7 + 8, %g0; \
+ nop; \
+.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;\
+1: save %sp, -96, %sp; \
+ cfi_def_cfa_register(%fp); \
+ cfi_window_save; \
+ cfi_register(%o7, %i7); \
+ CENABLE; \
+ nop; \
+ mov %o0, %l0; \
+ COPY_ARGS_##args \
+ mov SYS_ify(syscall_name), %g1; \
+ ta 0x10; \
+ bcc 1f; \
+ mov %o0, %l1; \
+ CDISABLE; \
+ mov %l0, %o0; \
+ call __syscall_error; \
+ mov %l1, %o0; \
+ b 2f; \
+ mov -1, %l1; \
+1: CDISABLE; \
+ mov %l0, %o0; \
+2: jmpl %i7 + 8, %g0; \
+ restore %g0, %l1, %o0;
+
+
+# ifdef IS_IN_libpthread
+# define CENABLE call __pthread_enable_asynccancel
+# define CDISABLE call __pthread_disable_asynccancel
+# elif !defined NOT_IN_libc
+# define CENABLE call __libc_enable_asynccancel
+# define CDISABLE call __libc_disable_asynccancel
+# elif defined IS_IN_librt
+# define CENABLE call __librt_enable_asynccancel
+# define CDISABLE call __librt_disable_asynccancel
+# else
+# error Unsupported library
+# endif
+
+#define COPY_ARGS_0 /* Nothing */
+#define COPY_ARGS_1 COPY_ARGS_0 mov %i0, %o0;
+#define COPY_ARGS_2 COPY_ARGS_1 mov %i1, %o1;
+#define COPY_ARGS_3 COPY_ARGS_2 mov %i2, %o2;
+#define COPY_ARGS_4 COPY_ARGS_3 mov %i3, %o3;
+#define COPY_ARGS_5 COPY_ARGS_4 mov %i4, %o4;
+#define COPY_ARGS_6 COPY_ARGS_5 mov %i5, %o5;
+
+# ifndef __ASSEMBLER__
+# define SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+# else
+# define SINGLE_THREAD_P ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1
+# endif
+
+#elif !defined __ASSEMBLER__
+
+# define SINGLE_THREAD_P (1)
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
new file mode 100644
index 000000000..8ee98684d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
@@ -0,0 +1,49 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tcb-offsets.h>
+
+ .text
+ .globl __syscall_error
+ENTRY(__vfork)
+ ld [%g7 + PID], %o5
+ cmp %o5, 0
+ bne 1f
+ sub %g0, %o5, %o4
+ sethi %hi(0x80000000), %o4
+1: st %o4, [%g7 + PID]
+
+ LOADSYSCALL(vfork)
+ ta 0x10
+ bcc 2f
+ mov %o7, %g1
+ st %o5, [%g7 + PID]
+ call __syscall_error
+ mov %g1, %o7
+2: sub %o1, 1, %o1
+ andcc %o0, %o1, %o0
+ bne,a 1f
+ st %o5, [%g7 + PID]
+1: retl
+ nop
+END(__vfork)
+
+libc_hidden_def (vfork)
+weak_alias (__vfork, vfork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
new file mode 100644
index 000000000..64e3bfc12
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S
@@ -0,0 +1,2 @@
+#define RESET_PID
+#include <libc/sysdeps/linux/sparc/sparcv9/clone.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S
new file mode 100644
index 000000000..8941043c3
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/pt-vfork.S
@@ -0,0 +1,45 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tcb-offsets.h>
+
+ .text
+ .globl __syscall_error
+ENTRY(__vfork)
+ ld [%g7 + PID], %o5
+ sub %g0, %o5, %o4
+ st %o4, [%g7 + PID]
+
+ LOADSYSCALL(vfork)
+ ta 0x6d
+ bcc,pt %xcc, 2f
+ mov %o7, %g1
+ st %o5, [%g7 + PID]
+ call __syscall_error
+ mov %g1, %o7
+2: sub %o1, 1, %o1
+ andcc %o0, %o1, %o0
+ bne,a,pt %icc, 1f
+ st %o5, [%g7 + PID]
+1: retl
+ nop
+END(__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
new file mode 100644
index 000000000..aec2d4a86
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
@@ -0,0 +1,110 @@
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .text; \
+ .globl __syscall_error; \
+ENTRY(name) \
+ ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;\
+ brnz,pn %g1, 1f; \
+.type __##syscall_name##_nocancel,@function; \
+.globl __##syscall_name##_nocancel; \
+__##syscall_name##_nocancel: \
+ mov SYS_ify(syscall_name), %g1; \
+ ta 0x6d; \
+ bcc,pt %xcc, 8f; \
+ mov %o7, %g1; \
+ call __syscall_error; \
+ mov %g1, %o7; \
+8: jmpl %o7 + 8, %g0; \
+ nop; \
+.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;\
+1: save %sp, -192, %sp; \
+ cfi_def_cfa_register(%fp); \
+ cfi_window_save; \
+ cfi_register(%o7, %i7); \
+ CENABLE; \
+ nop; \
+ mov %o0, %l0; \
+ COPY_ARGS_##args \
+ mov SYS_ify(syscall_name), %g1; \
+ ta 0x6d; \
+ bcc,pt %xcc, 1f; \
+ mov %o0, %l1; \
+ CDISABLE; \
+ mov %l0, %o0; \
+ call __syscall_error; \
+ mov %l1, %o0; \
+ ba,pt %xcc, 2f; \
+ mov -1, %l1; \
+1: CDISABLE; \
+ mov %l0, %o0; \
+2: jmpl %i7 + 8, %g0; \
+ restore %g0, %l1, %o0;
+
+# ifdef IS_IN_libpthread
+# define CENABLE call __pthread_enable_asynccancel
+# define CDISABLE call __pthread_disable_asynccancel
+# elif !defined NOT_IN_libc
+# define CENABLE call __libc_enable_asynccancel
+# define CDISABLE call __libc_disable_asynccancel
+# elif defined IS_IN_librt
+# define CENABLE call __librt_enable_asynccancel
+# define CDISABLE call __librt_disable_asynccancel
+# else
+# error Unsupported library
+# endif
+
+#define COPY_ARGS_0 /* Nothing */
+#define COPY_ARGS_1 COPY_ARGS_0 mov %i0, %o0;
+#define COPY_ARGS_2 COPY_ARGS_1 mov %i1, %o1;
+#define COPY_ARGS_3 COPY_ARGS_2 mov %i2, %o2;
+#define COPY_ARGS_4 COPY_ARGS_3 mov %i3, %o3;
+#define COPY_ARGS_5 COPY_ARGS_4 mov %i4, %o4;
+#define COPY_ARGS_6 COPY_ARGS_5 mov %i5, %o5;
+
+# ifndef __ASSEMBLER__
+# define SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+# else
+# define SINGLE_THREAD_P ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1
+# endif
+
+#elif !defined __ASSEMBLER__
+
+# define SINGLE_THREAD_P (1)
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_create.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_create.c
new file mode 100644
index 000000000..0a9c3372b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_create.c
@@ -0,0 +1 @@
+#include "../../x86_64/timer_create.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_delete.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_delete.c
new file mode 100644
index 000000000..f0d4fd21d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_delete.c
@@ -0,0 +1 @@
+#include "../../x86_64/timer_delete.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_getoverr.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_getoverr.c
new file mode 100644
index 000000000..82121a7a2
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_getoverr.c
@@ -0,0 +1 @@
+#include "../../x86_64/timer_getoverr.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_gettime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_gettime.c
new file mode 100644
index 000000000..313c05fea
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_gettime.c
@@ -0,0 +1 @@
+#include "../../x86_64/timer_gettime.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_settime.c
new file mode 100644
index 000000000..76f549cb4
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/timer_settime.c
@@ -0,0 +1 @@
+#include "../../x86_64/timer_settime.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
new file mode 100644
index 000000000..b4e89aceb
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
@@ -0,0 +1,49 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tcb-offsets.h>
+
+ .text
+ .globl __syscall_error
+ENTRY(__vfork)
+ ld [%g7 + PID], %o5
+ sethi %hi(0x80000000), %o3
+ cmp %o5, 0
+ sub %g0, %o5, %o4
+ move %icc, %o3, %o4
+ st %o4, [%g7 + PID]
+
+ LOADSYSCALL(vfork)
+ ta 0x6d
+ bcc,pt %xcc, 2f
+ mov %o7, %g1
+ st %o5, [%g7 + PID]
+ call __syscall_error
+ mov %g1, %o7
+2: sub %o1, 1, %o1
+ andcc %o0, %o1, %o0
+ bne,a,pt %icc, 1f
+ st %o5, [%g7 + PID]
+1: retl
+ nop
+END(__vfork)
+
+hidden_def (vfork)
+weak_alias (__vfork, vfork)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h
new file mode 100644
index 000000000..5be9beb92
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h
@@ -0,0 +1,5 @@
+#if defined(__arch64__)
+#include "sparc64/sysdep-cancel.h"
+#else
+#include "sparc32/sysdep-cancel.h"
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/vfork.S
new file mode 100644
index 000000000..160cd0b10
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/vfork.S
@@ -0,0 +1,5 @@
+#if defined(__arch64__)
+#include "sparc64/vfork.S"
+#else
+#include "sparc32/vfork.S"
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/structsem.sym b/libpthread/nptl/sysdeps/unix/sysv/linux/structsem.sym
new file mode 100644
index 000000000..0e2a15f2b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/structsem.sym
@@ -0,0 +1,12 @@
+#include <limits.h>
+#include <stddef.h>
+#include <sched.h>
+#include <bits/pthreadtypes.h>
+#include "internaltypes.h"
+
+--
+
+VALUE offsetof (struct new_sem, value)
+PRIVATE offsetof (struct new_sem, private)
+NWAITERS offsetof (struct new_sem, nwaiters)
+SEM_VALUE_MAX SEM_VALUE_MAX
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_create.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_create.c
new file mode 100644
index 000000000..a7da2a09a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_create.c
@@ -0,0 +1,243 @@
+/* Copyright (C) 2003,2004, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+#include <internaltypes.h>
+#include <pthreadP.h>
+#include "kernel-posix-timers.h"
+#include "kernel-posix-cpu-timers.h"
+
+
+#ifdef __NR_timer_create
+# ifndef __ASSUME_POSIX_TIMERS
+static int compat_timer_create (clockid_t clock_id, struct sigevent *evp,
+ timer_t *timerid);
+# define timer_create static compat_timer_create
+# include <nptl/sysdeps/pthread/timer_create.c>
+# undef timer_create
+
+/* Nonzero if the system calls are not available. */
+int __no_posix_timers attribute_hidden;
+# endif
+
+# ifdef timer_create_alias
+# define timer_create timer_create_alias
+# endif
+
+
+int
+timer_create (
+ clockid_t clock_id,
+ struct sigevent *evp,
+ timer_t *timerid)
+{
+# undef timer_create
+# ifndef __ASSUME_POSIX_TIMERS
+ if (__no_posix_timers >= 0)
+# endif
+ {
+ clockid_t syscall_clockid = (clock_id == CLOCK_PROCESS_CPUTIME_ID
+ ? MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED)
+ : clock_id == CLOCK_THREAD_CPUTIME_ID
+ ? MAKE_THREAD_CPUCLOCK (0, CPUCLOCK_SCHED)
+ : clock_id);
+
+ /* If the user wants notification via a thread we need to handle
+ this special. */
+ if (evp == NULL
+ || __builtin_expect (evp->sigev_notify != SIGEV_THREAD, 1))
+ {
+ struct sigevent local_evp;
+
+ /* We avoid allocating too much memory by basically
+ using struct timer as a derived class with the
+ first two elements being in the superclass. We only
+ need these two elements here. */
+ struct timer *newp = (struct timer *) malloc (offsetof (struct timer,
+ thrfunc));
+ if (newp == NULL)
+ /* No more memory. */
+ return -1;
+
+ if (evp == NULL)
+ {
+ /* The kernel has to pass up the timer ID which is a
+ userlevel object. Therefore we cannot leave it up to
+ the kernel to determine it. */
+ local_evp.sigev_notify = SIGEV_SIGNAL;
+ local_evp.sigev_signo = SIGALRM;
+ local_evp.sigev_value.sival_ptr = newp;
+
+ evp = &local_evp;
+ }
+
+ kernel_timer_t ktimerid;
+ int retval = INLINE_SYSCALL (timer_create, 3, syscall_clockid, evp,
+ &ktimerid);
+
+# ifndef __ASSUME_POSIX_TIMERS
+ if (retval != -1 || errno != ENOSYS)
+# endif
+ {
+# ifndef __ASSUME_POSIX_TIMERS
+ __no_posix_timers = 1;
+# endif
+
+ if (retval != -1)
+ {
+ newp->sigev_notify = (evp != NULL
+ ? evp->sigev_notify : SIGEV_SIGNAL);
+ newp->ktimerid = ktimerid;
+
+ *timerid = (timer_t) newp;
+ }
+ else
+ {
+ /* Cannot allocate the timer, fail. */
+ free (newp);
+ retval = -1;
+ }
+
+ return retval;
+ }
+
+ free (newp);
+
+# ifndef __ASSUME_POSIX_TIMERS
+ /* When we come here the syscall does not exist. Make sure we
+ do not try to use it again. */
+ __no_posix_timers = -1;
+# endif
+ }
+ else
+ {
+# ifndef __ASSUME_POSIX_TIMERS
+ /* Make sure we have the necessary kernel support. */
+ if (__no_posix_timers == 0)
+ {
+ INTERNAL_SYSCALL_DECL (err);
+ struct timespec ts;
+ int res;
+ res = INTERNAL_SYSCALL (clock_getres, err, 2,
+ CLOCK_REALTIME, &ts);
+ __no_posix_timers = (INTERNAL_SYSCALL_ERROR_P (res, err)
+ ? -1 : 1);
+ }
+
+ if (__no_posix_timers > 0)
+# endif
+ {
+ /* Create the helper thread. */
+ pthread_once (&__helper_once, __start_helper_thread);
+ if (__helper_tid == 0)
+ {
+ /* No resources to start the helper thread. */
+ __set_errno (EAGAIN);
+ return -1;
+ }
+
+ struct timer *newp;
+ newp = (struct timer *) malloc (sizeof (struct timer));
+ if (newp == NULL)
+ return -1;
+
+ /* Copy the thread parameters the user provided. */
+ newp->sival = evp->sigev_value;
+ newp->thrfunc = evp->sigev_notify_function;
+ newp->sigev_notify = SIGEV_THREAD;
+
+ /* We cannot simply copy the thread attributes since the
+ implementation might keep internal information for
+ each instance. */
+ (void) pthread_attr_init (&newp->attr);
+ if (evp->sigev_notify_attributes != NULL)
+ {
+ struct pthread_attr *nattr;
+ struct pthread_attr *oattr;
+
+ nattr = (struct pthread_attr *) &newp->attr;
+ oattr = (struct pthread_attr *) evp->sigev_notify_attributes;
+
+ nattr->schedparam = oattr->schedparam;
+ nattr->schedpolicy = oattr->schedpolicy;
+ nattr->flags = oattr->flags;
+ nattr->guardsize = oattr->guardsize;
+ nattr->stackaddr = oattr->stackaddr;
+ nattr->stacksize = oattr->stacksize;
+ }
+
+ /* In any case set the detach flag. */
+ (void) pthread_attr_setdetachstate (&newp->attr,
+ PTHREAD_CREATE_DETACHED);
+
+ /* Create the event structure for the kernel timer. */
+ struct sigevent sev =
+ { .sigev_value.sival_ptr = newp,
+ .sigev_signo = SIGTIMER,
+ .sigev_notify = SIGEV_SIGNAL | SIGEV_THREAD_ID,
+ ._sigev_un = { ._pad = { [0] = __helper_tid } } };
+
+ /* Create the timer. */
+ INTERNAL_SYSCALL_DECL (err);
+ int res;
+ res = INTERNAL_SYSCALL (timer_create, err, 3,
+ syscall_clockid, &sev, &newp->ktimerid);
+ if (! INTERNAL_SYSCALL_ERROR_P (res, err))
+ {
+ /* Add to the queue of active timers with thread
+ delivery. */
+ pthread_mutex_lock (&__active_timer_sigev_thread_lock);
+ newp->next = __active_timer_sigev_thread;
+ __active_timer_sigev_thread = newp;
+ pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
+
+ *timerid = (timer_t) newp;
+ return 0;
+ }
+
+ /* Free the resources. */
+ free (newp);
+
+ __set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
+
+ return -1;
+ }
+ }
+ }
+
+# ifndef __ASSUME_POSIX_TIMERS
+ /* Compatibility code. */
+ return compat_timer_create (clock_id, evp, timerid);
+# endif
+}
+#else
+# ifdef timer_create_alias
+# define timer_create timer_create_alias
+# endif
+/* The new system calls are not available. Use the userlevel
+ implementation. */
+# include <nptl/sysdeps/pthread/timer_create.c>
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_delete.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_delete.c
new file mode 100644
index 000000000..5ad40b99a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_delete.c
@@ -0,0 +1,115 @@
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+#include "kernel-posix-timers.h"
+
+
+#ifdef __NR_timer_delete
+# ifndef __ASSUME_POSIX_TIMERS
+static int compat_timer_delete (timer_t timerid);
+# define timer_delete static compat_timer_delete
+# include <nptl/sysdeps/pthread/timer_delete.c>
+# undef timer_delete
+# endif
+
+# ifdef timer_delete_alias
+# define timer_delete timer_delete_alias
+# endif
+
+
+int
+timer_delete (
+ timer_t timerid)
+{
+# undef timer_delete
+# ifndef __ASSUME_POSIX_TIMERS
+ if (__no_posix_timers >= 0)
+# endif
+ {
+ struct timer *kt = (struct timer *) timerid;
+
+ /* Delete the kernel timer object. */
+ int res = INLINE_SYSCALL (timer_delete, 1, kt->ktimerid);
+
+ if (res == 0)
+ {
+ if (kt->sigev_notify == SIGEV_THREAD)
+ {
+ /* Remove the timer from the list. */
+ pthread_mutex_lock (&__active_timer_sigev_thread_lock);
+ if (__active_timer_sigev_thread == kt)
+ __active_timer_sigev_thread = kt->next;
+ else
+ {
+ struct timer *prevp = __active_timer_sigev_thread;
+ while (prevp->next != NULL)
+ if (prevp->next == kt)
+ {
+ prevp->next = kt->next;
+ break;
+ }
+ else
+ prevp = prevp->next;
+ }
+ pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
+ }
+
+# ifndef __ASSUME_POSIX_TIMERS
+ /* We know the syscall support is available. */
+ __no_posix_timers = 1;
+# endif
+
+ /* Free the memory. */
+ (void) free (kt);
+
+ return 0;
+ }
+
+ /* The kernel timer is not known or something else bad happened.
+ Return the error. */
+# ifndef __ASSUME_POSIX_TIMERS
+ if (errno != ENOSYS)
+ {
+ __no_posix_timers = 1;
+# endif
+ return -1;
+# ifndef __ASSUME_POSIX_TIMERS
+ }
+
+ __no_posix_timers = -1;
+# endif
+ }
+
+# ifndef __ASSUME_POSIX_TIMERS
+ return compat_timer_delete (timerid);
+# endif
+}
+#else
+# ifdef timer_delete_alias
+# define timer_delete timer_delete_alias
+# endif
+/* The new system calls are not available. Use the userlevel
+ implementation. */
+# include <nptl/sysdeps/pthread/timer_delete.c>
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_getoverr.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_getoverr.c
new file mode 100644
index 000000000..62a558aef
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_getoverr.c
@@ -0,0 +1,81 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <time.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+#include "kernel-posix-timers.h"
+
+
+#ifdef __NR_timer_getoverrun
+# ifndef __ASSUME_POSIX_TIMERS
+static int compat_timer_getoverrun (timer_t timerid);
+# define timer_getoverrun static compat_timer_getoverrun
+# include <nptl/sysdeps/pthread/timer_getoverr.c>
+# undef timer_getoverrun
+# endif
+
+# ifdef timer_getoverrun_alias
+# define timer_getoverrun timer_getoverrun_alias
+# endif
+
+
+int
+timer_getoverrun (
+ timer_t timerid)
+{
+# undef timer_getoverrun
+# ifndef __ASSUME_POSIX_TIMERS
+ if (__no_posix_timers >= 0)
+# endif
+ {
+ struct timer *kt = (struct timer *) timerid;
+
+ /* Get the information from the kernel. */
+ int res = INLINE_SYSCALL (timer_getoverrun, 1, kt->ktimerid);
+
+# ifndef __ASSUME_POSIX_TIMERS
+ if (res != -1 || errno != ENOSYS)
+ {
+ /* We know the syscall support is available. */
+ __no_posix_timers = 1;
+# endif
+ return res;
+# ifndef __ASSUME_POSIX_TIMERS
+ }
+# endif
+
+# ifndef __ASSUME_POSIX_TIMERS
+ __no_posix_timers = -1;
+# endif
+ }
+
+# ifndef __ASSUME_POSIX_TIMERS
+ return compat_timer_getoverrun (timerid);
+# endif
+}
+#else
+# ifdef timer_getoverrun_alias
+# define timer_getoverrun timer_getoverrun_alias
+# endif
+/* The new system calls are not available. Use the userlevel
+ implementation. */
+# include <nptl/sysdeps/pthread/timer_getoverr.c>
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c
new file mode 100644
index 000000000..31401b19b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c
@@ -0,0 +1,83 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+#include "kernel-posix-timers.h"
+
+
+#ifdef __NR_timer_gettime
+# ifndef __ASSUME_POSIX_TIMERS
+static int compat_timer_gettime (timer_t timerid, struct itimerspec *value);
+# define timer_gettime static compat_timer_gettime
+# include <nptl/sysdeps/pthread/timer_gettime.c>
+# undef timer_gettime
+# endif
+
+# ifdef timer_gettime_alias
+# define timer_gettime timer_gettime_alias
+# endif
+
+
+int
+timer_gettime (
+ timer_t timerid,
+ struct itimerspec *value)
+{
+# undef timer_gettime
+# ifndef __ASSUME_POSIX_TIMERS
+ if (__no_posix_timers >= 0)
+# endif
+ {
+ struct timer *kt = (struct timer *) timerid;
+
+ /* Delete the kernel timer object. */
+ int res = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, value);
+
+# ifndef __ASSUME_POSIX_TIMERS
+ if (res != -1 || errno != ENOSYS)
+ {
+ /* We know the syscall support is available. */
+ __no_posix_timers = 1;
+# endif
+ return res;
+# ifndef __ASSUME_POSIX_TIMERS
+ }
+# endif
+
+# ifndef __ASSUME_POSIX_TIMERS
+ __no_posix_timers = -1;
+# endif
+ }
+
+# ifndef __ASSUME_POSIX_TIMERS
+ return compat_timer_gettime (timerid, value);
+# endif
+}
+#else
+# ifdef timer_gettime_alias
+# define timer_gettime timer_gettime_alias
+# endif
+/* The new system calls are not available. Use the userlevel
+ implementation. */
+# include <nptl/sysdeps/pthread/timer_gettime.c>
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_routines.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_routines.c
new file mode 100644
index 000000000..2681961bf
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_routines.c
@@ -0,0 +1,204 @@
+/* Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+#include <pthreadP.h>
+#include "kernel-posix-timers.h"
+
+
+/* List of active SIGEV_THREAD timers. */
+struct timer *__active_timer_sigev_thread;
+/* Lock for the __active_timer_sigev_thread. */
+pthread_mutex_t __active_timer_sigev_thread_lock = PTHREAD_MUTEX_INITIALIZER;
+
+
+struct thread_start_data
+{
+ void (*thrfunc) (sigval_t);
+ sigval_t sival;
+};
+
+
+#ifdef __NR_timer_create
+/* Helper thread to call the user-provided function. */
+static void *
+timer_sigev_thread (void *arg)
+{
+ /* The parent thread has all signals blocked. This is a bit
+ surprising for user code, although valid. We unblock all
+ signals. */
+ sigset_t ss;
+ sigemptyset (&ss);
+ INTERNAL_SYSCALL_DECL (err);
+ INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, NULL, _NSIG / 8);
+
+ struct thread_start_data *td = (struct thread_start_data *) arg;
+
+ void (*thrfunc) (sigval_t) = td->thrfunc;
+ sigval_t sival = td->sival;
+
+ /* The TD object was allocated in timer_helper_thread. */
+ free (td);
+
+ /* Call the user-provided function. */
+ thrfunc (sival);
+
+ return NULL;
+}
+
+
+/* Helper function to support starting threads for SIGEV_THREAD. */
+static void *
+timer_helper_thread (void *arg)
+{
+ /* Wait for the SIGTIMER signal, allowing the setXid signal, and
+ none else. */
+ sigset_t ss;
+ sigemptyset (&ss);
+ __sigaddset (&ss, SIGTIMER);
+
+ /* Endless loop of waiting for signals. The loop is only ended when
+ the thread is canceled. */
+ while (1)
+ {
+ siginfo_t si;
+
+ /* sigwaitinfo cannot be used here, since it deletes
+ SIGCANCEL == SIGTIMER from the set. */
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ int result = INLINE_SYSCALL (rt_sigtimedwait, 4, &ss, &si, NULL,
+ _NSIG / 8);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ if (result > 0)
+ {
+ if (si.si_code == SI_TIMER)
+ {
+ struct timer *tk = (struct timer *) si.si_ptr;
+
+ /* Check the timer is still used and will not go away
+ while we are reading the values here. */
+ pthread_mutex_lock (&__active_timer_sigev_thread_lock);
+
+ struct timer *runp = __active_timer_sigev_thread;
+ while (runp != NULL)
+ if (runp == tk)
+ break;
+ else
+ runp = runp->next;
+
+ if (runp != NULL)
+ {
+ struct thread_start_data *td = malloc (sizeof (*td));
+
+ /* There is not much we can do if the allocation fails. */
+ if (td != NULL)
+ {
+ /* This is the signal we are waiting for. */
+ td->thrfunc = tk->thrfunc;
+ td->sival = tk->sival;
+
+ pthread_t th;
+ (void) pthread_create (&th, &tk->attr,
+ timer_sigev_thread, td);
+ }
+ }
+
+ pthread_mutex_unlock (&__active_timer_sigev_thread_lock);
+ }
+ else if (si.si_code == SI_TKILL)
+ /* The thread is canceled. */
+ pthread_exit (NULL);
+ }
+ }
+}
+
+
+/* Control variable for helper thread creation. */
+pthread_once_t __helper_once attribute_hidden;
+
+
+/* TID of the helper thread. */
+pid_t __helper_tid attribute_hidden;
+
+
+/* Reset variables so that after a fork a new helper thread gets started. */
+static void
+reset_helper_control (void)
+{
+ __helper_once = PTHREAD_ONCE_INIT;
+ __helper_tid = 0;
+}
+
+
+void
+attribute_hidden
+__start_helper_thread (void)
+{
+ /* The helper thread needs only very little resources
+ and should go away automatically when canceled. */
+ pthread_attr_t attr;
+ (void) pthread_attr_init (&attr);
+ (void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+
+ /* Block all signals in the helper thread but SIGSETXID. To do this
+ thoroughly we temporarily have to block all signals here. The
+ helper can lose wakeups if SIGCANCEL is not blocked throughout,
+ but sigfillset omits it SIGSETXID. So, we add SIGCANCEL back
+ explicitly here. */
+ sigset_t ss;
+ sigset_t oss;
+ sigfillset (&ss);
+ __sigaddset (&ss, SIGCANCEL);
+ INTERNAL_SYSCALL_DECL (err);
+ INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, &oss, _NSIG / 8);
+
+ /* Create the helper thread for this timer. */
+ pthread_t th;
+ int res = pthread_create (&th, &attr, timer_helper_thread, NULL);
+ if (res == 0)
+ /* We managed to start the helper thread. */
+ __helper_tid = ((struct pthread *) th)->tid;
+
+ /* Restore the signal mask. */
+ INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &oss, NULL,
+ _NSIG / 8);
+
+ /* No need for the attribute anymore. */
+ (void) pthread_attr_destroy (&attr);
+
+ /* We have to make sure that after fork()ing a new helper thread can
+ be created. */
+ pthread_atfork (NULL, NULL, reset_helper_control);
+}
+#endif
+
+#ifndef __ASSUME_POSIX_TIMERS
+# include <nptl/sysdeps/pthread/timer_routines.c>
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
new file mode 100644
index 000000000..8c6ad91fa
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
@@ -0,0 +1,88 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+#include "kernel-posix-timers.h"
+
+
+#ifdef __NR_timer_settime
+# ifndef __ASSUME_POSIX_TIMERS
+static int compat_timer_settime (timer_t timerid, int flags,
+ const struct itimerspec *value,
+ struct itimerspec *ovalue);
+# define timer_settime static compat_timer_settime
+# include <nptl/sysdeps/pthread/timer_settime.c>
+# undef timer_settime
+# endif
+
+# ifdef timer_settime_alias
+# define timer_settime timer_settime_alias
+# endif
+
+
+int
+timer_settime (
+ timer_t timerid,
+ int flags,
+ const struct itimerspec *value,
+ struct itimerspec *ovalue)
+{
+# undef timer_settime
+# ifndef __ASSUME_POSIX_TIMERS
+ if (__no_posix_timers >= 0)
+# endif
+ {
+ struct timer *kt = (struct timer *) timerid;
+
+ /* Delete the kernel timer object. */
+ int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags,
+ value, ovalue);
+
+# ifndef __ASSUME_POSIX_TIMERS
+ if (res != -1 || errno != ENOSYS)
+ {
+ /* We know the syscall support is available. */
+ __no_posix_timers = 1;
+# endif
+ return res;
+# ifndef __ASSUME_POSIX_TIMERS
+ }
+# endif
+
+# ifndef __ASSUME_POSIX_TIMERS
+ __no_posix_timers = -1;
+# endif
+ }
+
+# ifndef __ASSUME_POSIX_TIMERS
+ return compat_timer_settime (timerid, flags, value, ovalue);
+# endif
+}
+#else
+# ifdef timer_settime_alias
+# define timer_settime timer_settime_alias
+# endif
+/* The new system calls are not available. Use the userlevel
+ implementation. */
+# include <nptl/sysdeps/pthread/timer_settime.c>
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
new file mode 100644
index 000000000..7eb095fd3
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
@@ -0,0 +1,123 @@
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <fork.h>
+#include <atomic.h>
+#include <tls.h>
+
+
+void
+__unregister_atfork (
+ void *dso_handle)
+{
+ /* Check whether there is any entry in the list which we have to
+ remove. It is likely that this is not the case so don't bother
+ getting the lock.
+
+ We do not worry about other threads adding entries for this DSO
+ right this moment. If this happens this is a race and we can do
+ whatever we please. The program will crash anyway seen. */
+ struct fork_handler *runp = __fork_handlers;
+ struct fork_handler *lastp = NULL;
+
+ while (runp != NULL)
+ if (runp->dso_handle == dso_handle)
+ break;
+ else
+ {
+ lastp = runp;
+ runp = runp->next;
+ }
+
+ if (runp == NULL)
+ /* Nothing to do. */
+ return;
+
+ /* Get the lock to not conflict with additions or deletions. Note
+ that there couldn't have been another thread deleting something.
+ The __unregister_atfork function is only called from the
+ dlclose() code which itself serializes the operations. */
+ lll_lock (__fork_lock, LLL_PRIVATE);
+
+ /* We have to create a new list with all the entries we don't remove. */
+ struct deleted_handler
+ {
+ struct fork_handler *handler;
+ struct deleted_handler *next;
+ } *deleted = NULL;
+
+ /* Remove the entries for the DSO which is unloaded from the list.
+ It's a single linked list so readers are. */
+ do
+ {
+ again:
+ if (runp->dso_handle == dso_handle)
+ {
+ if (lastp == NULL)
+ {
+ /* We have to use an atomic operation here because
+ __linkin_atfork also uses one. */
+ if (catomic_compare_and_exchange_bool_acq (&__fork_handlers,
+ runp->next, runp)
+ != 0)
+ {
+ runp = __fork_handlers;
+ goto again;
+ }
+ }
+ else
+ lastp->next = runp->next;
+
+ /* We cannot overwrite the ->next element now. Put the deleted
+ entries in a separate list. */
+ struct deleted_handler *newp = alloca (sizeof (*newp));
+ newp->handler = runp;
+ newp->next = deleted;
+ deleted = newp;
+ }
+ else
+ lastp = runp;
+
+ runp = runp->next;
+ }
+ while (runp != NULL);
+
+ /* Release the lock. */
+ lll_unlock (__fork_lock, LLL_PRIVATE);
+
+ /* Walk the list of all entries which have to be deleted. */
+ while (deleted != NULL)
+ {
+ /* We need to be informed by possible current users. */
+ deleted->handler->need_signal = 1;
+ /* Make sure this gets written out first. */
+ atomic_write_barrier ();
+
+ /* Decrement the reference counter. If it does not reach zero
+ wait for the last user. */
+ atomic_decrement (&deleted->handler->refcntr);
+ unsigned int val;
+ while ((val = deleted->handler->refcntr) != 0)
+ lll_futex_wait (&deleted->handler->refcntr, val, LLL_PRIVATE);
+
+ deleted = deleted->next;
+ }
+}
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/unwindbuf.sym b/libpthread/nptl/sysdeps/unix/sysv/linux/unwindbuf.sym
new file mode 100644
index 000000000..8044b4078
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/unwindbuf.sym
@@ -0,0 +1,7 @@
+#include <pthread.h>
+#include <stddef.h>
+
+--
+
+UNWINDBUFSIZE sizeof (__pthread_unwind_buf_t)
+UWJMPBUF offsetof (__pthread_unwind_buf_t, __cancel_jmp_buf)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/waitpid.S b/libpthread/nptl/sysdeps/unix/sysv/linux/waitpid.S
new file mode 100644
index 000000000..f55d34629
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/waitpid.S
@@ -0,0 +1,19 @@
+#include <sysdep-cancel.h>
+
+/*
+extern pid_t __waitpid_nocancel (pid_t, int *, int) attribute_hidden;
+*/
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+
+PSEUDO (__waitpid, waitpid, 3)
+ret
+PSEUDO_END(__waitpid)
+
+libc_hidden_def (__waitpid)
+weak_alias (__waitpid, waitpid)
+libc_hidden_weak (waitpid)
+weak_alias (__waitpid, __libc_waitpid)
+libc_hidden_weak (__libc_waitpid)
+
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/write.S b/libpthread/nptl/sysdeps/unix/sysv/linux/write.S
new file mode 100644
index 000000000..43de3320d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/write.S
@@ -0,0 +1,19 @@
+#include <sysdep-cancel.h>
+
+/*
+extern int __write_nocancel (int, const void *, size_t) attribute_hidden;
+*/
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+PSEUDO (__libc_write, write, 3)
+ret
+PSEUDO_END(__libc_write)
+
+libc_hidden_def (__write_nocancel)
+libc_hidden_def (__libc_write)
+weak_alias (__libc_write, __write)
+libc_hidden_weak (__write)
+weak_alias (__libc_write, write)
+libc_hidden_weak (write)
+
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
new file mode 100644
index 000000000..43a6fad84
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -0,0 +1,13 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../../../../../
+top_builddir=../../../../../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.arch
+include $(top_srcdir)Makerules
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile.arch
new file mode 100644
index 000000000..53a87728f
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile.arch
@@ -0,0 +1,78 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+LINUX_ARCH_DIR:=$(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/x86_64
+LINUX_ARCH_OUT:=$(top_builddir)libpthread/nptl/sysdeps/unix/sysv/linux/x86_64
+
+
+libpthread_SSRC = pt-vfork.S clone.S pthread_once.S
+libpthread_CSRC = pthread_spin_init.c pt-__syscall_error.c
+
+libc_a_CSRC = fork.c
+libc_a_SSRC = clone.S vfork.S
+
+libpthread_SSRC += lowlevellock.S pthread_barrier_wait.S pthread_cond_signal.S pthread_cond_broadcast.S \
+ sem_post.S sem_timedwait.S lowlevelrobustlock.S \
+ sem_trywait.S sem_wait.S pthread_rwlock_rdlock.S pthread_rwlock_wrlock.S \
+ pthread_rwlock_timedrdlock.S pthread_rwlock_timedwrlock.S pthread_rwlock_unlock.S \
+ pthread_spin_unlock.S
+# pthread_cond_timedwait.S pthread_cond_wait.S
+libc_a_SSRC += libc-lowlevellock.S
+
+
+CFLAGS-OMIT-fork.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-pt-__syscall_error.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
+ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y)
+CFLAGS-fork.c = -D__USE_STDIO_FUTEXES__
+endif
+
+ASFLAGS-pt-vfork.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-lowlevellock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-pthread_once.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+
+
+ASFLAGS-clone.S = -D_LIBC_REENTRANT
+ASFLAGS-vfork.S = -D_LIBC_REENTRANT
+ASFLAGS-libc-lowlevellock.S = -D_LIBC_REENTRANT
+
+ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y)
+#Needed to use the correct SYSCALL_ERROR_HANDLER
+ASFLAGS-clone.S += -DUSE___THREAD
+ASFLAGS-vfork.S += -DUSE___THREAD
+ASFLAGS-sem_wait.S += -DUSE___THREAD
+ASFLAGS-sem_trywait.S += -DUSE___THREAD
+ASFLAGS-sem_timedwait.S += -DUSE___THREAD
+ASFLAGS-sem_post.S += -DUSE___THREAD
+endif
+
+CFLAGS += $(SSP_ALL_CFLAGS)
+#CFLAGS:=$(CFLAGS:-O1=-O2)
+
+LINUX_ARCH_OBJ:=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libpthread_SSRC))
+LINUX_ARCH_OBJ+=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libpthread_CSRC))
+
+ifeq ($(DOPIC),y)
+libpthread-a-y += $(LINUX_ARCH_OBJ:.o=.os)
+else
+libpthread-a-y += $(LINUX_ARCH_OBJ)
+endif
+libpthread-so-y += $(LINUX_ARCH_OBJ:.o=.oS)
+
+libpthread-nomulti-y+=$(LINUX_ARCH_OBJS)
+
+LIBC_LINUX_ARCH_OBJ:=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libc_a_CSRC))
+LIBC_LINUX_ARCH_OBJ+=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libc_a_SSRC))
+
+libc-static-y+=$(LIBC_LINUX_ARCH_OBJ)
+libc-shared-y+=$(LIBC_LINUX_ARCH_OBJ:.o=.oS)
+
+libc-nomulti-y+=$(LIBC_LINUX_ARCH_OBJ)
+
+objclean-y+=nptl_linux_arch_clean
+
+nptl_linux_arch_clean:
+ $(do_rm) $(addprefix $(LINUX_ARCH_OUT)/*., o os oS)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
new file mode 100644
index 000000000..7a09c8119
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
@@ -0,0 +1,225 @@
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H 1
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+# define __SIZEOF_PTHREAD_ATTR_T 56
+# define __SIZEOF_PTHREAD_MUTEX_T 40
+# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+# define __SIZEOF_PTHREAD_COND_T 48
+# define __SIZEOF_PTHREAD_CONDATTR_T 4
+# define __SIZEOF_PTHREAD_RWLOCK_T 56
+# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+# define __SIZEOF_PTHREAD_BARRIER_T 32
+# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+#else
+# define __SIZEOF_PTHREAD_ATTR_T 36
+# define __SIZEOF_PTHREAD_MUTEX_T 24
+# define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+# define __SIZEOF_PTHREAD_COND_T 48
+# define __SIZEOF_PTHREAD_CONDATTR_T 4
+# define __SIZEOF_PTHREAD_RWLOCK_T 32
+# define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+# define __SIZEOF_PTHREAD_BARRIER_T 20
+# define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+#endif
+
+
+/* Thread identifiers. The structure of the attribute type is not
+ exposed on purpose. */
+typedef unsigned long int pthread_t;
+
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_ATTR_T];
+ long int __align;
+} pthread_attr_t;
+
+
+#if __WORDSIZE == 64
+typedef struct __pthread_internal_list
+{
+ struct __pthread_internal_list *__prev;
+ struct __pthread_internal_list *__next;
+} __pthread_list_t;
+#else
+typedef struct __pthread_internal_slist
+{
+ struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+#endif
+
+
+/* Data structures for mutex handling. The structure of the attribute
+ type is not exposed on purpose. */
+typedef union
+{
+ struct __pthread_mutex_s
+ {
+ int __lock;
+ unsigned int __count;
+ int __owner;
+#if __WORDSIZE == 64
+ unsigned int __nusers;
+#endif
+ /* KIND must stay at this position in the structure to maintain
+ binary compatibility. */
+ int __kind;
+#if __WORDSIZE == 64
+ int __spins;
+ __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV 1
+#else
+ unsigned int __nusers;
+ __extension__ union
+ {
+ int __spins;
+ __pthread_slist_t __list;
+ };
+#endif
+ } __data;
+ char __size[__SIZEOF_PTHREAD_MUTEX_T];
+ long int __align;
+} pthread_mutex_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+ int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling. The structure of
+ the attribute type is not exposed on purpose. */
+typedef union
+{
+ struct
+ {
+ int __lock;
+ unsigned int __futex;
+ __extension__ unsigned long long int __total_seq;
+ __extension__ unsigned long long int __wakeup_seq;
+ __extension__ unsigned long long int __woken_seq;
+ void *__mutex;
+ unsigned int __nwaiters;
+ unsigned int __broadcast_seq;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_COND_T];
+ __extension__ long long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+ int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Data structure for read-write lock variable handling. The
+ structure of the attribute type is not exposed on purpose. */
+typedef union
+{
+# if __WORDSIZE == 64
+ struct
+ {
+ int __lock;
+ unsigned int __nr_readers;
+ unsigned int __readers_wakeup;
+ unsigned int __writer_wakeup;
+ unsigned int __nr_readers_queued;
+ unsigned int __nr_writers_queued;
+ int __writer;
+ int __shared;
+ unsigned long int __pad1;
+ unsigned long int __pad2;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned int __flags;
+ } __data;
+# else
+ struct
+ {
+ int __lock;
+ unsigned int __nr_readers;
+ unsigned int __readers_wakeup;
+ unsigned int __writer_wakeup;
+ unsigned int __nr_readers_queued;
+ unsigned int __nr_writers_queued;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned char __flags;
+ unsigned char __shared;
+ unsigned char __pad1;
+ unsigned char __pad2;
+ int __writer;
+ } __data;
+# endif
+ char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+ long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+ long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type. */
+typedef volatile int pthread_spinlock_t;
+
+
+/* POSIX barriers data type. The structure of the type is
+ deliberately not exposed. */
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIER_T];
+ long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+ int __align;
+} pthread_barrierattr_t;
+#endif
+
+
+#if __WORDSIZE == 32
+/* Extra attributes for the cleanup functions. */
+# define __cleanup_fct_attribute __attribute__ ((__regparm__ (1)))
+#endif
+
+#endif /* bits/pthreadtypes.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h
new file mode 100644
index 000000000..e973bc5bf
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/semaphore.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+#include <bits/wordsize.h>
+
+#if __WORDSIZE == 64
+# define __SIZEOF_SEM_T 32
+#else
+# define __SIZEOF_SEM_T 16
+#endif
+
+
+/* Value returned if `sem_open' failed. */
+#define SEM_FAILED ((sem_t *) 0)
+
+
+typedef union
+{
+ char __size[__SIZEOF_SEM_T];
+ long int __align;
+} sem_t;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S
new file mode 100644
index 000000000..680696200
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S
@@ -0,0 +1,116 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tcb-offsets.h>
+#include <kernel-features.h>
+#include "lowlevellock.h"
+
+#ifdef IS_IN_libpthread
+# ifdef SHARED
+# define __pthread_unwind __GI___pthread_unwind
+# endif
+#else
+# ifndef SHARED
+ .weak __pthread_unwind
+# endif
+#endif
+
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+ movl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
+#else
+# if FUTEX_WAIT == 0
+# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+ movl %fs:PRIVATE_FUTEX, reg
+# else
+# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+ movl %fs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAIT, reg
+# endif
+#endif
+
+/* It is crucial that the functions in this file don't modify registers
+ other than %rax and %r11. The syscall wrapper code depends on this
+ because it doesn't explicitly save the other registers which hold
+ relevant values. */
+ .text
+
+ .hidden __pthread_enable_asynccancel
+ENTRY(__pthread_enable_asynccancel)
+ movl %fs:CANCELHANDLING, %eax
+2: movl %eax, %r11d
+ orl $TCB_CANCELTYPE_BITMASK, %r11d
+ cmpl %eax, %r11d
+ je 1f
+
+ lock
+ cmpxchgl %r11d, %fs:CANCELHANDLING
+ jnz 2b
+
+ andl $(TCB_CANCELSTATE_BITMASK|TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK|TCB_EXITING_BITMASK|TCB_CANCEL_RESTMASK|TCB_TERMINATED_BITMASK), %r11d
+ cmpl $(TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK), %r11d
+ je 3f
+
+1: ret
+
+3: movq $TCB_PTHREAD_CANCELED, %fs:RESULT
+ lock
+ orl $TCB_EXITING_BITMASK, %fs:CANCELHANDLING
+ movq %fs:CLEANUP_JMP_BUF, %rdi
+#ifdef SHARED
+ call __pthread_unwind@PLT
+#else
+ call __pthread_unwind
+#endif
+ hlt
+END(__pthread_enable_asynccancel)
+
+
+ .hidden __pthread_disable_asynccancel
+ENTRY(__pthread_disable_asynccancel)
+ testl $TCB_CANCELTYPE_BITMASK, %edi
+ jnz 1f
+
+ movl %fs:CANCELHANDLING, %eax
+2: movl %eax, %r11d
+ andl $~TCB_CANCELTYPE_BITMASK, %r11d
+ lock
+ cmpxchgl %r11d, %fs:CANCELHANDLING
+ jnz 2b
+
+ movl %r11d, %eax
+3: andl $(TCB_CANCELING_BITMASK|TCB_CANCELED_BITMASK), %eax
+ cmpl $TCB_CANCELING_BITMASK, %eax
+ je 4f
+1: ret
+
+ /* Performance doesn't matter in this loop. We will
+ delay until the thread is canceled. And we will unlikely
+ enter the loop twice. */
+4: movq %fs:0, %rdi
+ movl $__NR_futex, %eax
+ xorq %r10, %r10
+ addq $CANCELHANDLING, %rdi
+ LOAD_PRIVATE_FUTEX_WAIT (%esi)
+ syscall
+ movl %fs:CANCELHANDLING, %eax
+ jmp 3b
+END(__pthread_disable_asynccancel)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S
new file mode 100644
index 000000000..efbaee3d1
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S
@@ -0,0 +1,3 @@
+#include <tcb-offsets.h>
+#define RESET_PID
+#include <libc/sysdeps/linux/x86_64/clone.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/compat-timer.h b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/compat-timer.h
new file mode 100644
index 000000000..02485daa5
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/compat-timer.h
@@ -0,0 +1,46 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <signal.h>
+#include <time.h>
+#include <sys/types.h>
+
+#define OLD_TIMER_MAX 256
+
+extern timer_t __compat_timer_list[OLD_TIMER_MAX] attribute_hidden;
+
+
+extern int __timer_create_new (clockid_t clock_id, struct sigevent *evp,
+ timer_t *timerid);
+extern int __timer_delete_new (timer_t timerid);
+extern int __timer_getoverrun_new (timer_t timerid);
+extern int __timer_gettime_new (timer_t timerid, struct itimerspec *value);
+extern int __timer_settime_new (timer_t timerid, int flags,
+ const struct itimerspec *value,
+ struct itimerspec *ovalue);
+
+
+extern int __timer_create_old (clockid_t clock_id, struct sigevent *evp,
+ int *timerid);
+extern int __timer_delete_old (int timerid);
+extern int __timer_getoverrun_old (int timerid);
+extern int __timer_gettime_old (int timerid, struct itimerspec *value);
+extern int __timer_settime_old (int timerid, int flags,
+ const struct itimerspec *value,
+ struct itimerspec *ovalue);
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/fork.c
new file mode 100644
index 000000000..c828e158d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/fork.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sched.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+
+
+#define ARCH_FORK() \
+ INLINE_SYSCALL (clone, 4, \
+ CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0, \
+ NULL, &THREAD_SELF->tid)
+
+#include "../fork.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S
new file mode 100644
index 000000000..110058850
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S
@@ -0,0 +1,22 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __pthread_enable_asynccancel __libc_enable_asynccancel
+#define __pthread_disable_asynccancel __libc_disable_asynccancel
+#include "cancellation.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
new file mode 100644
index 000000000..ce8ad27aa
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "lowlevellock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S
new file mode 100644
index 000000000..ce4192b5d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S
@@ -0,0 +1,22 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define __pthread_enable_asynccancel __librt_enable_asynccancel
+#define __pthread_disable_asynccancel __librt_disable_asynccancel
+#include "cancellation.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
new file mode 100644
index 000000000..f87532359
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
@@ -0,0 +1,457 @@
+/* Copyright (C) 2002-2006, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <lowlevellock.h>
+#include <tcb-offsets.h>
+
+ .text
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+ movl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
+# define LOAD_PRIVATE_FUTEX_WAKE(reg) \
+ movl $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
+# define LOAD_FUTEX_WAIT_ABS(reg) \
+ xorl $(FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME), reg
+# define LOAD_FUTEX_WAKE(reg) \
+ xorl $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg
+#else
+# if FUTEX_WAIT == 0
+# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+ movl %fs:PRIVATE_FUTEX, reg
+# else
+# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+ movl %fs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAIT, reg
+# endif
+# define LOAD_PRIVATE_FUTEX_WAKE(reg) \
+ movl %fs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAKE, reg
+# if FUTEX_WAIT == 0
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %fs:PRIVATE_FUTEX, reg
+# else
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %fs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAIT, reg
+# endif
+# define LOAD_FUTEX_WAIT_ABS(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %fs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME, reg
+# define LOAD_FUTEX_WAKE(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %fs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAKE, reg
+#endif
+
+
+/* For the calculation see asm/vsyscall.h. */
+#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
+
+
+ .globl __lll_lock_wait_private
+ .type __lll_lock_wait_private,@function
+ .hidden __lll_lock_wait_private
+ .align 16
+__lll_lock_wait_private:
+ cfi_startproc
+ pushq %r10
+ cfi_adjust_cfa_offset(8)
+ pushq %rdx
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%r10, -16)
+ cfi_offset(%rdx, -24)
+ xorq %r10, %r10 /* No timeout. */
+ movl $2, %edx
+ LOAD_PRIVATE_FUTEX_WAIT (%esi)
+
+ cmpl %edx, %eax /* NB: %edx == 2 */
+ jne 2f
+
+1: movl $SYS_futex, %eax
+ syscall
+
+2: movl %edx, %eax
+ xchgl %eax, (%rdi) /* NB: lock is implied */
+
+ testl %eax, %eax
+ jnz 1b
+
+ popq %rdx
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%rdx)
+ popq %r10
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r10)
+ retq
+ cfi_endproc
+ .size __lll_lock_wait_private,.-__lll_lock_wait_private
+
+#ifdef NOT_IN_libc
+ .globl __lll_lock_wait
+ .type __lll_lock_wait,@function
+ .hidden __lll_lock_wait
+ .align 16
+__lll_lock_wait:
+ cfi_startproc
+ pushq %r10
+ cfi_adjust_cfa_offset(8)
+ pushq %rdx
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%r10, -16)
+ cfi_offset(%rdx, -24)
+ xorq %r10, %r10 /* No timeout. */
+ movl $2, %edx
+ LOAD_FUTEX_WAIT (%esi)
+
+ cmpl %edx, %eax /* NB: %edx == 2 */
+ jne 2f
+
+1: movl $SYS_futex, %eax
+ syscall
+
+2: movl %edx, %eax
+ xchgl %eax, (%rdi) /* NB: lock is implied */
+
+ testl %eax, %eax
+ jnz 1b
+
+ popq %rdx
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%rdx)
+ popq %r10
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r10)
+ retq
+ cfi_endproc
+ .size __lll_lock_wait,.-__lll_lock_wait
+
+ /* %rdi: futex
+ %rsi: flags
+ %rdx: timeout
+ %eax: futex value
+ */
+ .globl __lll_timedlock_wait
+ .type __lll_timedlock_wait,@function
+ .hidden __lll_timedlock_wait
+ .align 16
+__lll_timedlock_wait:
+ cfi_startproc
+# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+# ifdef __PIC__
+ cmpl $0, __have_futex_clock_realtime(%rip)
+# else
+ cmpl $0, __have_futex_clock_realtime
+# endif
+ je .Lreltmo
+# endif
+
+ pushq %r9
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r9, 0)
+ movq %rdx, %r10
+ movl $0xffffffff, %r9d
+ LOAD_FUTEX_WAIT_ABS (%esi)
+
+ movl $2, %edx
+ cmpl %edx, %eax
+ jne 2f
+
+1: movl $SYS_futex, %eax
+ movl $2, %edx
+ syscall
+
+2: xchgl %edx, (%rdi) /* NB: lock is implied */
+
+ testl %edx, %edx
+ jz 3f
+
+ cmpl $-ETIMEDOUT, %eax
+ je 4f
+ cmpl $-EINVAL, %eax
+ jne 1b
+4: movl %eax, %edx
+ negl %edx
+
+3: movl %edx, %eax
+ popq %r9
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r9)
+ retq
+
+# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+.Lreltmo:
+ /* Check for a valid timeout value. */
+ cmpq $1000000000, 8(%rdx)
+ jae 3f
+
+ pushq %r8
+ cfi_adjust_cfa_offset(8)
+ pushq %r9
+ cfi_adjust_cfa_offset(8)
+ pushq %r12
+ cfi_adjust_cfa_offset(8)
+ pushq %r13
+ cfi_adjust_cfa_offset(8)
+ pushq %r14
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%r8, -16)
+ cfi_offset(%r9, -24)
+ cfi_offset(%r12, -32)
+ cfi_offset(%r13, -40)
+ cfi_offset(%r14, -48)
+ pushq %rsi
+ cfi_adjust_cfa_offset(8)
+
+ /* Stack frame for the timespec and timeval structs. */
+ subq $24, %rsp
+ cfi_adjust_cfa_offset(24)
+
+ movq %rdi, %r12
+ movq %rdx, %r13
+
+ movl $2, %edx
+ xchgl %edx, (%r12)
+
+ testl %edx, %edx
+ je 6f
+
+1:
+ /* Get current time. */
+ movq %rsp, %rdi
+ xorl %esi, %esi
+ movq $VSYSCALL_ADDR_vgettimeofday, %rax
+ /* This is a regular function call, all caller-save registers
+ might be clobbered. */
+ callq *%rax
+
+ /* Compute relative timeout. */
+ movq 8(%rsp), %rax
+ movl $1000, %edi
+ mul %rdi /* Milli seconds to nano seconds. */
+ movq (%r13), %rdi
+ movq 8(%r13), %rsi
+ subq (%rsp), %rdi
+ subq %rax, %rsi
+ jns 4f
+ addq $1000000000, %rsi
+ decq %rdi
+4: testq %rdi, %rdi
+ js 2f /* Time is already up. */
+
+ /* Store relative timeout. */
+ movq %rdi, (%rsp)
+ movq %rsi, 8(%rsp)
+
+ /* Futex call. */
+ movl $2, %edx
+ movl $1, %eax
+ movq %rsp, %r10
+ movl 24(%rsp), %esi
+ LOAD_FUTEX_WAIT (%esi)
+ movq %r12, %rdi
+ movl $SYS_futex, %eax
+ syscall
+
+ /* NB: %edx == 2 */
+ xchgl %edx, (%r12)
+
+ testl %edx, %edx
+ je 6f
+
+ cmpl $-ETIMEDOUT, %eax
+ jne 1b
+2: movl $ETIMEDOUT, %edx
+
+6: addq $32, %rsp
+ cfi_adjust_cfa_offset(-32)
+ popq %r14
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r14)
+ popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r13)
+ popq %r12
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r12)
+ popq %r9
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r9)
+ popq %r8
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r8)
+ movl %edx, %eax
+ retq
+
+3: movl $EINVAL, %eax
+ retq
+# endif
+ cfi_endproc
+ .size __lll_timedlock_wait,.-__lll_timedlock_wait
+#endif
+
+
+ .globl __lll_unlock_wake_private
+ .type __lll_unlock_wake_private,@function
+ .hidden __lll_unlock_wake_private
+ .align 16
+__lll_unlock_wake_private:
+ cfi_startproc
+ pushq %rsi
+ cfi_adjust_cfa_offset(8)
+ pushq %rdx
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%rsi, -16)
+ cfi_offset(%rdx, -24)
+
+ movl $0, (%rdi)
+ LOAD_PRIVATE_FUTEX_WAKE (%esi)
+ movl $1, %edx /* Wake one thread. */
+ movl $SYS_futex, %eax
+ syscall
+
+ popq %rdx
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%rdx)
+ popq %rsi
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%rsi)
+ retq
+ cfi_endproc
+ .size __lll_unlock_wake_private,.-__lll_unlock_wake_private
+
+#ifdef NOT_IN_libc
+ .globl __lll_unlock_wake
+ .type __lll_unlock_wake,@function
+ .hidden __lll_unlock_wake
+ .align 16
+__lll_unlock_wake:
+ cfi_startproc
+ pushq %rsi
+ cfi_adjust_cfa_offset(8)
+ pushq %rdx
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%rsi, -16)
+ cfi_offset(%rdx, -24)
+
+ movl $0, (%rdi)
+ LOAD_FUTEX_WAKE (%esi)
+ movl $1, %edx /* Wake one thread. */
+ movl $SYS_futex, %eax
+ syscall
+
+ popq %rdx
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%rdx)
+ popq %rsi
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%rsi)
+ retq
+ cfi_endproc
+ .size __lll_unlock_wake,.-__lll_unlock_wake
+
+ .globl __lll_timedwait_tid
+ .type __lll_timedwait_tid,@function
+ .hidden __lll_timedwait_tid
+ .align 16
+__lll_timedwait_tid:
+ cfi_startproc
+ pushq %r12
+ cfi_adjust_cfa_offset(8)
+ pushq %r13
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%r12, -16)
+ cfi_offset(%r13, -24)
+
+ movq %rdi, %r12
+ movq %rsi, %r13
+
+ subq $16, %rsp
+ cfi_adjust_cfa_offset(16)
+
+ /* Get current time. */
+2: movq %rsp, %rdi
+ xorl %esi, %esi
+ movq $VSYSCALL_ADDR_vgettimeofday, %rax
+ callq *%rax
+
+ /* Compute relative timeout. */
+ movq 8(%rsp), %rax
+ movl $1000, %edi
+ mul %rdi /* Milli seconds to nano seconds. */
+ movq (%r13), %rdi
+ movq 8(%r13), %rsi
+ subq (%rsp), %rdi
+ subq %rax, %rsi
+ jns 5f
+ addq $1000000000, %rsi
+ decq %rdi
+5: testq %rdi, %rdi
+ js 6f /* Time is already up. */
+
+ movq %rdi, (%rsp) /* Store relative timeout. */
+ movq %rsi, 8(%rsp)
+
+ movl (%r12), %edx
+ testl %edx, %edx
+ jz 4f
+
+ movq %rsp, %r10
+ /* XXX The kernel so far uses global futex for the wakeup at
+ all times. */
+#if FUTEX_WAIT == 0
+ xorl %esi, %esi
+#else
+ movl $FUTEX_WAIT, %esi
+#endif
+ movq %r12, %rdi
+ movl $SYS_futex, %eax
+ syscall
+
+ cmpl $0, (%rdi)
+ jne 1f
+4: xorl %eax, %eax
+
+8: addq $16, %rsp
+ cfi_adjust_cfa_offset(-16)
+ popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r13)
+ popq %r12
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r12)
+ retq
+
+ cfi_adjust_cfa_offset(32)
+1: cmpq $-ETIMEDOUT, %rax
+ jne 2b
+
+6: movl $ETIMEDOUT, %eax
+ jmp 8b
+ cfi_endproc
+ .size __lll_timedwait_tid,.-__lll_timedwait_tid
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
new file mode 100644
index 000000000..7c042fc80
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
@@ -0,0 +1,598 @@
+/* Copyright (C) 2002-2004, 2006-2008, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H 1
+
+#ifndef __ASSEMBLER__
+# include <time.h>
+# include <sys/param.h>
+# include <bits/pthreadtypes.h>
+# include <bits/kernel-features.h>
+# include <tcb-offsets.h>
+
+# ifndef LOCK_INSTR
+# ifdef UP
+# define LOCK_INSTR /* nothing */
+# else
+# define LOCK_INSTR "lock;"
+# endif
+# endif
+#else
+# ifndef LOCK
+# ifdef UP
+# define LOCK
+# else
+# define LOCK lock
+# endif
+# endif
+#endif
+
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_CMP_REQUEUE 4
+#define FUTEX_WAKE_OP 5
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_WAIT_BITSET 9
+#define FUTEX_WAKE_BITSET 10
+#define FUTEX_WAIT_REQUEUE_PI 11
+#define FUTEX_CMP_REQUEUE_PI 12
+#define FUTEX_PRIVATE_FLAG 128
+#define FUTEX_CLOCK_REALTIME 256
+
+#define FUTEX_BITSET_MATCH_ANY 0xffffffff
+
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+#ifndef __ASSEMBLER__
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ({ unsigned int __fl = ((private) ^ FUTEX_PRIVATE_FLAG); \
+ __asm__ ("andl %%fs:%P1, %0" : "+r" (__fl) \
+ : "i" (offsetof (struct pthread, header.private_futex))); \
+ __fl | (fl); }))
+# endif
+#endif
+
+/* Initializer for lock. */
+#define LLL_LOCK_INITIALIZER (0)
+#define LLL_LOCK_INITIALIZER_LOCKED (1)
+#define LLL_LOCK_INITIALIZER_WAITERS (2)
+
+/* Delay in spinlock loop. */
+#define BUSY_WAIT_NOP __asm__ ("rep; nop")
+
+
+#define LLL_STUB_UNWIND_INFO_START \
+ ".section .eh_frame,\"a\",@progbits\n" \
+"7:\t" ".long 9f-8f # Length of Common Information Entry\n" \
+"8:\t" ".long 0x0 # CIE Identifier Tag\n\t" \
+ ".byte 0x1 # CIE Version\n\t" \
+ ".ascii \"zR\\0\" # CIE Augmentation\n\t" \
+ ".uleb128 0x1 # CIE Code Alignment Factor\n\t" \
+ ".sleb128 -8 # CIE Data Alignment Factor\n\t" \
+ ".byte 0x10 # CIE RA Column\n\t" \
+ ".uleb128 0x1 # Augmentation size\n\t" \
+ ".byte 0x1b # FDE Encoding (pcrel sdata4)\n\t" \
+ ".byte 0x12 # DW_CFA_def_cfa_sf\n\t" \
+ ".uleb128 0x7\n\t" \
+ ".sleb128 16\n\t" \
+ ".align 8\n" \
+"9:\t" ".long 23f-10f # FDE Length\n" \
+"10:\t" ".long 10b-7b # FDE CIE offset\n\t" \
+ ".long 1b-. # FDE initial location\n\t" \
+ ".long 6b-1b # FDE address range\n\t" \
+ ".uleb128 0x0 # Augmentation size\n\t" \
+ ".byte 0x16 # DW_CFA_val_expression\n\t" \
+ ".uleb128 0x10\n\t" \
+ ".uleb128 12f-11f\n" \
+"11:\t" ".byte 0x80 # DW_OP_breg16\n\t" \
+ ".sleb128 4b-1b\n"
+#define LLL_STUB_UNWIND_INFO_END \
+ ".byte 0x16 # DW_CFA_val_expression\n\t" \
+ ".uleb128 0x10\n\t" \
+ ".uleb128 14f-13f\n" \
+"13:\t" ".byte 0x80 # DW_OP_breg16\n\t" \
+ ".sleb128 4b-2b\n" \
+"14:\t" ".byte 0x40 + (3b-2b) # DW_CFA_advance_loc\n\t" \
+ ".byte 0x0e # DW_CFA_def_cfa_offset\n\t" \
+ ".uleb128 0\n\t" \
+ ".byte 0x16 # DW_CFA_val_expression\n\t" \
+ ".uleb128 0x10\n\t" \
+ ".uleb128 16f-15f\n" \
+"15:\t" ".byte 0x80 # DW_OP_breg16\n\t" \
+ ".sleb128 4b-3b\n" \
+"16:\t" ".byte 0x40 + (4b-3b-1) # DW_CFA_advance_loc\n\t" \
+ ".byte 0x0e # DW_CFA_def_cfa_offset\n\t" \
+ ".uleb128 128\n\t" \
+ ".byte 0x16 # DW_CFA_val_expression\n\t" \
+ ".uleb128 0x10\n\t" \
+ ".uleb128 20f-17f\n" \
+"17:\t" ".byte 0x80 # DW_OP_breg16\n\t" \
+ ".sleb128 19f-18f\n\t" \
+ ".byte 0x0d # DW_OP_const4s\n" \
+"18:\t" ".4byte 4b-.\n\t" \
+ ".byte 0x1c # DW_OP_minus\n\t" \
+ ".byte 0x0d # DW_OP_const4s\n" \
+"19:\t" ".4byte 24f-.\n\t" \
+ ".byte 0x22 # DW_OP_plus\n" \
+"20:\t" ".byte 0x40 + (5b-4b+1) # DW_CFA_advance_loc\n\t" \
+ ".byte 0x13 # DW_CFA_def_cfa_offset_sf\n\t" \
+ ".sleb128 16\n\t" \
+ ".byte 0x16 # DW_CFA_val_expression\n\t" \
+ ".uleb128 0x10\n\t" \
+ ".uleb128 22f-21f\n" \
+"21:\t" ".byte 0x80 # DW_OP_breg16\n\t" \
+ ".sleb128 4b-5b\n" \
+"22:\t" ".align 8\n" \
+"23:\t" ".previous\n"
+
+/* Unwind info for
+ 1: leaq ..., %rdi
+ 2: subq $128, %rsp
+ 3: callq ...
+ 4: addq $128, %rsp
+ 5: jmp 24f
+ 6:
+ snippet. */
+#define LLL_STUB_UNWIND_INFO_5 \
+LLL_STUB_UNWIND_INFO_START \
+"12:\t" ".byte 0x40 + (2b-1b) # DW_CFA_advance_loc\n\t" \
+LLL_STUB_UNWIND_INFO_END
+
+/* Unwind info for
+ 1: leaq ..., %rdi
+ 0: movq ..., %rdx
+ 2: subq $128, %rsp
+ 3: callq ...
+ 4: addq $128, %rsp
+ 5: jmp 24f
+ 6:
+ snippet. */
+#define LLL_STUB_UNWIND_INFO_6 \
+LLL_STUB_UNWIND_INFO_START \
+"12:\t" ".byte 0x40 + (0b-1b) # DW_CFA_advance_loc\n\t" \
+ ".byte 0x16 # DW_CFA_val_expression\n\t" \
+ ".uleb128 0x10\n\t" \
+ ".uleb128 26f-25f\n" \
+"25:\t" ".byte 0x80 # DW_OP_breg16\n\t" \
+ ".sleb128 4b-0b\n" \
+"26:\t" ".byte 0x40 + (2b-0b) # DW_CFA_advance_loc\n\t" \
+LLL_STUB_UNWIND_INFO_END
+
+
+#define lll_futex_wait(futex, val, private) \
+ lll_futex_timed_wait(futex, val, NULL, private)
+
+
+#define lll_futex_timed_wait(futex, val, timeout, private) \
+ ({ \
+ register const struct timespec *__to __asm__ ("r10") = timeout; \
+ int __status; \
+ register __typeof (val) _val __asm__ ("edx") = (val); \
+ __asm__ __volatile ("syscall" \
+ : "=a" (__status) \
+ : "0" (SYS_futex), "D" (futex), \
+ "S" (__lll_private_flag (FUTEX_WAIT, private)), \
+ "d" (_val), "r" (__to) \
+ : "memory", "cc", "r11", "cx"); \
+ __status; \
+ })
+
+
+#define lll_futex_wake(futex, nr, private) \
+ do { \
+ int __ignore; \
+ register __typeof (nr) _nr __asm__ ("edx") = (nr); \
+ __asm__ __volatile ("syscall" \
+ : "=a" (__ignore) \
+ : "0" (SYS_futex), "D" (futex), \
+ "S" (__lll_private_flag (FUTEX_WAKE, private)), \
+ "d" (_nr) \
+ : "memory", "cc", "r10", "r11", "cx"); \
+ } while (0)
+
+
+/* NB: in the lll_trylock macro we simply return the value in %eax
+ after the cmpxchg instruction. In case the operation succeded this
+ value is zero. In case the operation failed, the cmpxchg instruction
+ has loaded the current value of the memory work which is guaranteed
+ to be nonzero. */
+#if defined NOT_IN_libc || defined UP
+# define __lll_trylock_asm LOCK_INSTR "cmpxchgl %2, %1"
+#else
+# define __lll_trylock_asm "cmpl $0, __libc_multiple_threads(%%rip)\n\t" \
+ "je 0f\n\t" \
+ "lock; cmpxchgl %2, %1\n\t" \
+ "jmp 1f\n\t" \
+ "0:\tcmpxchgl %2, %1\n\t" \
+ "1:"
+#endif
+
+#define lll_trylock(futex) \
+ ({ int ret; \
+ __asm__ __volatile (__lll_trylock_asm \
+ : "=a" (ret), "=m" (futex) \
+ : "r" (LLL_LOCK_INITIALIZER_LOCKED), "m" (futex), \
+ "0" (LLL_LOCK_INITIALIZER) \
+ : "memory"); \
+ ret; })
+
+#define lll_robust_trylock(futex, id) \
+ ({ int ret; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %2, %1" \
+ : "=a" (ret), "=m" (futex) \
+ : "r" (id), "m" (futex), "0" (LLL_LOCK_INITIALIZER) \
+ : "memory"); \
+ ret; })
+
+#define lll_cond_trylock(futex) \
+ ({ int ret; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %2, %1" \
+ : "=a" (ret), "=m" (futex) \
+ : "r" (LLL_LOCK_INITIALIZER_WAITERS), \
+ "m" (futex), "0" (LLL_LOCK_INITIALIZER) \
+ : "memory"); \
+ ret; })
+
+#if defined NOT_IN_libc || defined UP
+# define __lll_lock_asm_start LOCK_INSTR "cmpxchgl %4, %2\n\t" \
+ "jnz 1f\n\t"
+#else
+# define __lll_lock_asm_start "cmpl $0, __libc_multiple_threads(%%rip)\n\t" \
+ "je 0f\n\t" \
+ "lock; cmpxchgl %4, %2\n\t" \
+ "jnz 1f\n\t" \
+ "jmp 24f\n" \
+ "0:\tcmpxchgl %4, %2\n\t" \
+ "jnz 1f\n\t"
+#endif
+
+#define lll_lock(futex, private) \
+ (void) \
+ ({ int ignore1, ignore2, ignore3; \
+ if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \
+ __asm__ __volatile (__lll_lock_asm_start \
+ ".subsection 1\n\t" \
+ ".type _L_lock_%=, @function\n" \
+ "_L_lock_%=:\n" \
+ "1:\tleaq %2, %%rdi\n" \
+ "2:\tsubq $128, %%rsp\n" \
+ "3:\tcallq __lll_lock_wait_private\n" \
+ "4:\taddq $128, %%rsp\n" \
+ "5:\tjmp 24f\n" \
+ "6:\t.size _L_lock_%=, 6b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_5 \
+ "24:" \
+ : "=S" (ignore1), "=&D" (ignore2), "=m" (futex), \
+ "=a" (ignore3) \
+ : "0" (1), "m" (futex), "3" (0) \
+ : "cx", "r11", "cc", "memory"); \
+ else \
+ __asm__ __volatile (__lll_lock_asm_start \
+ ".subsection 1\n\t" \
+ ".type _L_lock_%=, @function\n" \
+ "_L_lock_%=:\n" \
+ "1:\tleaq %2, %%rdi\n" \
+ "2:\tsubq $128, %%rsp\n" \
+ "3:\tcallq __lll_lock_wait\n" \
+ "4:\taddq $128, %%rsp\n" \
+ "5:\tjmp 24f\n" \
+ "6:\t.size _L_lock_%=, 6b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_5 \
+ "24:" \
+ : "=S" (ignore1), "=D" (ignore2), "=m" (futex), \
+ "=a" (ignore3) \
+ : "1" (1), "m" (futex), "3" (0), "0" (private) \
+ : "cx", "r11", "cc", "memory"); \
+ }) \
+
+#define lll_robust_lock(futex, id, private) \
+ ({ int result, ignore1, ignore2; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %4, %2\n\t" \
+ "jnz 1f\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_robust_lock_%=, @function\n" \
+ "_L_robust_lock_%=:\n" \
+ "1:\tleaq %2, %%rdi\n" \
+ "2:\tsubq $128, %%rsp\n" \
+ "3:\tcallq __lll_robust_lock_wait\n" \
+ "4:\taddq $128, %%rsp\n" \
+ "5:\tjmp 24f\n" \
+ "6:\t.size _L_robust_lock_%=, 6b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_5 \
+ "24:" \
+ : "=S" (ignore1), "=D" (ignore2), "=m" (futex), \
+ "=a" (result) \
+ : "1" (id), "m" (futex), "3" (0), "0" (private) \
+ : "cx", "r11", "cc", "memory"); \
+ result; })
+
+#define lll_cond_lock(futex, private) \
+ (void) \
+ ({ int ignore1, ignore2, ignore3; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %4, %2\n\t" \
+ "jnz 1f\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_cond_lock_%=, @function\n" \
+ "_L_cond_lock_%=:\n" \
+ "1:\tleaq %2, %%rdi\n" \
+ "2:\tsubq $128, %%rsp\n" \
+ "3:\tcallq __lll_lock_wait\n" \
+ "4:\taddq $128, %%rsp\n" \
+ "5:\tjmp 24f\n" \
+ "6:\t.size _L_cond_lock_%=, 6b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_5 \
+ "24:" \
+ : "=S" (ignore1), "=D" (ignore2), "=m" (futex), \
+ "=a" (ignore3) \
+ : "1" (2), "m" (futex), "3" (0), "0" (private) \
+ : "cx", "r11", "cc", "memory"); \
+ })
+
+#define lll_robust_cond_lock(futex, id, private) \
+ ({ int result, ignore1, ignore2; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %4, %2\n\t" \
+ "jnz 1f\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_robust_cond_lock_%=, @function\n" \
+ "_L_robust_cond_lock_%=:\n" \
+ "1:\tleaq %2, %%rdi\n" \
+ "2:\tsubq $128, %%rsp\n" \
+ "3:\tcallq __lll_robust_lock_wait\n" \
+ "4:\taddq $128, %%rsp\n" \
+ "5:\tjmp 24f\n" \
+ "6:\t.size _L_robust_cond_lock_%=, 6b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_5 \
+ "24:" \
+ : "=S" (ignore1), "=D" (ignore2), "=m" (futex), \
+ "=a" (result) \
+ : "1" (id | FUTEX_WAITERS), "m" (futex), "3" (0), \
+ "0" (private) \
+ : "cx", "r11", "cc", "memory"); \
+ result; })
+
+#define lll_timedlock(futex, timeout, private) \
+ ({ int result, ignore1, ignore2, ignore3; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %1, %4\n\t" \
+ "jnz 1f\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_timedlock_%=, @function\n" \
+ "_L_timedlock_%=:\n" \
+ "1:\tleaq %4, %%rdi\n" \
+ "0:\tmovq %8, %%rdx\n" \
+ "2:\tsubq $128, %%rsp\n" \
+ "3:\tcallq __lll_timedlock_wait\n" \
+ "4:\taddq $128, %%rsp\n" \
+ "5:\tjmp 24f\n" \
+ "6:\t.size _L_timedlock_%=, 6b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_6 \
+ "24:" \
+ : "=a" (result), "=D" (ignore1), "=S" (ignore2), \
+ "=&d" (ignore3), "=m" (futex) \
+ : "0" (0), "1" (1), "m" (futex), "m" (timeout), \
+ "2" (private) \
+ : "memory", "cx", "cc", "r10", "r11"); \
+ result; })
+
+#define lll_robust_timedlock(futex, timeout, id, private) \
+ ({ int result, ignore1, ignore2, ignore3; \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %1, %4\n\t" \
+ "jnz 1f\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_robust_timedlock_%=, @function\n" \
+ "_L_robust_timedlock_%=:\n" \
+ "1:\tleaq %4, %%rdi\n" \
+ "0:\tmovq %8, %%rdx\n" \
+ "2:\tsubq $128, %%rsp\n" \
+ "3:\tcallq __lll_robust_timedlock_wait\n" \
+ "4:\taddq $128, %%rsp\n" \
+ "5:\tjmp 24f\n" \
+ "6:\t.size _L_robust_timedlock_%=, 6b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_6 \
+ "24:" \
+ : "=a" (result), "=D" (ignore1), "=S" (ignore2), \
+ "=&d" (ignore3), "=m" (futex) \
+ : "0" (0), "1" (id), "m" (futex), "m" (timeout), \
+ "2" (private) \
+ : "memory", "cx", "cc", "r10", "r11"); \
+ result; })
+
+#if defined NOT_IN_libc || defined UP
+# define __lll_unlock_asm_start LOCK_INSTR "decl %0\n\t" \
+ "jne 1f\n\t"
+#else
+# define __lll_unlock_asm_start "cmpl $0, __libc_multiple_threads(%%rip)\n\t" \
+ "je 0f\n\t" \
+ "lock; decl %0\n\t" \
+ "jne 1f\n\t" \
+ "jmp 24f\n\t" \
+ "0:\tdecl %0\n\t" \
+ "jne 1f\n\t"
+#endif
+
+#define lll_unlock(futex, private) \
+ (void) \
+ ({ int ignore; \
+ if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \
+ __asm__ __volatile (__lll_unlock_asm_start \
+ ".subsection 1\n\t" \
+ ".type _L_unlock_%=, @function\n" \
+ "_L_unlock_%=:\n" \
+ "1:\tleaq %0, %%rdi\n" \
+ "2:\tsubq $128, %%rsp\n" \
+ "3:\tcallq __lll_unlock_wake_private\n" \
+ "4:\taddq $128, %%rsp\n" \
+ "5:\tjmp 24f\n" \
+ "6:\t.size _L_unlock_%=, 6b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_5 \
+ "24:" \
+ : "=m" (futex), "=&D" (ignore) \
+ : "m" (futex) \
+ : "ax", "cx", "r11", "cc", "memory"); \
+ else \
+ __asm__ __volatile (__lll_unlock_asm_start \
+ ".subsection 1\n\t" \
+ ".type _L_unlock_%=, @function\n" \
+ "_L_unlock_%=:\n" \
+ "1:\tleaq %0, %%rdi\n" \
+ "2:\tsubq $128, %%rsp\n" \
+ "3:\tcallq __lll_unlock_wake\n" \
+ "4:\taddq $128, %%rsp\n" \
+ "5:\tjmp 24f\n" \
+ "6:\t.size _L_unlock_%=, 6b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_5 \
+ "24:" \
+ : "=m" (futex), "=&D" (ignore) \
+ : "m" (futex), "S" (private) \
+ : "ax", "cx", "r11", "cc", "memory"); \
+ })
+
+#define lll_robust_unlock(futex, private) \
+ do \
+ { \
+ int ignore; \
+ __asm__ __volatile (LOCK_INSTR "andl %2, %0\n\t" \
+ "jne 1f\n\t" \
+ ".subsection 1\n\t" \
+ ".type _L_robust_unlock_%=, @function\n" \
+ "_L_robust_unlock_%=:\n" \
+ "1:\tleaq %0, %%rdi\n" \
+ "2:\tsubq $128, %%rsp\n" \
+ "3:\tcallq __lll_unlock_wake\n" \
+ "4:\taddq $128, %%rsp\n" \
+ "5:\tjmp 24f\n" \
+ "6:\t.size _L_robust_unlock_%=, 6b-1b\n\t" \
+ ".previous\n" \
+ LLL_STUB_UNWIND_INFO_5 \
+ "24:" \
+ : "=m" (futex), "=&D" (ignore) \
+ : "i" (FUTEX_WAITERS), "m" (futex), \
+ "S" (private) \
+ : "ax", "cx", "r11", "cc", "memory"); \
+ } \
+ while (0)
+
+#define lll_robust_dead(futex, private) \
+ do \
+ { \
+ int ignore; \
+ __asm__ __volatile (LOCK_INSTR "orl %3, (%2)\n\t" \
+ "syscall" \
+ : "=m" (futex), "=a" (ignore) \
+ : "D" (&(futex)), "i" (FUTEX_OWNER_DIED), \
+ "S" (__lll_private_flag (FUTEX_WAKE, private)), \
+ "1" (__NR_futex), "d" (1) \
+ : "cx", "r11", "cc", "memory"); \
+ } \
+ while (0)
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val, private) \
+ ({ int __res; \
+ register int __nr_move __asm__ ("r10") = nr_move; \
+ register void *__mutex __asm__ ("r8") = mutex; \
+ register int __val __asm__ ("r9") = val; \
+ __asm__ __volatile ("syscall" \
+ : "=a" (__res) \
+ : "0" (__NR_futex), "D" ((void *) ftx), \
+ "S" (__lll_private_flag (FUTEX_CMP_REQUEUE, \
+ private)), "d" (nr_wake), \
+ "r" (__nr_move), "r" (__mutex), "r" (__val) \
+ : "cx", "r11", "cc", "memory"); \
+ __res < 0; })
+
+#define lll_islocked(futex) \
+ (futex != LLL_LOCK_INITIALIZER)
+
+
+/* The kernel notifies a process with uses CLONE_CLEARTID via futex
+ wakeup when the clone terminates. The memory location contains the
+ thread ID while the clone is running and is reset to zero
+ afterwards.
+
+ The macro parameter must not have any side effect. */
+#define lll_wait_tid(tid) \
+ do { \
+ int __ignore; \
+ register __typeof (tid) _tid __asm__ ("edx") = (tid); \
+ if (_tid != 0) \
+ __asm__ __volatile ("xorq %%r10, %%r10\n\t" \
+ "1:\tmovq %2, %%rax\n\t" \
+ "syscall\n\t" \
+ "cmpl $0, (%%rdi)\n\t" \
+ "jne 1b" \
+ : "=&a" (__ignore) \
+ : "S" (FUTEX_WAIT), "i" (SYS_futex), "D" (&tid), \
+ "d" (_tid) \
+ : "memory", "cc", "r10", "r11", "cx"); \
+ } while (0)
+
+extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
+ attribute_hidden;
+#define lll_timedwait_tid(tid, abstime) \
+ ({ \
+ int __result = 0; \
+ if (tid != 0) \
+ { \
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) \
+ __result = EINVAL; \
+ else \
+ __result = __lll_timedwait_tid (&tid, abstime); \
+ } \
+ __result; })
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* lowlevellock.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
new file mode 100644
index 000000000..2eb8e29fa
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
@@ -0,0 +1,306 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <lowlevellock.h>
+#include <lowlevelrobustlock.h>
+#include <bits/kernel-features.h>
+
+ .text
+
+#define FUTEX_WAITERS 0x80000000
+#define FUTEX_OWNER_DIED 0x40000000
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
+# define LOAD_FUTEX_WAIT_ABS(reg) \
+ xorl $(FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME), reg
+#else
+# if FUTEX_WAIT == 0
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %fs:PRIVATE_FUTEX, reg
+# else
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %fs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAIT, reg
+# endif
+# define LOAD_FUTEX_WAIT_ABS(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %fs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME, reg
+#endif
+
+/* For the calculation see asm/vsyscall.h. */
+#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
+
+
+ .globl __lll_robust_lock_wait
+ .type __lll_robust_lock_wait,@function
+ .hidden __lll_robust_lock_wait
+ .align 16
+__lll_robust_lock_wait:
+ cfi_startproc
+ pushq %r10
+ cfi_adjust_cfa_offset(8)
+ pushq %rdx
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%r10, -16)
+ cfi_offset(%rdx, -24)
+
+ xorq %r10, %r10 /* No timeout. */
+ LOAD_FUTEX_WAIT (%esi)
+
+4: movl %eax, %edx
+ orl $FUTEX_WAITERS, %edx
+
+ testl $FUTEX_OWNER_DIED, %eax
+ jnz 3f
+
+ cmpl %edx, %eax
+ je 1f
+
+ LOCK
+ cmpxchgl %edx, (%rdi)
+ jnz 2f
+
+1: movl $SYS_futex, %eax
+ syscall
+
+ movl (%rdi), %eax
+
+2: testl %eax, %eax
+ jne 4b
+
+ movl %fs:TID, %edx
+ orl $FUTEX_WAITERS, %edx
+ LOCK
+ cmpxchgl %edx, (%rdi)
+ jnz 4b
+ /* NB: %rax == 0 */
+
+3: popq %rdx
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%rdx)
+ popq %r10
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r10)
+ retq
+ cfi_endproc
+ .size __lll_robust_lock_wait,.-__lll_robust_lock_wait
+
+
+ .globl __lll_robust_timedlock_wait
+ .type __lll_robust_timedlock_wait,@function
+ .hidden __lll_robust_timedlock_wait
+ .align 16
+__lll_robust_timedlock_wait:
+ cfi_startproc
+# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+# ifdef __PIC__
+ cmpl $0, __have_futex_clock_realtime(%rip)
+# else
+ cmpl $0, __have_futex_clock_realtime
+# endif
+ je .Lreltmo
+# endif
+
+ pushq %r9
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r9, 0)
+ movq %rdx, %r10
+ movl $0xffffffff, %r9d
+ LOAD_FUTEX_WAIT_ABS (%esi)
+
+1: testl $FUTEX_OWNER_DIED, %eax
+ jnz 3f
+
+ movl %eax, %edx
+ orl $FUTEX_WAITERS, %edx
+
+ cmpl %eax, %edx
+ je 5f
+
+ LOCK
+ cmpxchgl %edx, (%rdi)
+ movq $0, %rcx /* Must use mov to avoid changing cc. */
+ jnz 6f
+
+5: movl $SYS_futex, %eax
+ syscall
+ movl %eax, %ecx
+
+ movl (%rdi), %eax
+
+6: testl %eax, %eax
+ jne 2f
+
+ movl %fs:TID, %edx
+ orl $FUTEX_WAITERS, %edx
+ LOCK
+ cmpxchgl %edx, (%rdi)
+ jnz 2f
+
+3: popq %r9
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r9)
+ retq
+
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r9, 0)
+ /* Check whether the time expired. */
+2: cmpl $-ETIMEDOUT, %ecx
+ je 4f
+ cmpl $-EINVAL, %ecx
+ jne 1b
+
+4: movl %ecx, %eax
+ negl %eax
+ jmp 3b
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r9)
+
+
+# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+.Lreltmo:
+ /* Check for a valid timeout value. */
+ cmpq $1000000000, 8(%rdx)
+ jae 3f
+
+ pushq %r8
+ cfi_adjust_cfa_offset(8)
+ pushq %r9
+ cfi_adjust_cfa_offset(8)
+ pushq %r12
+ cfi_adjust_cfa_offset(8)
+ pushq %r13
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%r8, -16)
+ cfi_offset(%r9, -24)
+ cfi_offset(%r12, -32)
+ cfi_offset(%r13, -40)
+ pushq %rsi
+ cfi_adjust_cfa_offset(8)
+
+ /* Stack frame for the timespec and timeval structs. */
+ subq $32, %rsp
+ cfi_adjust_cfa_offset(32)
+
+ movq %rdi, %r12
+ movq %rdx, %r13
+
+1: movq %rax, 16(%rsp)
+
+ /* Get current time. */
+ movq %rsp, %rdi
+ xorl %esi, %esi
+ movq $VSYSCALL_ADDR_vgettimeofday, %rax
+ /* This is a regular function call, all caller-save registers
+ might be clobbered. */
+ callq *%rax
+
+ /* Compute relative timeout. */
+ movq 8(%rsp), %rax
+ movl $1000, %edi
+ mul %rdi /* Milli seconds to nano seconds. */
+ movq (%r13), %rdi
+ movq 8(%r13), %rsi
+ subq (%rsp), %rdi
+ subq %rax, %rsi
+ jns 4f
+ addq $1000000000, %rsi
+ decq %rdi
+4: testq %rdi, %rdi
+ js 8f /* Time is already up. */
+
+ /* Futex call. */
+ movq %rdi, (%rsp) /* Store relative timeout. */
+ movq %rsi, 8(%rsp)
+
+ movq 16(%rsp), %rdx
+ movl %edx, %eax
+ orl $FUTEX_WAITERS, %edx
+
+ testl $FUTEX_OWNER_DIED, %eax
+ jnz 6f
+
+ cmpl %eax, %edx
+ je 2f
+
+ LOCK
+ cmpxchgl %edx, (%r12)
+ movq $0, %rcx /* Must use mov to avoid changing cc. */
+ jnz 5f
+
+2: movq %rsp, %r10
+ movl 32(%rsp), %esi
+ LOAD_FUTEX_WAIT (%esi)
+ movq %r12, %rdi
+ movl $SYS_futex, %eax
+ syscall
+ movq %rax, %rcx
+
+ movl (%r12), %eax
+
+5: testl %eax, %eax
+ jne 7f
+
+ movl %fs:TID, %edx
+ orl $FUTEX_WAITERS, %edx
+ LOCK
+ cmpxchgl %edx, (%r12)
+ jnz 7f
+
+6: addq $40, %rsp
+ cfi_adjust_cfa_offset(-40)
+ popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r13)
+ popq %r12
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r12)
+ popq %r9
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r9)
+ popq %r8
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r8)
+ retq
+
+3: movl $EINVAL, %eax
+ retq
+
+ cfi_adjust_cfa_offset(72)
+ cfi_offset(%r8, -16)
+ cfi_offset(%r9, -24)
+ cfi_offset(%r12, -32)
+ cfi_offset(%r13, -40)
+ /* Check whether the time expired. */
+7: cmpl $-ETIMEDOUT, %ecx
+ jne 1b
+
+8: movl $ETIMEDOUT, %eax
+ jmp 6b
+#endif
+ cfi_endproc
+ .size __lll_robust_timedlock_wait,.-__lll_robust_timedlock_wait
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-__syscall_error.c b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-__syscall_error.c
new file mode 100644
index 000000000..2ab81490c
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-__syscall_error.c
@@ -0,0 +1 @@
+#include <../../../../../../../libc/sysdeps/linux/x86_64/__syscall_error.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-vfork.S
new file mode 100644
index 000000000..df4949615
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-vfork.S
@@ -0,0 +1,33 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <tcb-offsets.h>
+
+#define SAVE_PID \
+ movl %fs:PID, %esi; \
+ movl %esi, %edx; \
+ negl %edx; \
+ movl %edx, %fs:PID
+
+#define RESTORE_PID \
+ testq %rax, %rax; \
+ je 1f; \
+ movl %esi, %fs:PID; \
+1:
+
+#include <../../../../../../../libc/sysdeps/linux/x86_64/vfork.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
new file mode 100644
index 000000000..15ad534fa
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
@@ -0,0 +1,161 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelbarrier.h>
+
+
+ .text
+
+ .globl pthread_barrier_wait
+ .type pthread_barrier_wait,@function
+ .align 16
+pthread_barrier_wait:
+ /* Get the mutex. */
+ xorl %eax, %eax
+ movl $1, %esi
+ LOCK
+ cmpxchgl %esi, MUTEX(%rdi)
+ jnz 1f
+
+ /* One less waiter. If this was the last one needed wake
+ everybody. */
+2: decl LEFT(%rdi)
+ je 3f
+
+ /* There are more threads to come. */
+#if CURR_EVENT == 0
+ movl (%rdi), %edx
+#else
+ movl CURR_EVENT(%rdi), %edx
+#endif
+
+ /* Release the mutex. */
+ LOCK
+ decl MUTEX(%rdi)
+ jne 6f
+
+ /* Wait for the remaining threads. The call will return immediately
+ if the CURR_EVENT memory has meanwhile been changed. */
+7:
+#if FUTEX_WAIT == 0
+ movl PRIVATE(%rdi), %esi
+#else
+ movl $FUTEX_WAIT, %esi
+ orl PRIVATE(%rdi), %esi
+#endif
+ xorq %r10, %r10
+8: movl $SYS_futex, %eax
+ syscall
+
+ /* Don't return on spurious wakeups. The syscall does not change
+ any register except %eax so there is no need to reload any of
+ them. */
+#if CURR_EVENT == 0
+ cmpl %edx, (%rdi)
+#else
+ cmpl %edx, CURR_EVENT(%rdi)
+#endif
+ je 8b
+
+ /* Increment LEFT. If this brings the count back to the
+ initial count unlock the object. */
+ movl $1, %edx
+ movl INIT_COUNT(%rdi), %eax
+ LOCK
+ xaddl %edx, LEFT(%rdi)
+ subl $1, %eax
+ cmpl %eax, %edx
+ jne,pt 10f
+
+ /* Release the mutex. We cannot release the lock before
+ waking the waiting threads since otherwise a new thread might
+ arrive and gets waken up, too. */
+ LOCK
+ decl MUTEX(%rdi)
+ jne 9f
+
+10: xorl %eax, %eax /* != PTHREAD_BARRIER_SERIAL_THREAD */
+
+ retq
+
+ /* The necessary number of threads arrived. */
+3:
+#if CURR_EVENT == 0
+ incl (%rdi)
+#else
+ incl CURR_EVENT(%rdi)
+#endif
+
+ /* Wake up all waiters. The count is a signed number in the kernel
+ so 0x7fffffff is the highest value. */
+ movl $0x7fffffff, %edx
+ movl $FUTEX_WAKE, %esi
+ orl PRIVATE(%rdi), %esi
+ movl $SYS_futex, %eax
+ syscall
+
+ /* Increment LEFT. If this brings the count back to the
+ initial count unlock the object. */
+ movl $1, %edx
+ movl INIT_COUNT(%rdi), %eax
+ LOCK
+ xaddl %edx, LEFT(%rdi)
+ subl $1, %eax
+ cmpl %eax, %edx
+ jne,pt 5f
+
+ /* Release the mutex. We cannot release the lock before
+ waking the waiting threads since otherwise a new thread might
+ arrive and gets waken up, too. */
+ LOCK
+ decl MUTEX(%rdi)
+ jne 4f
+
+5: orl $-1, %eax /* == PTHREAD_BARRIER_SERIAL_THREAD */
+
+ retq
+
+1: movl PRIVATE(%rdi), %esi
+ addq $MUTEX, %rdi
+ xorl $LLL_SHARED, %esi
+ callq __lll_lock_wait
+ subq $MUTEX, %rdi
+ jmp 2b
+
+4: movl PRIVATE(%rdi), %esi
+ addq $MUTEX, %rdi
+ xorl $LLL_SHARED, %esi
+ callq __lll_unlock_wake
+ jmp 5b
+
+6: movl PRIVATE(%rdi), %esi
+ addq $MUTEX, %rdi
+ xorl $LLL_SHARED, %esi
+ callq __lll_unlock_wake
+ subq $MUTEX, %rdi
+ jmp 7b
+
+9: movl PRIVATE(%rdi), %esi
+ addq $MUTEX, %rdi
+ xorl $LLL_SHARED, %esi
+ callq __lll_unlock_wake
+ jmp 10b
+ .size pthread_barrier_wait,.-pthread_barrier_wait
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
new file mode 100644
index 000000000..1a116cf8f
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
@@ -0,0 +1,178 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelcond.h>
+#include <bits/kernel-features.h>
+#include <pthread-pi-defines.h>
+#include <pthread-errnos.h>
+
+
+ .text
+
+ /* int pthread_cond_broadcast (pthread_cond_t *cond) */
+ .globl __pthread_cond_broadcast
+ .type __pthread_cond_broadcast, @function
+ .protected __pthread_cond_broadcast
+ .align 16
+__pthread_cond_broadcast:
+
+ /* Get internal lock. */
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, cond_lock(%rdi)
+#endif
+ jnz 1f
+
+2: addq $cond_futex, %rdi
+ movq total_seq-cond_futex(%rdi), %r9
+ cmpq wakeup_seq-cond_futex(%rdi), %r9
+ jna 4f
+
+ /* Cause all currently waiting threads to recognize they are
+ woken up. */
+ movq %r9, wakeup_seq-cond_futex(%rdi)
+ movq %r9, woken_seq-cond_futex(%rdi)
+ addq %r9, %r9
+ movl %r9d, (%rdi)
+ incl broadcast_seq-cond_futex(%rdi)
+
+ /* Get the address of the mutex used. */
+ movq dep_mutex-cond_futex(%rdi), %r8
+
+ /* Unlock. */
+ LOCK
+ decl cond_lock-cond_futex(%rdi)
+ jne 7f
+
+8: cmpq $-1, %r8
+ je 9f
+
+ /* Do not use requeue for pshared condvars. */
+ testl $PS_BIT, MUTEX_KIND(%r8)
+ jne 9f
+
+ /* Requeue to a PI mutex if the PI bit is set. */
+ movl MUTEX_KIND(%r8), %eax
+ andl $(ROBUST_BIT|PI_BIT), %eax
+ cmpl $PI_BIT, %eax
+ je 81f
+
+ /* Wake up all threads. */
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), %esi
+#else
+ movl %fs:PRIVATE_FUTEX, %esi
+ orl $FUTEX_CMP_REQUEUE, %esi
+#endif
+ movl $SYS_futex, %eax
+ movl $1, %edx
+ movl $0x7fffffff, %r10d
+ syscall
+
+ /* For any kind of error, which mainly is EAGAIN, we try again
+ with WAKE. The general test also covers running on old
+ kernels. */
+ cmpq $-4095, %rax
+ jae 9f
+
+10: xorl %eax, %eax
+ retq
+
+ /* Wake up all threads. */
+81: movl $(FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
+ movl $SYS_futex, %eax
+ movl $1, %edx
+ movl $0x7fffffff, %r10d
+ syscall
+
+ /* For any kind of error, which mainly is EAGAIN, we try again
+ with WAKE. The general test also covers running on old
+ kernels. */
+ cmpq $-4095, %rax
+ jb 10b
+ jmp 9f
+
+ .align 16
+ /* Unlock. */
+4: LOCK
+ decl cond_lock-cond_futex(%rdi)
+ jne 5f
+
+6: xorl %eax, %eax
+ retq
+
+ /* Initial locking failed. */
+1:
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_lock_wait
+#if cond_lock != 0
+ subq $cond_lock, %rdi
+#endif
+ jmp 2b
+
+ /* Unlock in loop requires wakeup. */
+5: addq $cond_lock-cond_futex, %rdi
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_unlock_wake
+ jmp 6b
+
+ /* Unlock in loop requires wakeup. */
+7: addq $cond_lock-cond_futex, %rdi
+ cmpq $-1, %r8
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_unlock_wake
+ subq $cond_lock-cond_futex, %rdi
+ jmp 8b
+
+9: /* The futex requeue functionality is not available. */
+ cmpq $-1, %r8
+ movl $0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE, %eax
+ movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+#else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+ orl $FUTEX_WAKE, %esi
+#endif
+ movl $SYS_futex, %eax
+ syscall
+ jmp 10b
+ .size __pthread_cond_broadcast, .-__pthread_cond_broadcast
+weak_alias(__pthread_cond_broadcast, pthread_cond_broadcast)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
new file mode 100644
index 000000000..9852e79fc
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
@@ -0,0 +1,161 @@
+/* Copyright (C) 2002-2005, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelcond.h>
+#include <pthread-pi-defines.h>
+#include <bits/kernel-features.h>
+#include <pthread-errnos.h>
+
+
+ .text
+
+ /* int pthread_cond_signal (pthread_cond_t *cond) */
+ .globl __pthread_cond_signal
+ .type __pthread_cond_signal, @function
+ .protected __pthread_cond_signal
+ .align 16
+__pthread_cond_signal:
+
+ /* Get internal lock. */
+ movq %rdi, %r8
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, cond_lock(%rdi)
+#endif
+ jnz 1f
+
+2: addq $cond_futex, %rdi
+ movq total_seq(%r8), %rcx
+ cmpq wakeup_seq(%r8), %rcx
+ jbe 4f
+
+ /* Bump the wakeup number. */
+ addq $1, wakeup_seq(%r8)
+ addl $1, (%rdi)
+
+ /* Wake up one thread. */
+ cmpq $-1, dep_mutex(%r8)
+ movl $FUTEX_WAKE_OP, %esi
+ movl $1, %edx
+ movl $SYS_futex, %eax
+ je 8f
+
+ /* Get the address of the mutex used. */
+ movq dep_mutex(%r8), %rcx
+ movl MUTEX_KIND(%rcx), %r11d
+ andl $(ROBUST_BIT|PI_BIT), %r11d
+ cmpl $PI_BIT, %r11d
+ je 9f
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $(FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG), %esi
+#else
+ orl %fs:PRIVATE_FUTEX, %esi
+#endif
+
+8: movl $1, %r10d
+#if cond_lock != 0
+ addq $cond_lock, %r8
+#endif
+ movl $FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, %r9d
+ syscall
+#if cond_lock != 0
+ subq $cond_lock, %r8
+#endif
+ /* For any kind of error, we try again with WAKE.
+ The general test also covers running on old kernels. */
+ cmpq $-4095, %rax
+ jae 7f
+
+ xorl %eax, %eax
+ retq
+
+ /* Wake up one thread and requeue none in the PI Mutex case. */
+9: movl $(FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
+ movq %rcx, %r8
+ xorq %r10, %r10
+ movl (%rdi), %r9d // XXX Can this be right?
+ syscall
+
+ leaq -cond_futex(%rdi), %r8
+
+ /* For any kind of error, we try again with WAKE.
+ The general test also covers running on old kernels. */
+ cmpq $-4095, %rax
+ jb 4f
+
+7:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %esi
+#else
+ andl %fs:PRIVATE_FUTEX, %esi
+#endif
+ orl $FUTEX_WAKE, %esi
+ movl $SYS_futex, %eax
+ /* %rdx should be 1 already from $FUTEX_WAKE_OP syscall.
+ movl $1, %edx */
+ syscall
+
+ /* Unlock. */
+4: LOCK
+#if cond_lock == 0
+ decl (%r8)
+#else
+ decl cond_lock(%r8)
+#endif
+ jne 5f
+
+6: xorl %eax, %eax
+ retq
+
+ /* Initial locking failed. */
+1:
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_lock_wait
+#if cond_lock != 0
+ subq $cond_lock, %rdi
+#endif
+ jmp 2b
+
+ /* Unlock in loop requires wakeup. */
+5:
+ movq %r8, %rdi
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_unlock_wake
+ jmp 6b
+ .size __pthread_cond_signal, .-__pthread_cond_signal
+weak_alias(__pthread_cond_signal, pthread_cond_signal)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
new file mode 100644
index 000000000..3a965ad0b
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
@@ -0,0 +1,804 @@
+/* Copyright (C) 2002-2005, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelcond.h>
+#include <pthread-pi-defines.h>
+#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+
+/* For the calculation see asm/vsyscall.h. */
+#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
+
+
+ .text
+
+
+/* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
+ const struct timespec *abstime) */
+ .globl __pthread_cond_timedwait
+ .type __pthread_cond_timedwait, @function
+ .protected __pthread_cond_timedwait
+ .align 16
+__pthread_cond_timedwait:
+.LSTARTCODE:
+ cfi_startproc
+
+ pushq %r12
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r12, 0)
+ pushq %r13
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r13, 0)
+ pushq %r14
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r14, 0)
+ pushq %r15
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r15, 0)
+#ifdef __ASSUME_FUTEX_CLOCK_REALTIME
+# define FRAME_SIZE 32
+#else
+# define FRAME_SIZE 48
+#endif
+ subq $FRAME_SIZE, %rsp
+ cfi_adjust_cfa_offset(FRAME_SIZE)
+ cfi_remember_state
+
+ cmpq $1000000000, 8(%rdx)
+ movl $EINVAL, %eax
+ jae 48f
+
+ /* Stack frame:
+
+ rsp + 48
+ +--------------------------+
+ rsp + 32 | timeout value |
+ +--------------------------+
+ rsp + 24 | old wake_seq value |
+ +--------------------------+
+ rsp + 16 | mutex pointer |
+ +--------------------------+
+ rsp + 8 | condvar pointer |
+ +--------------------------+
+ rsp + 4 | old broadcast_seq value |
+ +--------------------------+
+ rsp + 0 | old cancellation mode |
+ +--------------------------+
+ */
+
+ cmpq $-1, dep_mutex(%rdi)
+
+ /* Prepare structure passed to cancellation handler. */
+ movq %rdi, 8(%rsp)
+ movq %rsi, 16(%rsp)
+ movq %rdx, %r13
+
+ je 22f
+ movq %rsi, dep_mutex(%rdi)
+
+22:
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+# ifdef __PIC__
+ cmpl $0, __have_futex_clock_realtime(%rip)
+# else
+ cmpl $0, __have_futex_clock_realtime
+# endif
+ je .Lreltmo
+#endif
+
+ /* Get internal lock. */
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, cond_lock(%rdi)
+#endif
+ jnz 31f
+
+ /* Unlock the mutex. */
+32: movq 16(%rsp), %rdi
+ xorl %esi, %esi
+ callq __pthread_mutex_unlock_usercnt
+
+ testl %eax, %eax
+ jne 46f
+
+ movq 8(%rsp), %rdi
+ incq total_seq(%rdi)
+ incl cond_futex(%rdi)
+ addl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
+
+ /* Get and store current wakeup_seq value. */
+ movq 8(%rsp), %rdi
+ movq wakeup_seq(%rdi), %r9
+ movl broadcast_seq(%rdi), %edx
+ movq %r9, 24(%rsp)
+ movl %edx, 4(%rsp)
+
+38: movl cond_futex(%rdi), %r12d
+
+ /* Unlock. */
+ LOCK
+#if cond_lock == 0
+ decl (%rdi)
+#else
+ decl cond_lock(%rdi)
+#endif
+ jne 33f
+
+.LcleanupSTART1:
+34: callq __pthread_enable_asynccancel
+ movl %eax, (%rsp)
+
+ movq %r13, %r10
+ movl $FUTEX_WAIT_BITSET, %esi
+ cmpq $-1, dep_mutex(%rdi)
+ je 60f
+
+ movq dep_mutex(%rdi), %r8
+ /* Requeue to a non-robust PI mutex if the PI bit is set and
+ the robust bit is not set. */
+ movl MUTEX_KIND(%r8), %eax
+ andl $(ROBUST_BIT|PI_BIT), %eax
+ cmpl $PI_BIT, %eax
+ jne 61f
+
+ movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
+ xorl %eax, %eax
+ /* The following only works like this because we only support
+ two clocks, represented using a single bit. */
+ testl $1, cond_nwaiters(%rdi)
+ movl $FUTEX_CLOCK_REALTIME, %edx
+ cmove %edx, %eax
+ orl %eax, %esi
+ movq %r12, %rdx
+ addq $cond_futex, %rdi
+ movl $SYS_futex, %eax
+ syscall
+
+ movl $1, %r15d
+#ifdef __ASSUME_REQUEUE_PI
+ jmp 62f
+#else
+ cmpq $-4095, %rax
+ jnae 62f
+
+ subq $cond_futex, %rdi
+#endif
+
+61: movl $(FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG), %esi
+60: xorl %r15d, %r15d
+ xorl %eax, %eax
+ /* The following only works like this because we only support
+ two clocks, represented using a single bit. */
+ testl $1, cond_nwaiters(%rdi)
+ movl $FUTEX_CLOCK_REALTIME, %edx
+ movl $0xffffffff, %r9d
+ cmove %edx, %eax
+ orl %eax, %esi
+ movq %r12, %rdx
+ addq $cond_futex, %rdi
+ movl $SYS_futex, %eax
+ syscall
+62: movq %rax, %r14
+
+ movl (%rsp), %edi
+ callq __pthread_disable_asynccancel
+.LcleanupEND1:
+
+ /* Lock. */
+ movq 8(%rsp), %rdi
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, cond_lock(%rdi)
+#endif
+ jne 35f
+
+36: movl broadcast_seq(%rdi), %edx
+
+ movq woken_seq(%rdi), %rax
+
+ movq wakeup_seq(%rdi), %r9
+
+ cmpl 4(%rsp), %edx
+ jne 53f
+
+ cmpq 24(%rsp), %r9
+ jbe 45f
+
+ cmpq %rax, %r9
+ ja 39f
+
+45: cmpq $-ETIMEDOUT, %r14
+ jne 38b
+
+99: incq wakeup_seq(%rdi)
+ incl cond_futex(%rdi)
+ movl $ETIMEDOUT, %r14d
+ jmp 44f
+
+53: xorq %r14, %r14
+ jmp 54f
+
+39: xorq %r14, %r14
+44: incq woken_seq(%rdi)
+
+54: subl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ cmpq $0xffffffffffffffff, total_seq(%rdi)
+ jne 55f
+ movl cond_nwaiters(%rdi), %eax
+ andl $~((1 << nwaiters_shift) - 1), %eax
+ jne 55f
+
+ addq $cond_nwaiters, %rdi
+ cmpq $-1, dep_mutex-cond_nwaiters(%rdi)
+ movl $1, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE, %eax
+ movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+#else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+ orl $FUTEX_WAKE, %esi
+#endif
+ movl $SYS_futex, %eax
+ syscall
+ subq $cond_nwaiters, %rdi
+
+55: LOCK
+#if cond_lock == 0
+ decl (%rdi)
+#else
+ decl cond_lock(%rdi)
+#endif
+ jne 40f
+
+ /* If requeue_pi is used the kernel performs the locking of the
+ mutex. */
+41: movq 16(%rsp), %rdi
+ testl %r15d, %r15d
+ jnz 64f
+
+ callq __pthread_mutex_cond_lock
+
+63: testq %rax, %rax
+ cmoveq %r14, %rax
+
+48: addq $FRAME_SIZE, %rsp
+ cfi_adjust_cfa_offset(-FRAME_SIZE)
+ popq %r15
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r15)
+ popq %r14
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r14)
+ popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r13)
+ popq %r12
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r12)
+
+ retq
+
+ cfi_restore_state
+
+64: callq __pthread_mutex_cond_lock_adjust
+ movq %r14, %rax
+ jmp 48b
+
+ /* Initial locking failed. */
+31:
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_lock_wait
+ jmp 32b
+
+ /* Unlock in loop requires wakeup. */
+33:
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_unlock_wake
+ jmp 34b
+
+ /* Locking in loop failed. */
+35:
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_lock_wait
+#if cond_lock != 0
+ subq $cond_lock, %rdi
+#endif
+ jmp 36b
+
+ /* Unlock after loop requires wakeup. */
+40:
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_unlock_wake
+ jmp 41b
+
+ /* The initial unlocking of the mutex failed. */
+46: movq 8(%rsp), %rdi
+ movq %rax, (%rsp)
+ LOCK
+#if cond_lock == 0
+ decl (%rdi)
+#else
+ decl cond_lock(%rdi)
+#endif
+ jne 47f
+
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_unlock_wake
+
+47: movq (%rsp), %rax
+ jmp 48b
+
+
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+.Lreltmo:
+ xorl %r15d, %r15d
+
+ /* Get internal lock. */
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+# if cond_lock == 0
+ cmpxchgl %esi, (%rdi)
+# else
+ cmpxchgl %esi, cond_lock(%rdi)
+# endif
+ jnz 1f
+
+ /* Unlock the mutex. */
+2: movq 16(%rsp), %rdi
+ xorl %esi, %esi
+ callq __pthread_mutex_unlock_usercnt
+
+ testl %eax, %eax
+ jne 46b
+
+ movq 8(%rsp), %rdi
+ incq total_seq(%rdi)
+ incl cond_futex(%rdi)
+ addl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
+
+ /* Get and store current wakeup_seq value. */
+ movq 8(%rsp), %rdi
+ movq wakeup_seq(%rdi), %r9
+ movl broadcast_seq(%rdi), %edx
+ movq %r9, 24(%rsp)
+ movl %edx, 4(%rsp)
+
+ /* Get the current time. */
+8:
+# ifdef __NR_clock_gettime
+ /* Get the clock number. Note that the field in the condvar
+ structure stores the number minus 1. */
+ movq 8(%rsp), %rdi
+ movl cond_nwaiters(%rdi), %edi
+ andl $((1 << nwaiters_shift) - 1), %edi
+ /* Only clocks 0 and 1 are allowed so far. Both are handled in the
+ kernel. */
+ leaq 32(%rsp), %rsi
+# ifdef SHARED
+ movq __vdso_clock_gettime@GOTPCREL(%rip), %rax
+ movq (%rax), %rax
+ PTR_DEMANGLE (%rax)
+ jz 26f
+ call *%rax
+ jmp 27f
+# endif
+26: movl $__NR_clock_gettime, %eax
+ syscall
+27:
+# ifndef __ASSUME_POSIX_TIMERS
+ cmpq $-ENOSYS, %rax
+ je 19f
+# endif
+
+ /* Compute relative timeout. */
+ movq (%r13), %rcx
+ movq 8(%r13), %rdx
+ subq 32(%rsp), %rcx
+ subq 40(%rsp), %rdx
+# else
+ leaq 24(%rsp), %rdi
+ xorl %esi, %esi
+ movq $VSYSCALL_ADDR_vgettimeofday, %rax
+ callq *%rax
+
+ /* Compute relative timeout. */
+ movq 40(%rsp), %rax
+ movl $1000, %edx
+ mul %rdx /* Milli seconds to nano seconds. */
+ movq (%r13), %rcx
+ movq 8(%r13), %rdx
+ subq 32(%rsp), %rcx
+ subq %rax, %rdx
+# endif
+ jns 12f
+ addq $1000000000, %rdx
+ decq %rcx
+12: testq %rcx, %rcx
+ movq 8(%rsp), %rdi
+ movq $-ETIMEDOUT, %r14
+ js 6f
+
+ /* Store relative timeout. */
+21: movq %rcx, 32(%rsp)
+ movq %rdx, 40(%rsp)
+
+ movl cond_futex(%rdi), %r12d
+
+ /* Unlock. */
+ LOCK
+# if cond_lock == 0
+ decl (%rdi)
+# else
+ decl cond_lock(%rdi)
+# endif
+ jne 3f
+
+.LcleanupSTART2:
+4: callq __pthread_enable_asynccancel
+ movl %eax, (%rsp)
+
+ leaq 32(%rsp), %r10
+ cmpq $-1, dep_mutex(%rdi)
+ movq %r12, %rdx
+# ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAIT, %eax
+ movl $(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+# else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+# if FUTEX_WAIT != 0
+ orl $FUTEX_WAIT, %esi
+# endif
+# endif
+ addq $cond_futex, %rdi
+ movl $SYS_futex, %eax
+ syscall
+ movq %rax, %r14
+
+ movl (%rsp), %edi
+ callq __pthread_disable_asynccancel
+.LcleanupEND2:
+
+ /* Lock. */
+ movq 8(%rsp), %rdi
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+# if cond_lock == 0
+ cmpxchgl %esi, (%rdi)
+# else
+ cmpxchgl %esi, cond_lock(%rdi)
+# endif
+ jne 5f
+
+6: movl broadcast_seq(%rdi), %edx
+
+ movq woken_seq(%rdi), %rax
+
+ movq wakeup_seq(%rdi), %r9
+
+ cmpl 4(%rsp), %edx
+ jne 53b
+
+ cmpq 24(%rsp), %r9
+ jbe 15f
+
+ cmpq %rax, %r9
+ ja 39b
+
+15: cmpq $-ETIMEDOUT, %r14
+ jne 8b
+
+ jmp 99b
+
+ /* Initial locking failed. */
+1:
+# if cond_lock != 0
+ addq $cond_lock, %rdi
+# endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_lock_wait
+ jmp 2b
+
+ /* Unlock in loop requires wakeup. */
+3:
+# if cond_lock != 0
+ addq $cond_lock, %rdi
+# endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_unlock_wake
+ jmp 4b
+
+ /* Locking in loop failed. */
+5:
+# if cond_lock != 0
+ addq $cond_lock, %rdi
+# endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_lock_wait
+# if cond_lock != 0
+ subq $cond_lock, %rdi
+# endif
+ jmp 6b
+
+# if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS
+ /* clock_gettime not available. */
+19: leaq 32(%rsp), %rdi
+ xorl %esi, %esi
+ movq $VSYSCALL_ADDR_vgettimeofday, %rax
+ callq *%rax
+
+ /* Compute relative timeout. */
+ movq 40(%rsp), %rax
+ movl $1000, %edx
+ mul %rdx /* Milli seconds to nano seconds. */
+ movq (%r13), %rcx
+ movq 8(%r13), %rdx
+ subq 32(%rsp), %rcx
+ subq %rax, %rdx
+ jns 20f
+ addq $1000000000, %rdx
+ decq %rcx
+20: testq %rcx, %rcx
+ movq 8(%rsp), %rdi
+ movq $-ETIMEDOUT, %r14
+ js 6b
+ jmp 21b
+# endif
+#endif
+ .size __pthread_cond_timedwait, .-__pthread_cond_timedwait
+weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait)
+
+
+ .align 16
+ .type __condvar_cleanup2, @function
+__condvar_cleanup2:
+ /* Stack frame:
+
+ rsp + 72
+ +--------------------------+
+ rsp + 64 | %r12 |
+ +--------------------------+
+ rsp + 56 | %r13 |
+ +--------------------------+
+ rsp + 48 | %r14 |
+ +--------------------------+
+ rsp + 24 | unused |
+ +--------------------------+
+ rsp + 16 | mutex pointer |
+ +--------------------------+
+ rsp + 8 | condvar pointer |
+ +--------------------------+
+ rsp + 4 | old broadcast_seq value |
+ +--------------------------+
+ rsp + 0 | old cancellation mode |
+ +--------------------------+
+ */
+
+ movq %rax, 24(%rsp)
+
+ /* Get internal lock. */
+ movq 8(%rsp), %rdi
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, cond_lock(%rdi)
+#endif
+ jz 1f
+
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_lock_wait
+#if cond_lock != 0
+ subq $cond_lock, %rdi
+#endif
+
+1: movl broadcast_seq(%rdi), %edx
+ cmpl 4(%rsp), %edx
+ jne 3f
+
+ /* We increment the wakeup_seq counter only if it is lower than
+ total_seq. If this is not the case the thread was woken and
+ then canceled. In this case we ignore the signal. */
+ movq total_seq(%rdi), %rax
+ cmpq wakeup_seq(%rdi), %rax
+ jbe 6f
+ incq wakeup_seq(%rdi)
+ incl cond_futex(%rdi)
+6: incq woken_seq(%rdi)
+
+3: subl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ xorq %r12, %r12
+ cmpq $0xffffffffffffffff, total_seq(%rdi)
+ jne 4f
+ movl cond_nwaiters(%rdi), %eax
+ andl $~((1 << nwaiters_shift) - 1), %eax
+ jne 4f
+
+ cmpq $-1, dep_mutex(%rdi)
+ leaq cond_nwaiters(%rdi), %rdi
+ movl $1, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE, %eax
+ movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+#else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+ orl $FUTEX_WAKE, %esi
+#endif
+ movl $SYS_futex, %eax
+ syscall
+ subq $cond_nwaiters, %rdi
+ movl $1, %r12d
+
+4: LOCK
+#if cond_lock == 0
+ decl (%rdi)
+#else
+ decl cond_lock(%rdi)
+#endif
+ je 2f
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_unlock_wake
+
+ /* Wake up all waiters to make sure no signal gets lost. */
+2: testq %r12, %r12
+ jnz 5f
+ addq $cond_futex, %rdi
+ cmpq $-1, dep_mutex-cond_futex(%rdi)
+ movl $0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE, %eax
+ movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+#else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+ orl $FUTEX_WAKE, %esi
+#endif
+ movl $SYS_futex, %eax
+ syscall
+
+5: movq 16(%rsp), %rdi
+ callq __pthread_mutex_cond_lock
+
+ movq 24(%rsp), %rdi
+ movq FRAME_SIZE(%rsp), %r15
+ movq FRAME_SIZE+8(%rsp), %r14
+ movq FRAME_SIZE+16(%rsp), %r13
+ movq FRAME_SIZE+24(%rsp), %r12
+.LcallUR:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE:
+ cfi_endproc
+ .size __condvar_cleanup2, .-__condvar_cleanup2
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte DW_EH_PE_omit # @LPStart format
+ .byte DW_EH_PE_omit # @TType format
+ .byte DW_EH_PE_uleb128 # call-site format
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART1-.LSTARTCODE
+ .uleb128 .LcleanupEND1-.LcleanupSTART1
+ .uleb128 __condvar_cleanup2-.LSTARTCODE
+ .uleb128 0
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+ .uleb128 .LcleanupSTART2-.LSTARTCODE
+ .uleb128 .LcleanupEND2-.LcleanupSTART2
+ .uleb128 __condvar_cleanup2-.LSTARTCODE
+ .uleb128 0
+#endif
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 8
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 8
+DW.ref.__gcc_personality_v0:
+ .quad __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
new file mode 100644
index 000000000..cc67ed9de
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
@@ -0,0 +1,487 @@
+/* Copyright (C) 2002-2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelcond.h>
+#include <tcb-offsets.h>
+#include <pthread-pi-defines.h>
+
+#include <bits/kernel-features.h>
+
+
+ .text
+
+/* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
+ .globl __pthread_cond_wait
+ .type __pthread_cond_wait, @function
+ .protected __pthread_cond_wait
+ .align 16
+__pthread_cond_wait:
+.LSTARTCODE:
+ cfi_startproc
+
+#define FRAME_SIZE 32
+ leaq -FRAME_SIZE(%rsp), %rsp
+ cfi_adjust_cfa_offset(FRAME_SIZE)
+
+ /* Stack frame:
+
+ rsp + 32
+ +--------------------------+
+ rsp + 24 | old wake_seq value |
+ +--------------------------+
+ rsp + 16 | mutex pointer |
+ +--------------------------+
+ rsp + 8 | condvar pointer |
+ +--------------------------+
+ rsp + 4 | old broadcast_seq value |
+ +--------------------------+
+ rsp + 0 | old cancellation mode |
+ +--------------------------+
+ */
+
+ cmpq $-1, dep_mutex(%rdi)
+
+ /* Prepare structure passed to cancellation handler. */
+ movq %rdi, 8(%rsp)
+ movq %rsi, 16(%rsp)
+
+ je 15f
+ movq %rsi, dep_mutex(%rdi)
+
+ /* Get internal lock. */
+15: movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, cond_lock(%rdi)
+#endif
+ jne 1f
+
+ /* Unlock the mutex. */
+2: movq 16(%rsp), %rdi
+ xorl %esi, %esi
+ callq __pthread_mutex_unlock_usercnt
+
+ testl %eax, %eax
+ jne 12f
+
+ movq 8(%rsp), %rdi
+ incq total_seq(%rdi)
+ incl cond_futex(%rdi)
+ addl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
+
+ /* Get and store current wakeup_seq value. */
+ movq 8(%rsp), %rdi
+ movq wakeup_seq(%rdi), %r9
+ movl broadcast_seq(%rdi), %edx
+ movq %r9, 24(%rsp)
+ movl %edx, 4(%rsp)
+
+ /* Unlock. */
+8: movl cond_futex(%rdi), %edx
+ LOCK
+#if cond_lock == 0
+ decl (%rdi)
+#else
+ decl cond_lock(%rdi)
+#endif
+ jne 3f
+
+.LcleanupSTART:
+4: callq __pthread_enable_asynccancel
+ movl %eax, (%rsp)
+
+ xorq %r10, %r10
+ cmpq $-1, dep_mutex(%rdi)
+ leaq cond_futex(%rdi), %rdi
+ movl $FUTEX_WAIT, %esi
+ je 60f
+
+ movq dep_mutex-cond_futex(%rdi), %r8
+ /* Requeue to a non-robust PI mutex if the PI bit is set and
+ the robust bit is not set. */
+ movl MUTEX_KIND(%r8), %eax
+ andl $(ROBUST_BIT|PI_BIT), %eax
+ cmpl $PI_BIT, %eax
+ jne 61f
+
+ movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
+ movl $SYS_futex, %eax
+ syscall
+
+ movl $1, %r8d
+#ifdef __ASSUME_REQUEUE_PI
+ jmp 62f
+#else
+ cmpq $-4095, %rax
+ jnae 62f
+
+# ifndef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAIT, %esi
+# endif
+#endif
+
+61:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), %esi
+#else
+ orl %fs:PRIVATE_FUTEX, %esi
+#endif
+60: xorl %r8d, %r8d
+ movl $SYS_futex, %eax
+ syscall
+
+62: movl (%rsp), %edi
+ callq __pthread_disable_asynccancel
+.LcleanupEND:
+
+ /* Lock. */
+ movq 8(%rsp), %rdi
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, cond_lock(%rdi)
+#endif
+ jnz 5f
+
+6: movl broadcast_seq(%rdi), %edx
+
+ movq woken_seq(%rdi), %rax
+
+ movq wakeup_seq(%rdi), %r9
+
+ cmpl 4(%rsp), %edx
+ jne 16f
+
+ cmpq 24(%rsp), %r9
+ jbe 8b
+
+ cmpq %rax, %r9
+ jna 8b
+
+ incq woken_seq(%rdi)
+
+ /* Unlock */
+16: subl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ cmpq $0xffffffffffffffff, total_seq(%rdi)
+ jne 17f
+ movl cond_nwaiters(%rdi), %eax
+ andl $~((1 << nwaiters_shift) - 1), %eax
+ jne 17f
+
+ addq $cond_nwaiters, %rdi
+ cmpq $-1, dep_mutex-cond_nwaiters(%rdi)
+ movl $1, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE, %eax
+ movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+#else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+ orl $FUTEX_WAKE, %esi
+#endif
+ movl $SYS_futex, %eax
+ syscall
+ subq $cond_nwaiters, %rdi
+
+17: LOCK
+#if cond_lock == 0
+ decl (%rdi)
+#else
+ decl cond_lock(%rdi)
+#endif
+ jne 10f
+
+ /* If requeue_pi is used the kernel performs the locking of the
+ mutex. */
+11: movq 16(%rsp), %rdi
+ testl %r8d, %r8d
+ jnz 18f
+
+ callq __pthread_mutex_cond_lock
+
+14: leaq FRAME_SIZE(%rsp), %rsp
+ cfi_adjust_cfa_offset(-FRAME_SIZE)
+
+ /* We return the result of the mutex_lock operation. */
+ retq
+
+ cfi_adjust_cfa_offset(FRAME_SIZE)
+
+18: callq __pthread_mutex_cond_lock_adjust
+ xorl %eax, %eax
+ jmp 14b
+
+ /* Initial locking failed. */
+1:
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_lock_wait
+ jmp 2b
+
+ /* Unlock in loop requires wakeup. */
+3:
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ /* The call preserves %rdx. */
+ callq __lll_unlock_wake
+#if cond_lock != 0
+ subq $cond_lock, %rdi
+#endif
+ jmp 4b
+
+ /* Locking in loop failed. */
+5:
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_lock_wait
+#if cond_lock != 0
+ subq $cond_lock, %rdi
+#endif
+ jmp 6b
+
+ /* Unlock after loop requires wakeup. */
+10:
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_unlock_wake
+ jmp 11b
+
+ /* The initial unlocking of the mutex failed. */
+12: movq %rax, %r10
+ movq 8(%rsp), %rdi
+ LOCK
+#if cond_lock == 0
+ decl (%rdi)
+#else
+ decl cond_lock(%rdi)
+#endif
+ je 13f
+
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_unlock_wake
+
+13: movq %r10, %rax
+ jmp 14b
+ .size __pthread_cond_wait, .-__pthread_cond_wait
+weak_alias(__pthread_cond_wait, pthread_cond_wait)
+
+
+ .align 16
+ .type __condvar_cleanup1, @function
+ .globl __condvar_cleanup1
+ .hidden __condvar_cleanup1
+__condvar_cleanup1:
+ /* Stack frame:
+
+ rsp + 32
+ +--------------------------+
+ rsp + 24 | unused |
+ +--------------------------+
+ rsp + 16 | mutex pointer |
+ +--------------------------+
+ rsp + 8 | condvar pointer |
+ +--------------------------+
+ rsp + 4 | old broadcast_seq value |
+ +--------------------------+
+ rsp + 0 | old cancellation mode |
+ +--------------------------+
+ */
+
+ movq %rax, 24(%rsp)
+
+ /* Get internal lock. */
+ movq 8(%rsp), %rdi
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if cond_lock == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, cond_lock(%rdi)
+#endif
+ jz 1f
+
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ callq __lll_lock_wait
+#if cond_lock != 0
+ subq $cond_lock, %rdi
+#endif
+
+1: movl broadcast_seq(%rdi), %edx
+ cmpl 4(%rsp), %edx
+ jne 3f
+
+ /* We increment the wakeup_seq counter only if it is lower than
+ total_seq. If this is not the case the thread was woken and
+ then canceled. In this case we ignore the signal. */
+ movq total_seq(%rdi), %rax
+ cmpq wakeup_seq(%rdi), %rax
+ jbe 6f
+ incq wakeup_seq(%rdi)
+ incl cond_futex(%rdi)
+6: incq woken_seq(%rdi)
+
+3: subl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
+
+ /* Wake up a thread which wants to destroy the condvar object. */
+ xorl %ecx, %ecx
+ cmpq $0xffffffffffffffff, total_seq(%rdi)
+ jne 4f
+ movl cond_nwaiters(%rdi), %eax
+ andl $~((1 << nwaiters_shift) - 1), %eax
+ jne 4f
+
+ cmpq $-1, dep_mutex(%rdi)
+ leaq cond_nwaiters(%rdi), %rdi
+ movl $1, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE, %eax
+ movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+#else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+ orl $FUTEX_WAKE, %esi
+#endif
+ movl $SYS_futex, %eax
+ syscall
+ subq $cond_nwaiters, %rdi
+ movl $1, %ecx
+
+4: LOCK
+#if cond_lock == 0
+ decl (%rdi)
+#else
+ decl cond_lock(%rdi)
+#endif
+ je 2f
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
+ movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
+ /* The call preserves %rcx. */
+ callq __lll_unlock_wake
+
+ /* Wake up all waiters to make sure no signal gets lost. */
+2: testl %ecx, %ecx
+ jnz 5f
+ addq $cond_futex, %rdi
+ cmpq $-1, dep_mutex-cond_futex(%rdi)
+ movl $0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE, %eax
+ movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+#else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+ orl $FUTEX_WAKE, %esi
+#endif
+ movl $SYS_futex, %eax
+ syscall
+
+5: movq 16(%rsp), %rdi
+ callq __pthread_mutex_cond_lock
+
+ movq 24(%rsp), %rdi
+.LcallUR:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE:
+ cfi_endproc
+ .size __condvar_cleanup1, .-__condvar_cleanup1
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte DW_EH_PE_omit # @LPStart format
+ .byte DW_EH_PE_omit # @TType format
+ .byte DW_EH_PE_uleb128 # call-site format
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 __condvar_cleanup1-.LSTARTCODE
+ .uleb128 0
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 8
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 8
+DW.ref.__gcc_personality_v0:
+ .quad __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
new file mode 100644
index 000000000..9013d8fa0
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
@@ -0,0 +1,190 @@
+/* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+#include <lowlevellock.h>
+
+
+ .comm __fork_generation, 4, 4
+
+ .text
+
+
+ .globl __pthread_once
+ .type __pthread_once,@function
+ .protected __pthread_once
+ .align 16
+__pthread_once:
+.LSTARTCODE:
+ cfi_startproc
+ testl $2, (%rdi)
+ jz 1f
+ xorl %eax, %eax
+ retq
+
+ /* Preserve the function pointer. */
+1: pushq %rsi
+ cfi_adjust_cfa_offset(8)
+ xorq %r10, %r10
+
+ /* Not yet initialized or initialization in progress.
+ Get the fork generation counter now. */
+6: movl (%rdi), %eax
+
+5: movl %eax, %edx
+
+ testl $2, %eax
+ jnz 4f
+
+ andl $3, %edx
+ orl __fork_generation(%rip), %edx
+ orl $1, %edx
+
+ LOCK
+ cmpxchgl %edx, (%rdi)
+ jnz 5b
+
+ /* Check whether another thread already runs the initializer. */
+ testl $1, %eax
+ jz 3f /* No -> do it. */
+
+ /* Check whether the initializer execution was interrupted
+ by a fork. */
+ xorl %edx, %eax
+ testl $0xfffffffc, %eax
+ jnz 3f /* Different for generation -> run initializer. */
+
+ /* Somebody else got here first. Wait. */
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAIT|FUTEX_PRIVATE_FLAG, %esi
+#else
+# if FUTEX_WAIT == 0
+ movl %fs:PRIVATE_FUTEX, %esi
+# else
+ movl $FUTEX_WAIT, %esi
+ orl %fs:PRIVATE_FUTEX, %esi
+# endif
+#endif
+ movl $SYS_futex, %eax
+ syscall
+ jmp 6b
+
+ /* Preserve the pointer to the control variable. */
+3: pushq %rdi
+ cfi_adjust_cfa_offset(8)
+ pushq %rdi
+ cfi_adjust_cfa_offset(8)
+
+.LcleanupSTART:
+ callq *16(%rsp)
+.LcleanupEND:
+
+ /* Get the control variable address back. */
+ popq %rdi
+ cfi_adjust_cfa_offset(-8)
+
+ /* Sucessful run of the initializer. Signal that we are done. */
+ LOCK
+ incl (%rdi)
+
+ addq $8, %rsp
+ cfi_adjust_cfa_offset(-8)
+
+ /* Wake up all other threads. */
+ movl $0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %esi
+#else
+ movl $FUTEX_WAKE, %esi
+ orl %fs:PRIVATE_FUTEX, %esi
+#endif
+ movl $SYS_futex, %eax
+ syscall
+
+4: addq $8, %rsp
+ cfi_adjust_cfa_offset(-8)
+ xorl %eax, %eax
+ retq
+ .size __pthread_once,.-__pthread_once
+
+
+ .globl __pthread_once_internal
+__pthread_once_internal = __pthread_once
+
+ .globl pthread_once
+pthread_once = __pthread_once
+
+
+ .type clear_once_control,@function
+ .align 16
+clear_once_control:
+ cfi_adjust_cfa_offset(3 * 8)
+ movq (%rsp), %rdi
+ movq %rax, %r8
+ movl $0, (%rdi)
+
+ movl $0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %esi
+#else
+ movl $FUTEX_WAKE, %esi
+ orl %fs:PRIVATE_FUTEX, %esi
+#endif
+ movl $SYS_futex, %eax
+ syscall
+
+ movq %r8, %rdi
+.LcallUR:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE:
+ cfi_endproc
+ .size clear_once_control,.-clear_once_control
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte DW_EH_PE_omit # @LPStart format
+ .byte DW_EH_PE_omit # @TType format
+ .byte DW_EH_PE_uleb128 # call-site format
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 clear_once_control-.LSTARTCODE
+ .uleb128 0
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 8
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 8
+DW.ref.__gcc_personality_v0:
+ .quad __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
new file mode 100644
index 000000000..82badb1ee
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
@@ -0,0 +1,180 @@
+/* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+
+
+ .text
+
+ .globl __pthread_rwlock_rdlock
+ .type __pthread_rwlock_rdlock,@function
+ .protected __pthread_rwlock_rdlock
+ .align 16
+__pthread_rwlock_rdlock:
+ cfi_startproc
+ xorq %r10, %r10
+
+ /* Get the lock. */
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, MUTEX(%rdi)
+#endif
+ jnz 1f
+
+2: movl WRITER(%rdi), %eax
+ testl %eax, %eax
+ jne 14f
+ cmpl $0, WRITERS_QUEUED(%rdi)
+ je 5f
+ cmpl $0, FLAGS(%rdi)
+ je 5f
+
+3: incl READERS_QUEUED(%rdi)
+ je 4f
+
+ movl READERS_WAKEUP(%rdi), %edx
+
+ LOCK
+#if MUTEX == 0
+ decl (%rdi)
+#else
+ decl MUTEX(%rdi)
+#endif
+ jne 10f
+
+11:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
+ xorl PSHARED(%rdi), %esi
+#else
+# if FUTEX_WAIT == 0
+ movl PSHARED(%rdi), %esi
+# else
+ movl $FUTEX_WAIT, %esi
+ orl PSHARED(%rdi), %esi
+# endif
+ xorl %fs:PRIVATE_FUTEX, %esi
+#endif
+ addq $READERS_WAKEUP, %rdi
+ movl $SYS_futex, %eax
+ syscall
+
+ subq $READERS_WAKEUP, %rdi
+
+ /* Reget the lock. */
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, MUTEX(%rdi)
+#endif
+ jnz 12f
+
+13: decl READERS_QUEUED(%rdi)
+ jmp 2b
+
+5: xorl %edx, %edx
+ incl NR_READERS(%rdi)
+ je 8f
+9: LOCK
+#if MUTEX == 0
+ decl (%rdi)
+#else
+ decl MUTEX(%rdi)
+#endif
+ jne 6f
+7:
+
+ movq %rdx, %rax
+ retq
+
+1: movl PSHARED(%rdi), %esi
+#if MUTEX != 0
+ addq $MUTEX, %rdi
+#endif
+ callq __lll_lock_wait
+#if MUTEX != 0
+ subq $MUTEX, %rdi
+#endif
+ jmp 2b
+
+14: cmpl %fs:TID, %eax
+ jne 3b
+ /* Deadlock detected. */
+ movl $EDEADLK, %edx
+ jmp 9b
+
+6: movl PSHARED(%rdi), %esi
+#if MUTEX != 0
+ addq $MUTEX, %rdi
+#endif
+ callq __lll_unlock_wake
+#if MUTEX != 0
+ subq $MUTEX, %rdi
+#endif
+ jmp 7b
+
+ /* Overflow. */
+8: decl NR_READERS(%rdi)
+ movl $EAGAIN, %edx
+ jmp 9b
+
+ /* Overflow. */
+4: decl READERS_QUEUED(%rdi)
+ movl $EAGAIN, %edx
+ jmp 9b
+
+10: movl PSHARED(%rdi), %esi
+#if MUTEX != 0
+ addq $MUTEX, %rdi
+#endif
+ callq __lll_unlock_wake
+#if MUTEX != 0
+ subq $MUTEX, %rdi
+#endif
+ jmp 11b
+
+12: movl PSHARED(%rdi), %esi
+#if MUTEX == 0
+ addq $MUTEX, %rdi
+#endif
+ callq __lll_lock_wait
+#if MUTEX != 0
+ subq $MUTEX, %rdi
+#endif
+ jmp 13b
+ cfi_endproc
+ .size __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
+
+ .globl pthread_rwlock_rdlock
+pthread_rwlock_rdlock = __pthread_rwlock_rdlock
+
+ .globl __pthread_rwlock_rdlock_internal
+__pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
new file mode 100644
index 000000000..3629ffbe5
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
@@ -0,0 +1,276 @@
+/* Copyright (C) 2002-2005, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+
+
+/* For the calculation see asm/vsyscall.h. */
+#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
+
+ .text
+
+ .globl pthread_rwlock_timedrdlock
+ .type pthread_rwlock_timedrdlock,@function
+ .align 16
+pthread_rwlock_timedrdlock:
+ cfi_startproc
+ pushq %r12
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r12, 0)
+ pushq %r13
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r13, 0)
+#ifdef __ASSUME_FUTEX_CLOCK_REALTIME
+# define VALREG %edx
+#else
+ pushq %r14
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r14, 0)
+
+ subq $16, %rsp
+ cfi_adjust_cfa_offset(16)
+# define VALREG %r14d
+#endif
+
+ movq %rdi, %r12
+ movq %rsi, %r13
+
+ /* Get the lock. */
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, MUTEX(%rdi)
+#endif
+ jnz 1f
+
+2: movl WRITER(%r12), %eax
+ testl %eax, %eax
+ jne 14f
+ cmpl $0, WRITERS_QUEUED(%r12)
+ je 5f
+ cmpl $0, FLAGS(%r12)
+ je 5f
+
+ /* Check the value of the timeout parameter. */
+3: cmpq $1000000000, 8(%r13)
+ jae 19f
+
+ incl READERS_QUEUED(%r12)
+ je 4f
+
+ movl READERS_WAKEUP(%r12), VALREG
+
+ /* Unlock. */
+ LOCK
+#if MUTEX == 0
+ decl (%r12)
+#else
+ decl MUTEX(%r12)
+#endif
+ jne 10f
+
+11:
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+# ifdef __PIC__
+ cmpl $0, __have_futex_clock_realtime(%rip)
+# else
+ cmpl $0, __have_futex_clock_realtime
+# endif
+ je .Lreltmo
+#endif
+
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %esi
+ xorl PSHARED(%r12), %esi
+ movq %r13, %r10
+ movl $0xffffffff, %r9d
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+ movl %r14d, %edx
+#endif
+21: leaq READERS_WAKEUP(%r12), %rdi
+ movl $SYS_futex, %eax
+ syscall
+ movq %rax, %rdx
+
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+ .subsection 2
+.Lreltmo:
+ /* Get current time. */
+ movq %rsp, %rdi
+ xorl %esi, %esi
+ movq $VSYSCALL_ADDR_vgettimeofday, %rax
+ callq *%rax
+
+ /* Compute relative timeout. */
+ movq 8(%rsp), %rax
+ movl $1000, %edi
+ mul %rdi /* Milli seconds to nano seconds. */
+ movq (%r13), %rcx
+ movq 8(%r13), %rdi
+ subq (%rsp), %rcx
+ subq %rax, %rdi
+ jns 15f
+ addq $1000000000, %rdi
+ decq %rcx
+15: testq %rcx, %rcx
+ js 16f /* Time is already up. */
+
+ /* Futex call. */
+ movq %rcx, (%rsp) /* Store relative timeout. */
+ movq %rdi, 8(%rsp)
+
+# ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
+ xorl PSHARED(%r12), %esi
+# else
+# if FUTEX_WAIT == 0
+ movl PSHARED(%r12), %esi
+# else
+ movl $FUTEX_WAIT, %esi
+ orl PSHARED(%r12), %esi
+# endif
+ xorl %fs:PRIVATE_FUTEX, %esi
+# endif
+ movq %rsp, %r10
+ movl %r14d, %edx
+
+ jmp 21b
+ .previous
+#endif
+
+17: /* Reget the lock. */
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %esi, (%r12)
+#else
+ cmpxchgl %esi, MUTEX(%r12)
+#endif
+ jnz 12f
+
+13: decl READERS_QUEUED(%r12)
+ cmpq $-ETIMEDOUT, %rdx
+ jne 2b
+
+18: movl $ETIMEDOUT, %edx
+ jmp 9f
+
+
+5: xorl %edx, %edx
+ incl NR_READERS(%r12)
+ je 8f
+9: LOCK
+#if MUTEX == 0
+ decl (%r12)
+#else
+ decl MUTEX(%r12)
+#endif
+ jne 6f
+
+7: movq %rdx, %rax
+
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+ addq $16, %rsp
+ cfi_adjust_cfa_offset(-16)
+ popq %r14
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r14)
+#endif
+ popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r13)
+ popq %r12
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r12)
+ retq
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+ cfi_adjust_cfa_offset(16)
+ cfi_rel_offset(%r12, 8)
+ cfi_rel_offset(%r13, 0)
+#else
+ cfi_adjust_cfa_offset(40)
+ cfi_offset(%r12, -16)
+ cfi_offset(%r13, -24)
+ cfi_offset(%r14, -32)
+#endif
+1: movl PSHARED(%rdi), %esi
+#if MUTEX != 0
+ addq $MUTEX, %rdi
+#endif
+ callq __lll_lock_wait
+ jmp 2b
+
+14: cmpl %fs:TID, %eax
+ jne 3b
+ movl $EDEADLK, %edx
+ jmp 9b
+
+6: movl PSHARED(%r12), %esi
+#if MUTEX == 0
+ movq %r12, %rdi
+#else
+ leal MUTEX(%r12), %rdi
+#endif
+ callq __lll_unlock_wake
+ jmp 7b
+
+ /* Overflow. */
+8: decl NR_READERS(%r12)
+ movl $EAGAIN, %edx
+ jmp 9b
+
+ /* Overflow. */
+4: decl READERS_QUEUED(%r12)
+ movl $EAGAIN, %edx
+ jmp 9b
+
+10: movl PSHARED(%r12), %esi
+#if MUTEX == 0
+ movq %r12, %rdi
+#else
+ leaq MUTEX(%r12), %rdi
+#endif
+ callq __lll_unlock_wake
+ jmp 11b
+
+12: movl PSHARED(%r12), %esi
+#if MUTEX == 0
+ movq %r12, %rdi
+#else
+ leaq MUTEX(%r12), %rdi
+#endif
+ callq __lll_lock_wait
+ jmp 13b
+
+16: movq $-ETIMEDOUT, %rdx
+ jmp 17b
+
+19: movl $EINVAL, %edx
+ jmp 9b
+ cfi_endproc
+ .size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
new file mode 100644
index 000000000..23e1ee155
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
@@ -0,0 +1,268 @@
+/* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+
+
+/* For the calculation see asm/vsyscall.h. */
+#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
+
+ .text
+
+ .globl pthread_rwlock_timedwrlock
+ .type pthread_rwlock_timedwrlock,@function
+ .align 16
+pthread_rwlock_timedwrlock:
+ cfi_startproc
+ pushq %r12
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r12, 0)
+ pushq %r13
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r13, 0)
+#ifdef __ASSUME_FUTEX_CLOCK_REALTIME
+# define VALREG %edx
+#else
+ pushq %r14
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r14, 0)
+
+ subq $16, %rsp
+ cfi_adjust_cfa_offset(16)
+# define VALREG %r14d
+#endif
+
+ movq %rdi, %r12
+ movq %rsi, %r13
+
+ /* Get the lock. */
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, MUTEX(%rdi)
+#endif
+ jnz 1f
+
+2: movl WRITER(%r12), %eax
+ testl %eax, %eax
+ jne 14f
+ cmpl $0, NR_READERS(%r12)
+ je 5f
+
+ /* Check the value of the timeout parameter. */
+3: cmpq $1000000000, 8(%r13)
+ jae 19f
+
+ incl WRITERS_QUEUED(%r12)
+ je 4f
+
+ movl WRITERS_WAKEUP(%r12), VALREG
+
+ LOCK
+#if MUTEX == 0
+ decl (%r12)
+#else
+ decl MUTEX(%r12)
+#endif
+ jne 10f
+
+11:
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+# ifdef __PIC__
+ cmpl $0, __have_futex_clock_realtime(%rip)
+# else
+ cmpl $0, __have_futex_clock_realtime
+# endif
+ je .Lreltmo
+#endif
+
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %esi
+ xorl PSHARED(%r12), %esi
+ movq %r13, %r10
+ movl $0xffffffff, %r9d
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+ movl %r14d, %edx
+#endif
+21: leaq WRITERS_WAKEUP(%r12), %rdi
+ movl $SYS_futex, %eax
+ syscall
+ movq %rax, %rdx
+
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+ .subsection 2
+.Lreltmo:
+ /* Get current time. */
+ movq %rsp, %rdi
+ xorl %esi, %esi
+ movq $VSYSCALL_ADDR_vgettimeofday, %rax
+ callq *%rax
+
+ /* Compute relative timeout. */
+ movq 8(%rsp), %rax
+ movl $1000, %edi
+ mul %rdi /* Milli seconds to nano seconds. */
+ movq (%r13), %rcx
+ movq 8(%r13), %rdi
+ subq (%rsp), %rcx
+ subq %rax, %rdi
+ jns 15f
+ addq $1000000000, %rdi
+ decq %rcx
+15: testq %rcx, %rcx
+ js 16f /* Time is already up. */
+
+ /* Futex call. */
+ movq %rcx, (%rsp) /* Store relative timeout. */
+ movq %rdi, 8(%rsp)
+
+# ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
+ xorl PSHARED(%r12), %esi
+# else
+# if FUTEX_WAIT == 0
+ movl PSHARED(%r12), %esi
+# else
+ movl $FUTEX_WAIT, %esi
+ orl PSHARED(%r12), %esi
+# endif
+ xorl %fs:PRIVATE_FUTEX, %esi
+# endif
+ movq %rsp, %r10
+ movl %r14d, %edx
+
+ jmp 21b
+ .previous
+#endif
+
+17: /* Reget the lock. */
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %esi, (%r12)
+#else
+ cmpxchgl %esi, MUTEX(%r12)
+#endif
+ jnz 12f
+
+13: decl WRITERS_QUEUED(%r12)
+ cmpq $-ETIMEDOUT, %rdx
+ jne 2b
+
+18: movl $ETIMEDOUT, %edx
+ jmp 9f
+
+
+5: xorl %edx, %edx
+ movl %fs:TID, %eax
+ movl %eax, WRITER(%r12)
+9: LOCK
+#if MUTEX == 0
+ decl (%r12)
+#else
+ decl MUTEX(%r12)
+#endif
+ jne 6f
+
+7: movq %rdx, %rax
+
+#ifndef __ASSUME_PRIVATE_FUTEX
+ addq $16, %rsp
+ cfi_adjust_cfa_offset(-16)
+ popq %r14
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r14)
+#endif
+ popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r13)
+ popq %r12
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r12)
+ retq
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+ cfi_adjust_cfa_offset(16)
+ cfi_rel_offset(%r12, 8)
+ cfi_rel_offset(%r13, 0)
+#else
+ cfi_adjust_cfa_offset(40)
+ cfi_offset(%r12, -16)
+ cfi_offset(%r13, -24)
+ cfi_offset(%r14, -32)
+#endif
+1: movl PSHARED(%rdi), %esi
+#if MUTEX != 0
+ addq $MUTEX, %rdi
+#endif
+ callq __lll_lock_wait
+ jmp 2b
+
+14: cmpl %fs:TID, %eax
+ jne 3b
+20: movl $EDEADLK, %edx
+ jmp 9b
+
+6: movl PSHARED(%r12), %esi
+#if MUTEX == 0
+ movq %r12, %rdi
+#else
+ leal MUTEX(%r12), %rdi
+#endif
+ callq __lll_unlock_wake
+ jmp 7b
+
+ /* Overflow. */
+4: decl WRITERS_QUEUED(%r12)
+ movl $EAGAIN, %edx
+ jmp 9b
+
+10: movl PSHARED(%r12), %esi
+#if MUTEX == 0
+ movq %r12, %rdi
+#else
+ leaq MUTEX(%r12), %rdi
+#endif
+ callq __lll_unlock_wake
+ jmp 11b
+
+12: movl PSHARED(%r12), %esi
+#if MUTEX == 0
+ movq %r12, %rdi
+#else
+ leaq MUTEX(%r12), %rdi
+#endif
+ callq __lll_lock_wait
+ jmp 13b
+
+16: movq $-ETIMEDOUT, %rdx
+ jmp 17b
+
+19: movl $EINVAL, %edx
+ jmp 9b
+ cfi_endproc
+ .size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
new file mode 100644
index 000000000..e34c42ea2
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
@@ -0,0 +1,131 @@
+/* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <bits/kernel-features.h>
+
+
+ .text
+
+ .globl __pthread_rwlock_unlock
+ .type __pthread_rwlock_unlock,@function
+ .protected __pthread_rwlock_unlock
+ .align 16
+__pthread_rwlock_unlock:
+ cfi_startproc
+ /* Get the lock. */
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, MUTEX(%rdi)
+#endif
+ jnz 1f
+
+2: cmpl $0, WRITER(%rdi)
+ jne 5f
+ decl NR_READERS(%rdi)
+ jnz 6f
+
+5: movl $0, WRITER(%rdi)
+
+ movl $1, %edx
+ leaq WRITERS_WAKEUP(%rdi), %r10
+ cmpl $0, WRITERS_QUEUED(%rdi)
+ jne 0f
+
+ /* If also no readers waiting nothing to do. */
+ cmpl $0, READERS_QUEUED(%rdi)
+ je 6f
+
+ movl $0x7fffffff, %edx
+ leaq READERS_WAKEUP(%rdi), %r10
+
+0: incl (%r10)
+ LOCK
+#if MUTEX == 0
+ decl (%rdi)
+#else
+ decl MUTEX(%rdi)
+#endif
+ jne 7f
+
+8:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %esi
+ xorl PSHARED(%rdi), %esi
+#else
+ movl $FUTEX_WAKE, %esi
+ orl PSHARED(%rdi), %esi
+ xorl %fs:PRIVATE_FUTEX, %esi
+#endif
+ movl $SYS_futex, %eax
+ movq %r10, %rdi
+ syscall
+
+ xorl %eax, %eax
+ retq
+
+ .align 16
+6: LOCK
+#if MUTEX == 0
+ decl (%rdi)
+#else
+ decl MUTEX(%rdi)
+#endif
+ jne 3f
+
+4: xorl %eax, %eax
+ retq
+
+1: movl PSHARED(%rdi), %esi
+#if MUTEX != 0
+ addq $MUTEX, %rdi
+#endif
+ callq __lll_lock_wait
+#if MUTEX != 0
+ subq $MUTEX, %rdi
+#endif
+ jmp 2b
+
+3: movl PSHARED(%rdi), %esi
+#if MUTEX != 0
+ addq $MUTEX, %rdi
+#endif
+ callq __lll_unlock_wake
+ jmp 4b
+
+7: movl PSHARED(%rdi), %esi
+#if MUTEX != 0
+ addq $MUTEX, %rdi
+#endif
+ callq __lll_unlock_wake
+ jmp 8b
+ cfi_endproc
+ .size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
+
+ .globl pthread_rwlock_unlock
+pthread_rwlock_unlock = __pthread_rwlock_unlock
+
+ .globl __pthread_rwlock_unlock_internal
+__pthread_rwlock_unlock_internal = __pthread_rwlock_unlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
new file mode 100644
index 000000000..c626d9e1a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
@@ -0,0 +1,168 @@
+/* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <lowlevelrwlock.h>
+#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
+
+
+ .text
+
+ .globl __pthread_rwlock_wrlock
+ .type __pthread_rwlock_wrlock,@function
+ .protected __pthread_rwlock_wrlock
+ .align 16
+__pthread_rwlock_wrlock:
+ cfi_startproc
+ xorq %r10, %r10
+
+ /* Get the lock. */
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, MUTEX(%rdi)
+#endif
+ jnz 1f
+
+2: movl WRITER(%rdi), %eax
+ testl %eax, %eax
+ jne 14f
+ cmpl $0, NR_READERS(%rdi)
+ je 5f
+
+3: incl WRITERS_QUEUED(%rdi)
+ je 4f
+
+ movl WRITERS_WAKEUP(%rdi), %edx
+
+ LOCK
+#if MUTEX == 0
+ decl (%rdi)
+#else
+ decl MUTEX(%rdi)
+#endif
+ jne 10f
+
+11:
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
+ xorl PSHARED(%rdi), %esi
+#else
+# if FUTEX_WAIT == 0
+ movl PSHARED(%rdi), %esi
+# else
+ movl $FUTEX_WAIT, %esi
+ orl PSHARED(%rdi), %esi
+# endif
+ xorl %fs:PRIVATE_FUTEX, %esi
+#endif
+ addq $WRITERS_WAKEUP, %rdi
+ movl $SYS_futex, %eax
+ syscall
+
+ subq $WRITERS_WAKEUP, %rdi
+
+ /* Reget the lock. */
+ movl $1, %esi
+ xorl %eax, %eax
+ LOCK
+#if MUTEX == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, MUTEX(%rdi)
+#endif
+ jnz 12f
+
+13: decl WRITERS_QUEUED(%rdi)
+ jmp 2b
+
+5: xorl %edx, %edx
+ movl %fs:TID, %eax
+ movl %eax, WRITER(%rdi)
+9: LOCK
+#if MUTEX == 0
+ decl (%rdi)
+#else
+ decl MUTEX(%rdi)
+#endif
+ jne 6f
+7:
+
+ movq %rdx, %rax
+ retq
+
+1: movl PSHARED(%rdi), %esi
+#if MUTEX != 0
+ addq $MUTEX, %rdi
+#endif
+ callq __lll_lock_wait
+#if MUTEX != 0
+ subq $MUTEX, %rdi
+#endif
+ jmp 2b
+
+14: cmpl %fs:TID, %eax
+ jne 3b
+ movl $EDEADLK, %edx
+ jmp 9b
+
+6: movl PSHARED(%rdi), %esi
+#if MUTEX != 0
+ addq $MUTEX, %rdi
+#endif
+ callq __lll_unlock_wake
+ jmp 7b
+
+4: decl WRITERS_QUEUED(%rdi)
+ movl $EAGAIN, %edx
+ jmp 9b
+
+10: movl PSHARED(%rdi), %esi
+#if MUTEX != 0
+ addq $MUTEX, %rdi
+#endif
+ callq __lll_unlock_wake
+#if MUTEX != 0
+ subq $MUTEX, %rdi
+#endif
+ jmp 11b
+
+12: movl PSHARED(%rdi), %esi
+#if MUTEX != 0
+ addq $MUTEX, %rdi
+#endif
+ callq __lll_lock_wait
+#if MUTEX != 0
+ subq $MUTEX, %rdi
+#endif
+ jmp 13b
+ cfi_endproc
+ .size __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock
+
+ .globl pthread_rwlock_wrlock
+pthread_rwlock_wrlock = __pthread_rwlock_wrlock
+
+ .globl __pthread_rwlock_wrlock_internal
+__pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c
new file mode 100644
index 000000000..640d3044f
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c
@@ -0,0 +1,14 @@
+#include <tls.h>
+
+#define RESET_VGETCPU_CACHE() \
+ do { \
+ asm volatile ("movl %0, %%fs:%P1\n\t" \
+ "movl %0, %%fs:%P2" \
+ : \
+ : "ir" (0), "i" (offsetof (struct pthread, \
+ header.vgetcpu_cache[0])), \
+ "i" (offsetof (struct pthread, \
+ header.vgetcpu_cache[1]))); \
+ } while (0)
+
+#include "../pthread_setaffinity.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_init.c b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_init.c
new file mode 100644
index 000000000..483de8cac
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_init.c
@@ -0,0 +1 @@
+#include <sysdeps/x86_64/pthread_spin_init.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_unlock.S
new file mode 100644
index 000000000..e8e2ba262
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_unlock.S
@@ -0,0 +1 @@
+#include <sysdeps/x86_64/pthread_spin_unlock.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
new file mode 100644
index 000000000..7af6524fe
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
@@ -0,0 +1,89 @@
+/* Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <pthread-errnos.h>
+#include <structsem.h>
+
+
+ .text
+
+ .globl sem_post
+ .type sem_post,@function
+ .align 16
+sem_post:
+#if VALUE == 0
+ movl (%rdi), %eax
+#else
+ movl VALUE(%rdi), %eax
+#endif
+0: cmpl $SEM_VALUE_MAX, %eax
+ je 3f
+ leal 1(%rax), %esi
+ LOCK
+#if VALUE == 0
+ cmpxchgl %esi, (%rdi)
+#else
+ cmpxchgl %esi, VALUE(%rdi)
+#endif
+ jnz 0b
+
+ cmpq $0, NWAITERS(%rdi)
+ je 2f
+
+ movl $SYS_futex, %eax
+ movl $FUTEX_WAKE, %esi
+ orl PRIVATE(%rdi), %esi
+ movl $1, %edx
+ syscall
+
+ testq %rax, %rax
+ js 1f
+
+2: xorl %eax, %eax
+ retq
+
+1:
+#if USE___THREAD
+ movl $EINVAL, %eax
+#else
+ callq __errno_location@plt
+ movl $EINVAL, %edx
+#endif
+ jmp 4f
+
+3:
+#if USE___THREAD
+ movl $EOVERFLOW, %eax
+#else
+ callq __errno_location@plt
+ movl $EOVERFLOW, %edx
+#endif
+
+4:
+#if USE___THREAD
+ movq errno@gottpoff(%rip), %rdx
+ movl %eax, %fs:(%rdx)
+#else
+ movl %edx, (%rax)
+#endif
+ orl $-1, %eax
+ retq
+ .size sem_post,.-sem_post
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
new file mode 100644
index 000000000..704a2223a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
@@ -0,0 +1,379 @@
+/* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <bits/kernel-features.h>
+#include <lowlevellock.h>
+#include <pthread-errnos.h>
+#include <structsem.h>
+
+
+/* For the calculation see asm/vsyscall.h. */
+#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
+
+ .text
+
+ .globl sem_timedwait
+ .type sem_timedwait,@function
+ .align 16
+sem_timedwait:
+.LSTARTCODE:
+ cfi_startproc
+#if VALUE == 0
+ movl (%rdi), %eax
+#else
+ movl VALUE(%rdi), %eax
+#endif
+2: testl %eax, %eax
+ je 1f
+
+ leaq -1(%rax), %rdx
+ LOCK
+#if VALUE == 0
+ cmpxchgl %edx, (%rdi)
+#else
+ cmpxchgl %edx, VALUE(%rdi)
+#endif
+ jne 2b
+
+ xorl %eax, %eax
+ retq
+
+ /* Check whether the timeout value is valid. */
+1: cmpq $1000000000, 8(%rsi)
+ jae 6f
+
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+# ifdef __PIC__
+ cmpl $0, __have_futex_clock_realtime(%rip)
+# else
+ cmpl $0, __have_futex_clock_realtime
+# endif
+ je .Lreltmo
+#endif
+
+ /* This push is only needed to store the sem_t pointer for the
+ exception handler. */
+ pushq %rdi
+ cfi_adjust_cfa_offset(8)
+
+ movq %rsi, %r10
+
+ LOCK
+ addq $1, NWAITERS(%rdi)
+
+.LcleanupSTART:
+13: call __pthread_enable_asynccancel
+ movl %eax, %r8d
+
+#if VALUE != 0
+ leaq VALUE(%rdi), %rdi
+#endif
+ movl $0xffffffff, %r9d
+ movl $FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %esi
+ orl PRIVATE(%rdi), %esi
+ movl $SYS_futex, %eax
+ xorl %edx, %edx
+ syscall
+ movq %rax, %r9
+#if VALUE != 0
+ leaq -VALUE(%rdi), %rdi
+#endif
+
+ xchgq %r8, %rdi
+ call __pthread_disable_asynccancel
+.LcleanupEND:
+ movq %r8, %rdi
+
+ testq %r9, %r9
+ je 11f
+ cmpq $-EWOULDBLOCK, %r9
+ jne 3f
+
+11:
+#if VALUE == 0
+ movl (%rdi), %eax
+#else
+ movl VALUE(%rdi), %eax
+#endif
+14: testl %eax, %eax
+ je 13b
+
+ leaq -1(%rax), %rcx
+ LOCK
+#if VALUE == 0
+ cmpxchgl %ecx, (%rdi)
+#else
+ cmpxchgl %ecx, VALUE(%rdi)
+#endif
+ jne 14b
+
+ xorl %eax, %eax
+
+15: LOCK
+ subq $1, NWAITERS(%rdi)
+
+ leaq 8(%rsp), %rsp
+ cfi_adjust_cfa_offset(-8)
+ retq
+
+ cfi_adjust_cfa_offset(8)
+3: negq %r9
+#if USE___THREAD
+ movq errno@gottpoff(%rip), %rdx
+ movl %r9d, %fs:(%rdx)
+#else
+ callq __errno_location@plt
+ movl %r9d, (%rax)
+#endif
+
+ orl $-1, %eax
+ jmp 15b
+
+ cfi_adjust_cfa_offset(-8)
+6:
+#if USE___THREAD
+ movq errno@gottpoff(%rip), %rdx
+ movl $EINVAL, %fs:(%rdx)
+#else
+ callq __errno_location@plt
+ movl $EINVAL, (%rax)
+#endif
+
+ orl $-1, %eax
+
+ retq
+
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+.Lreltmo:
+ pushq %r12
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r12, 0)
+ pushq %r13
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r13, 0)
+ pushq %r14
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r14, 0)
+
+#ifdef __ASSUME_FUTEX_CLOCK_REALTIME
+# define STACKFRAME 8
+#else
+# define STACKFRAME 24
+#endif
+ subq $STACKFRAME, %rsp
+ cfi_adjust_cfa_offset(STACKFRAME)
+
+ movq %rdi, %r12
+ movq %rsi, %r13
+
+ LOCK
+ addq $1, NWAITERS(%r12)
+
+7: xorl %esi, %esi
+ movq %rsp, %rdi
+ movq $VSYSCALL_ADDR_vgettimeofday, %rax
+ callq *%rax
+
+ /* Compute relative timeout. */
+ movq 8(%rsp), %rax
+ movl $1000, %edi
+ mul %rdi /* Milli seconds to nano seconds. */
+ movq (%r13), %rdi
+ movq 8(%r13), %rsi
+ subq (%rsp), %rdi
+ subq %rax, %rsi
+ jns 5f
+ addq $1000000000, %rsi
+ decq %rdi
+5: testq %rdi, %rdi
+ movl $ETIMEDOUT, %r14d
+ js 36f /* Time is already up. */
+
+ movq %rdi, (%rsp) /* Store relative timeout. */
+ movq %rsi, 8(%rsp)
+
+.LcleanupSTART2:
+ call __pthread_enable_asynccancel
+ movl %eax, 16(%rsp)
+
+ movq %rsp, %r10
+# if VALUE == 0
+ movq %r12, %rdi
+# else
+ leaq VALUE(%r12), %rdi
+# endif
+# if FUTEX_WAIT == 0
+ movl PRIVATE(%rdi), %esi
+# else
+ movl $FUTEX_WAIT, %esi
+ orl PRIVATE(%rdi), %esi
+# endif
+ movl $SYS_futex, %eax
+ xorl %edx, %edx
+ syscall
+ movq %rax, %r14
+
+ movl 16(%rsp), %edi
+ call __pthread_disable_asynccancel
+.LcleanupEND2:
+
+ testq %r14, %r14
+ je 9f
+ cmpq $-EWOULDBLOCK, %r14
+ jne 33f
+
+9:
+# if VALUE == 0
+ movl (%r12), %eax
+# else
+ movl VALUE(%r12), %eax
+# endif
+8: testl %eax, %eax
+ je 7b
+
+ leaq -1(%rax), %rcx
+ LOCK
+# if VALUE == 0
+ cmpxchgl %ecx, (%r12)
+# else
+ cmpxchgl %ecx, VALUE(%r12)
+# endif
+ jne 8b
+
+ xorl %eax, %eax
+
+45: LOCK
+ subq $1, NWAITERS(%r12)
+
+ addq $STACKFRAME, %rsp
+ cfi_adjust_cfa_offset(-STACKFRAME)
+ popq %r14
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r14)
+ popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r13)
+ popq %r12
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r12)
+ retq
+
+ cfi_adjust_cfa_offset(STACKFRAME + 3 * 8)
+ cfi_rel_offset(%r12, STACKFRAME + 2 * 8)
+ cfi_rel_offset(%r13, STACKFRAME + 1 * 8)
+ cfi_rel_offset(%r14, STACKFRAME)
+33: negq %r14
+36:
+#if USE___THREAD
+ movq errno@gottpoff(%rip), %rdx
+ movl %r14d, %fs:(%rdx)
+#else
+ callq __errno_location@plt
+ movl %r14d, (%rax)
+#endif
+
+ orl $-1, %eax
+ jmp 45b
+#endif
+ cfi_endproc
+ .size sem_timedwait,.-sem_timedwait
+
+
+ .type sem_timedwait_cleanup,@function
+sem_timedwait_cleanup:
+ cfi_startproc
+ cfi_adjust_cfa_offset(8)
+
+ movq (%rsp), %rdi
+ LOCK
+ subq $1, NWAITERS(%rdi)
+ movq %rax, %rdi
+.LcallUR:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE:
+ cfi_endproc
+ .size sem_timedwait_cleanup,.-sem_timedwait_cleanup
+
+
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+ .type sem_timedwait_cleanup2,@function
+sem_timedwait_cleanup2:
+ cfi_startproc
+ cfi_adjust_cfa_offset(STACKFRAME + 3 * 8)
+ cfi_rel_offset(%r12, STACKFRAME + 2 * 8)
+ cfi_rel_offset(%r13, STACKFRAME + 1 * 8)
+ cfi_rel_offset(%r14, STACKFRAME)
+
+ LOCK
+ subq $1, NWAITERS(%r12)
+ movq %rax, %rdi
+ movq STACKFRAME(%rsp), %r14
+ movq STACKFRAME+8(%rsp), %r13
+ movq STACKFRAME+16(%rsp), %r12
+.LcallUR2:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE2:
+ cfi_endproc
+ .size sem_timedwait_cleanup2,.-sem_timedwait_cleanup2
+#endif
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte DW_EH_PE_omit # @LPStart format
+ .byte DW_EH_PE_omit # @TType format
+ .byte DW_EH_PE_uleb128 # call-site format
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 sem_timedwait_cleanup-.LSTARTCODE
+ .uleb128 0
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+ .uleb128 .LcleanupSTART2-.LSTARTCODE
+ .uleb128 .LcleanupEND2-.LcleanupSTART2
+ .uleb128 sem_timedwait_cleanup2-.LSTARTCODE
+ .uleb128 0
+#endif
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+ .uleb128 .LcallUR2-.LSTARTCODE
+ .uleb128 .LENDCODE2-.LcallUR2
+ .uleb128 0
+ .uleb128 0
+#endif
+.Lcstend:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 8
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 8
+DW.ref.__gcc_personality_v0:
+ .quad __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
new file mode 100644
index 000000000..7b7f63ddb
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
@@ -0,0 +1,52 @@
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <pthread-errnos.h>
+
+ .text
+
+ .globl sem_trywait
+ .type sem_trywait,@function
+ .align 16
+sem_trywait:
+ movl (%rdi), %eax
+2: testl %eax, %eax
+ jz 1f
+
+ leal -1(%rax), %edx
+ LOCK
+ cmpxchgl %edx, (%rdi)
+ jne 2b
+
+ xorl %eax, %eax
+ retq
+
+1:
+#if USE___THREAD
+ movq errno@gottpoff(%rip), %rdx
+ movl $EAGAIN, %fs:(%rdx)
+#else
+ callq __errno_location@plt
+ movl $EAGAIN, (%rax)
+#endif
+ orl $-1, %eax
+ retq
+ .size sem_trywait,.-sem_trywait
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
new file mode 100644
index 000000000..f6b39bd74
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
@@ -0,0 +1,174 @@
+/* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <pthread-errnos.h>
+#include <structsem.h>
+
+
+ .text
+
+ .globl sem_wait
+ .type sem_wait,@function
+ .align 16
+sem_wait:
+.LSTARTCODE:
+ cfi_startproc
+
+#if VALUE == 0
+ movl (%rdi), %eax
+#else
+ movl VALUE(%rdi), %eax
+#endif
+2: testl %eax, %eax
+ je 1f
+
+ leal -1(%rax), %edx
+ LOCK
+#if VALUE == 0
+ cmpxchgl %edx, (%rdi)
+#else
+ cmpxchgl %edx, VALUE(%rdi)
+#endif
+ jne 2b
+
+ xorl %eax, %eax
+ retq
+
+ /* This push is only needed to store the sem_t pointer for the
+ exception handler. */
+1: pushq %rdi
+ cfi_adjust_cfa_offset(8)
+
+ LOCK
+ addq $1, NWAITERS(%rdi)
+
+.LcleanupSTART:
+6: call __pthread_enable_asynccancel
+ movl %eax, %r8d
+
+ xorq %r10, %r10
+ movl $SYS_futex, %eax
+#if FUTEX_WAIT == 0
+ movl PRIVATE(%rdi), %esi
+#else
+ movl $FUTEX_WAIT, %esi
+ orl PRIVATE(%rdi), %esi
+#endif
+ xorl %edx, %edx
+ syscall
+ movq %rax, %rcx
+
+ xchgq %r8, %rdi
+ call __pthread_disable_asynccancel
+.LcleanupEND:
+ movq %r8, %rdi
+
+ testq %rcx, %rcx
+ je 3f
+ cmpq $-EWOULDBLOCK, %rcx
+ jne 4f
+
+3:
+#if VALUE == 0
+ movl (%rdi), %eax
+#else
+ movl VALUE(%rdi), %eax
+#endif
+5: testl %eax, %eax
+ je 6b
+
+ leal -1(%rax), %edx
+ LOCK
+#if VALUE == 0
+ cmpxchgl %edx, (%rdi)
+#else
+ cmpxchgl %edx, VALUE(%rdi)
+#endif
+ jne 5b
+
+ xorl %eax, %eax
+
+9: LOCK
+ subq $1, NWAITERS(%rdi)
+
+ leaq 8(%rsp), %rsp
+ cfi_adjust_cfa_offset(-8)
+
+ retq
+
+ cfi_adjust_cfa_offset(8)
+4: negq %rcx
+#if USE___THREAD
+ movq errno@gottpoff(%rip), %rdx
+ movl %ecx, %fs:(%rdx)
+#else
+# error "not supported. %rcx and %rdi must be preserved"
+ callq __errno_location@plt
+ movl %ecx, (%rax)
+#endif
+ orl $-1, %eax
+
+ jmp 9b
+ .size sem_wait,.-sem_wait
+
+
+ .type sem_wait_cleanup,@function
+sem_wait_cleanup:
+ movq (%rsp), %rdi
+ LOCK
+ subq $1, NWAITERS(%rdi)
+ movq %rax, %rdi
+.LcallUR:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE:
+ cfi_endproc
+ .size sem_wait_cleanup,.-sem_wait_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte DW_EH_PE_omit # @LPStart format
+ .byte DW_EH_PE_omit # @TType format
+ .byte DW_EH_PE_uleb128 # call-site format
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 sem_wait_cleanup-.LSTARTCODE
+ .uleb128 0
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 8
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 8
+DW.ref.__gcc_personality_v0:
+ .quad __gcc_personality_v0
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
new file mode 100644
index 000000000..1c93952d4
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
@@ -0,0 +1,111 @@
+/* Copyright (C) 2002-2006, 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+/* The code to disable cancellation depends on the fact that the called
+ functions are special. They don't modify registers other than %rax
+ and %r11 if they return. Therefore we don't have to preserve other
+ registers around these calls. */
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ SINGLE_THREAD_P; \
+ jne L(pseudo_cancel); \
+ .type __##syscall_name##_nocancel,@function; \
+ .globl __##syscall_name##_nocancel; \
+ __##syscall_name##_nocancel: \
+ DO_CALL (syscall_name, args); \
+ cmpq $-4095, %rax; \
+ jae SYSCALL_ERROR_LABEL; \
+ ret; \
+ .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
+ L(pseudo_cancel): \
+ /* We always have to align the stack before calling a function. */ \
+ subq $8, %rsp; cfi_adjust_cfa_offset (8); \
+ CENABLE \
+ /* The return value from CENABLE is argument for CDISABLE. */ \
+ movq %rax, (%rsp); \
+ DO_CALL (syscall_name, args); \
+ movq (%rsp), %rdi; \
+ /* Save %rax since it's the error code from the syscall. */ \
+ movq %rax, %rdx; \
+ CDISABLE \
+ movq %rdx, %rax; \
+ addq $8,%rsp; cfi_adjust_cfa_offset (-8); \
+ cmpq $-4095, %rax; \
+ jae SYSCALL_ERROR_LABEL; \
+ L(pseudo_end):
+
+
+# ifdef IS_IN_libpthread
+# define CENABLE call __pthread_enable_asynccancel;
+# define CDISABLE call __pthread_disable_asynccancel;
+# define __local_multiple_threads __pthread_multiple_threads
+# elif !defined NOT_IN_libc
+# define CENABLE call __libc_enable_asynccancel;
+# define CDISABLE call __libc_disable_asynccancel;
+# define __local_multiple_threads __libc_multiple_threads
+# elif defined IS_IN_librt
+# define CENABLE call __librt_enable_asynccancel;
+# define CDISABLE call __librt_disable_asynccancel;
+# else
+# error Unsupported library
+# endif
+
+# if defined IS_IN_libpthread || !defined NOT_IN_libc
+# ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+# define SINGLE_THREAD_P \
+ __builtin_expect (__local_multiple_threads == 0, 1)
+# else
+# define SINGLE_THREAD_P cmpl $0, __local_multiple_threads(%rip)
+# endif
+
+# else
+
+# ifndef __ASSEMBLER__
+# define SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+# else
+# define SINGLE_THREAD_P cmpl $0, %fs:MULTIPLE_THREADS_OFFSET
+# endif
+
+# endif
+
+#elif !defined __ASSEMBLER__
+
+# define SINGLE_THREAD_P (1)
+# define NO_CANCELLATION 1
+
+#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S
new file mode 100644
index 000000000..9a9912ca8
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S
@@ -0,0 +1,43 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* We want an #include_next, but we are the main source file.
+ So, #include ourselves and in that incarnation we can use #include_next. */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <vfork.S>
+#else
+
+# include <tcb-offsets.h>
+
+# define SAVE_PID \
+ movl %fs:PID, %esi; \
+ movl $0x80000000, %ecx; \
+ movl %esi, %edx; \
+ negl %edx; \
+ cmove %ecx, %edx; \
+ movl %edx, %fs:PID
+
+# define RESTORE_PID \
+ testq %rax, %rax; \
+ je 1f; \
+ movl %esi, %fs:PID; \
+1:
+
+# include_next <vfork.S>
+#endif