From 73f7c32c47ab2397935d9fc2aeaa594794b38c7e Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 2 Sep 2004 18:59:24 +0000 Subject: [BZ #357] Update. 2004-09-02 Steven Munroe [BZ #357] * stdlib/tst-setcontext.c (test_stack): Added test for stack clobber. (main): Call test_stack. * sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S (__getcontext): Push stack frame then save parms in local frame. Improve instruction scheduling. * sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S (__swapcontext): Likewise. --- .../unix/sysv/linux/i386/bits/pthreadtypes.h | 2 +- .../sysv/linux/i386/i486/pthread_cond_timedwait.S | 54 +++++++++++++++++++--- .../unix/sysv/linux/i386/i486/pthread_cond_wait.S | 49 ++++++++++++++++++-- 3 files changed, 94 insertions(+), 11 deletions(-) (limited to 'nptl/sysdeps/unix/sysv/linux/i386') diff --git a/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h index 8d7858a071..fb62c0d99b 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h +++ b/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h @@ -81,7 +81,7 @@ typedef union unsigned long long int __wakeup_seq; unsigned long long int __woken_seq; void *__mutex; - int __clock; + unsigned int __nwaiters; unsigned int __broadcast_seq; } __data; char __size[__SIZEOF_PTHREAD_COND_T]; diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S index eecec8aee3..699c2cb227 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S +++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S @@ -87,6 +87,7 @@ __pthread_cond_timedwait: addl $1, total_seq(%ebx) adcl $0, total_seq+4(%ebx) addl $1, cond_futex(%ebx) + addl $(1 << clock_bits), cond_nwaiters(%ebx) #define FRAME_SIZE 24 subl $FRAME_SIZE, %esp @@ -104,8 +105,9 @@ __pthread_cond_timedwait: 8: movl %ebx, %edx #ifdef __NR_clock_gettime /* Get the clock number. */ - movl cond_clock(%ebx), %ebx - /* Only clocks 0 and 1 are allowed. Both are handled in the + movl cond_nwaiters(%ebx), %ebx + andl $((1 << clock_bits) - 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 @@ -226,7 +228,25 @@ __pthread_cond_timedwait: 14: addl $1, woken_seq(%ebx) adcl $0, woken_seq+4(%ebx) -24: LOCK +24: subl $(1 << clock_bits), 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 << clock_bits) - 1), %eax + jne 25f + + addl $cond_nwaiters, %ebx + movl $SYS_futex, %eax + movl $FUTEX_WAKE, %ecx + movl $1, %edx + ENTER_KERNEL + subl $cond_nwaiters, %ebx + +25: LOCK #if cond_lock == 0 subl $1, (%ebx) #else @@ -394,7 +414,27 @@ __condvar_tw_cleanup: addl $1, woken_seq(%ebx) adcl $0, woken_seq+4(%ebx) -3: LOCK +3: subl $(1 << clock_bits), 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 << clock_bits) - 1), %eax + jne 4f + + addl $cond_nwaiters, %ebx + movl $SYS_futex, %eax + movl $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 @@ -410,13 +450,15 @@ __condvar_tw_cleanup: call __lll_mutex_unlock_wake /* Wake up all waiters to make sure no signal gets lost. */ -2: addl $cond_futex, %ebx +2: testl %edi, %edi + jnz 5f + addl $cond_futex, %ebx movl $FUTEX_WAKE, %ecx movl $SYS_futex, %eax movl $0x7fffffff, %edx ENTER_KERNEL - movl 24+FRAME_SIZE(%esp), %eax +5: movl 24+FRAME_SIZE(%esp), %eax call __pthread_mutex_cond_lock movl %esi, (%esp) diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S index 3fe7f8c17a..d282785151 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S +++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S @@ -80,6 +80,7 @@ __pthread_cond_wait: addl $1, total_seq(%ebx) adcl $0, total_seq+4(%ebx) addl $1, cond_futex(%ebx) + addl $(1 << clock_bits), cond_nwaiters(%ebx) #define FRAME_SIZE 16 subl $FRAME_SIZE, %esp @@ -156,7 +157,25 @@ __pthread_cond_wait: adcl $0, woken_seq+4(%ebx) /* Unlock */ -16: LOCK +16: subl $(1 << clock_bits), 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 << clock_bits) - 1), %eax + jne 17f + + addl $cond_nwaiters, %ebx + movl $SYS_futex, %eax + movl $FUTEX_WAKE, %ecx + movl $1, %edx + ENTER_KERNEL + subl $cond_nwaiters, %ebx + +17: LOCK #if cond_lock == 0 subl $1, (%ebx) #else @@ -286,7 +305,27 @@ __condvar_w_cleanup: addl $1, woken_seq(%ebx) adcl $0, woken_seq+4(%ebx) -3: LOCK +3: subl $(1 << clock_bits), 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 << clock_bits) - 1), %eax + jne 4f + + addl $cond_nwaiters, %ebx + movl $SYS_futex, %eax + movl $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 @@ -302,13 +341,15 @@ __condvar_w_cleanup: call __lll_mutex_unlock_wake /* Wake up all waiters to make sure no signal gets lost. */ -2: addl $cond_futex, %ebx +2: testl %edi, %edi + jnz 5f + addl $cond_futex, %ebx movl $FUTEX_WAKE, %ecx movl $SYS_futex, %eax movl $0x7fffffff, %edx ENTER_KERNEL - movl 20+FRAME_SIZE(%esp), %eax +5: movl 20+FRAME_SIZE(%esp), %eax call __pthread_mutex_cond_lock movl %esi, (%esp) -- cgit 1.4.1