diff options
author | Ulrich Drepper <drepper@redhat.com> | 2003-02-14 03:26:28 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2003-02-14 03:26:28 +0000 |
commit | a7720b5e184ed038576e017701911169c7de8f8a (patch) | |
tree | 17bca8f9128fa8a7cfed52eae755fa13046ac70e /nptl/sysdeps | |
parent | a1ea4c0638ecf4ef3c421b03089000aca7d0f0eb (diff) | |
download | glibc-a7720b5e184ed038576e017701911169c7de8f8a.tar glibc-a7720b5e184ed038576e017701911169c7de8f8a.tar.gz glibc-a7720b5e184ed038576e017701911169c7de8f8a.tar.bz2 glibc-a7720b5e184ed038576e017701911169c7de8f8a.zip |
Update.
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Fix
handling of cancellation and failung pthread_mutex_unlock call.
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
* Makefile (tests): Add tst-cond8 and tst-cond9.
* tst-cond8.c: New file.
* tst-cond9.c: New file.
Diffstat (limited to 'nptl/sysdeps')
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S | 63 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S | 67 |
2 files changed, 99 insertions, 31 deletions
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 c520f287d9..b13ad19408 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 @@ -67,6 +67,9 @@ __pthread_cond_timedwait: 2: pushl 24(%esp) call __pthread_mutex_unlock_internal + testl %eax, %eax + jne 16f + addl $1, total_seq(%ebx) adcl $0, total_seq+4(%ebx) @@ -78,18 +81,23 @@ __pthread_cond_timedwait: #else leal __condvar_cleanup, %eax #endif - subl $32, %esp - leal 16(%esp), %edx - movl %ebx, 8(%esp) + subl $40, %esp + leal 28(%esp), %edx + movl %esp, 8(%esp) movl %eax, 4(%esp) movl %edx, (%esp) call __pthread_cleanup_push + /* Address of the mutex. */ + movl 68(%esp), %ecx /* Get and store current wakeup_seq value. */ movl wakeup_seq(%ebx), %edi movl wakeup_seq+4(%ebx), %edx - movl %edi, 12(%esp) - movl %edx, 16(%esp) + movl %edi, 20(%esp) + movl %edx, 24(%esp) + /* Prepare structure passed to cancellation handler. */ + movl %ebx, 4(%esp) + movl %ecx, 8(%esp) /* Unlock. */ 8: LOCK @@ -105,19 +113,19 @@ __pthread_cond_timedwait: /* Get the current time. */ movl %ebx, %edx - leal 4(%esp), %ebx + leal 12(%esp), %ebx xorl %ecx, %ecx movl $SYS_gettimeofday, %eax ENTER_KERNEL movl %edx, %ebx /* Compute relative timeout. */ - movl 8(%esp), %eax + movl 16(%esp), %eax movl $1000, %edx mul %edx /* Milli seconds to nano seconds. */ movl (%ebp), %ecx movl 4(%ebp), %edx - subl 4(%esp), %ecx + subl 12(%esp), %ecx subl %eax, %edx jns 12f addl $1000000000, %edx @@ -126,9 +134,9 @@ __pthread_cond_timedwait: js 13f /* Store relative timeout. */ - movl %ecx, 4(%esp) - movl %edx, 8(%esp) - leal 4(%esp), %esi + movl %ecx, 12(%esp) + movl %edx, 16(%esp) + leal 12(%esp), %esi xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */ movl %edi, %edx addl $wakeup_seq, %ebx @@ -156,10 +164,10 @@ __pthread_cond_timedwait: movl wakeup_seq(%ebx), %edi movl wakeup_seq+4(%ebx), %edx - cmpl 16(%esp), %ecx + cmpl 24(%esp), %ecx ja 7f jb 15f - cmpl 12(%esp), %eax + cmpl 20(%esp), %eax jb 15f 7: cmpl %ecx, %edx @@ -189,19 +197,19 @@ __pthread_cond_timedwait: jne 10f /* Remove cancellation handler. */ -11: leal 20(%esp), %edx +11: leal 28(%esp), %edx movl $0, 4(%esp) movl %edx, (%esp) call __pthread_cleanup_pop - movl 60(%esp), %ecx - movl %ecx, (%esp) + /* Trick ahead: 8(%esp) contains the address of the mutex. */ + addl $8, %esp call __pthread_mutex_lock_internal addl $36, %esp movl %esi, %eax - popl %ebx +18: popl %ebx popl %esi popl %edi popl %ebp @@ -248,6 +256,27 @@ __pthread_cond_timedwait: #endif call __lll_mutex_unlock_wake jmp 11b + + /* The initial unlocking of the mutex failed. */ +16: movl %eax, (%esp) + LOCK +#if cond_lock == 0 + decl (%ebx) +#else + decl cond_lock(%ebx) +#endif + jne 17f + +#if cond_lock == 0 + movl %ebx, %eax +#else + leal cond_lock(%ebx), %eax +#endif + call __lll_mutex_unlock_wake + +17: popl %eax + jmp 18b + .size __pthread_cond_wait, .-__pthread_cond_wait .size __pthread_cond_timedwait, .-__pthread_cond_timedwait versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait, GLIBC_2_3_2) 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 e43bcbac82..da0483ab1b 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 @@ -20,6 +20,7 @@ #include <sysdep.h> #include <shlib-compat.h> #include <lowlevelcond.h> +#include <tcb-offsets.h> #ifdef UP # define LOCK @@ -40,9 +41,11 @@ .hidden __condvar_cleanup __condvar_cleanup: pushl %ebx - movl 8(%esp), %ebx + pushl %esi + movl 12(%esp), %esi /* Get internal lock. */ + movl 4(%esi), %ebx movl $1, %eax LOCK #if cond_lock == 0 @@ -80,7 +83,16 @@ __condvar_cleanup: #endif call __lll_mutex_unlock_wake -2: popl %ebx + /* Lock the mutex unless asnychronous cancellation is in effect. */ +2: testl $2, (%esi) + jne 3f + + pushl 8(%esi) + call __pthread_mutex_lock_internal + popl %eax + +3: popl %esi + popl %ebx ret .size __condvar_cleanup, .-__condvar_cleanup @@ -113,6 +125,9 @@ __pthread_cond_wait: 2: pushl 20(%esp) call __pthread_mutex_unlock_internal + testl %eax, %eax + jne 12f + addl $1, total_seq(%ebx) adcl $0, total_seq+4(%ebx) @@ -124,18 +139,22 @@ __pthread_cond_wait: #else leal __condvar_cleanup, %eax #endif - subl $24, %esp - leal 12(%esp), %edx - movl %ebx, 8(%esp) + subl $32, %esp + leal 20(%esp), %edx + movl %esp, 8(%esp) movl %eax, 4(%esp) movl %edx, (%esp) call __pthread_cleanup_push /* Get and store current wakeup_seq value. */ + movl 56(%esp), %ecx movl wakeup_seq(%ebx), %edi movl wakeup_seq+4(%ebx), %edx - movl %edi, 4(%esp) - movl %edx, 8(%esp) + movl %edi, 12(%esp) + movl %edx, 16(%esp) + /* Prepare structure passed to cancellation handler. */ + movl %ebx, 4(%esp) + movl %ecx, 8(%esp) /* Unlock. */ 8: LOCK @@ -175,10 +194,10 @@ __pthread_cond_wait: movl wakeup_seq(%ebx), %edi movl wakeup_seq+4(%ebx), %edx - cmpl 8(%esp), %ecx + cmpl 16(%esp), %ecx ja 7f jb 8b - cmpl 4(%esp), %eax + cmpl 12(%esp), %eax jb 8b 7: cmpl %ecx, %edx @@ -199,17 +218,17 @@ __pthread_cond_wait: jne 10f /* Remove cancellation handler. */ -11: leal 12(%esp), %edx +11: leal 20(%esp), %edx movl $0, 4(%esp) movl %edx, (%esp) call __pthread_cleanup_pop - movl 48(%esp), %eax - movl %eax, (%esp) + /* Trick ahead: 8(%esp) contains the address of the mutex. */ + addl $8, %esp call __pthread_mutex_lock_internal addl $28, %esp - popl %ebx +14: popl %ebx popl %esi popl %edi @@ -246,7 +265,7 @@ __pthread_cond_wait: call __lll_mutex_lock_wait jmp 6b - /* Unlock after loop requires waekup. */ + /* Unlock after loop requires wakeup. */ 10: #if cond_lock == 0 movl %ebx, %eax @@ -255,6 +274,26 @@ __pthread_cond_wait: #endif call __lll_mutex_unlock_wake jmp 11b + + /* The initial unlocking of the mutex failed. */ +12: movl %eax, (%esp) + LOCK +#if cond_lock == 0 + decl (%ebx) +#else + decl cond_lock(%ebx) +#endif + jne 13f + +#if cond_lock == 0 + movl %ebx, %eax +#else + leal cond_lock(%ebx), %eax +#endif + call __lll_mutex_unlock_wake + +13: popl %eax + jmp 14b .size __pthread_cond_wait, .-__pthread_cond_wait versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait, GLIBC_2_3_2) |