2003-03-03  Martin Schwidefsky  <schwidefsky@de.ibm.com>

	* atomic.h (atomic_exchange_and_add): Return newval, not oldval.

	* sysdeps/pthread/pthread_cond_timedwait.c (__pthread_cond_timedwait):
	Fix handling of cancellation and failing pthread_mutex_unlock call.
	* sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Likewise.
	(__pthread_cond_wait): Likewise.

	* sysdeps/pthread/pthread_rwlock_timedrdlock.c
	(pthread_rwlock_timedrdlock): Fix clobber of result variable by
	lll_futex_timed_wait call.
	* sysdeps/pthread/pthread_rwlock_timedwrlock.c
	(pthread_rwlock_timedwrlock): Likewise.

	* sysdeps/unix/sysv/linux/s390/libc-lowlevellock.c (___lll_lock):
	Don't define lll_unlock_wake_cb and ___lll_timedwait_tid in libc.so.
	* sysdeps/unix/sysv/linux/s390/lowlevellock.c: Remove XXX comments.

	* sysdeps/unix/sysv/linux/s390/sem_post.c (__new_sem_post): Fix
	check of lll_futex_wake return value.
This commit is contained in:
Ulrich Drepper 2003-03-03 21:11:12 +00:00
parent 625f22fc7f
commit 7ce5c1640c
10 changed files with 377 additions and 276 deletions

View File

@ -1,3 +1,25 @@
2003-03-03 Martin Schwidefsky <schwidefsky@de.ibm.com>
* atomic.h (atomic_exchange_and_add): Return newval, not oldval.
* sysdeps/pthread/pthread_cond_timedwait.c (__pthread_cond_timedwait):
Fix handling of cancellation and failing pthread_mutex_unlock call.
* sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Likewise.
(__pthread_cond_wait): Likewise.
* sysdeps/pthread/pthread_rwlock_timedrdlock.c
(pthread_rwlock_timedrdlock): Fix clobber of result variable by
lll_futex_timed_wait call.
* sysdeps/pthread/pthread_rwlock_timedwrlock.c
(pthread_rwlock_timedwrlock): Likewise.
* sysdeps/unix/sysv/linux/s390/libc-lowlevellock.c (___lll_lock):
Don't define lll_unlock_wake_cb and ___lll_timedwait_tid in libc.so.
* sysdeps/unix/sysv/linux/s390/lowlevellock.c: Remove XXX comments.
* sysdeps/unix/sysv/linux/s390/sem_post.c (__new_sem_post): Fix
check of lll_futex_wake return value.
2003-03-03 Roland McGrath <roland@redhat.com> 2003-03-03 Roland McGrath <roland@redhat.com>
* forward.c: Fix typo in __pthread_attr_init_2_0 compat_symbol decl. * forward.c: Fix typo in __pthread_attr_init_2_0 compat_symbol decl.

View File

@ -60,7 +60,7 @@
while (atomic_compare_and_exchange_acq (__memp, __oldval + __value, \ while (atomic_compare_and_exchange_acq (__memp, __oldval + __value, \
__oldval)); \ __oldval)); \
\ \
__oldval; }) __oldval + __value; })
#endif #endif

View File

@ -31,6 +31,12 @@
extern void __condvar_cleanup (void *arg) extern void __condvar_cleanup (void *arg)
__attribute__ ((visibility ("hidden"))); __attribute__ ((visibility ("hidden")));
struct _condvar_cleanup_buffer
{
int oldtype;
pthread_cond_t *cond;
pthread_mutex_t *mutex;
};
int int
__pthread_cond_timedwait (cond, mutex, abstime) __pthread_cond_timedwait (cond, mutex, abstime)
@ -39,6 +45,7 @@ __pthread_cond_timedwait (cond, mutex, abstime)
const struct timespec *abstime; const struct timespec *abstime;
{ {
struct _pthread_cleanup_buffer buffer; struct _pthread_cleanup_buffer buffer;
struct _condvar_cleanup_buffer cbuffer;
int result = 0; int result = 0;
/* Catch invalid parameters. */ /* Catch invalid parameters. */
@ -54,9 +61,13 @@ __pthread_cond_timedwait (cond, mutex, abstime)
/* We have one new user of the condvar. */ /* We have one new user of the condvar. */
++cond->__data.__total_seq; ++cond->__data.__total_seq;
/* Prepare structure passed to cancellation handler. */
cbuffer.cond = cond;
cbuffer.mutex = mutex;
/* Before we block we enable cancellation. Therefore we have to /* Before we block we enable cancellation. Therefore we have to
install a cancellation handler. */ install a cancellation handler. */
__pthread_cleanup_push (&buffer, __condvar_cleanup, cond); __pthread_cleanup_push (&buffer, __condvar_cleanup, &cbuffer);
/* The current values of the wakeup counter. The "woken" counter /* The current values of the wakeup counter. The "woken" counter
must exceed this value. */ must exceed this value. */
@ -76,6 +87,8 @@ __pthread_cond_timedwait (cond, mutex, abstime)
while (1) while (1)
{ {
int err;
/* Get the current time. So far we support only one clock. */ /* Get the current time. So far we support only one clock. */
struct timeval tv; struct timeval tv;
(void) gettimeofday (&tv, NULL); (void) gettimeofday (&tv, NULL);
@ -104,14 +117,14 @@ __pthread_cond_timedwait (cond, mutex, abstime)
lll_mutex_unlock (cond->__data.__lock); lll_mutex_unlock (cond->__data.__lock);
/* Enable asynchronous cancellation. Required by the standard. */ /* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel (); cbuffer.oldtype = __pthread_enable_asynccancel ();
/* Wait until woken by signal or broadcast. Note that we /* Wait until woken by signal or broadcast. Note that we
truncate the 'val' value to 32 bits. */ truncate the 'val' value to 32 bits. */
result = lll_futex_timed_wait (futex, (unsigned int) val, &rt); err = lll_futex_timed_wait (futex, (unsigned int) val, &rt);
/* Disable asynchronous cancellation. */ /* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype); __pthread_disable_asynccancel (cbuffer.oldtype);
/* We are going to look at shared data again, so get the lock. */ /* We are going to look at shared data again, so get the lock. */
lll_mutex_lock(cond->__data.__lock); lll_mutex_lock(cond->__data.__lock);
@ -123,7 +136,7 @@ __pthread_cond_timedwait (cond, mutex, abstime)
break; break;
/* Not woken yet. Maybe the time expired? */ /* Not woken yet. Maybe the time expired? */
if (result == -ETIMEDOUT) if (err == -ETIMEDOUT)
{ {
/* Yep. Adjust the counters. */ /* Yep. Adjust the counters. */
++cond->__data.__wakeup_seq; ++cond->__data.__wakeup_seq;

View File

@ -27,22 +27,35 @@
#include <shlib-compat.h> #include <shlib-compat.h>
struct _condvar_cleanup_buffer
{
int oldtype;
pthread_cond_t *cond;
pthread_mutex_t *mutex;
};
void void
__attribute__ ((visibility ("hidden"))) __attribute__ ((visibility ("hidden")))
__condvar_cleanup (void *arg) __condvar_cleanup (void *arg)
{ {
pthread_cond_t *cond = (pthread_cond_t *) arg; struct _condvar_cleanup_buffer *cbuffer =
(struct _condvar_cleanup_buffer *) arg;
/* We are going to modify shared data. */ /* We are going to modify shared data. */
lll_mutex_lock (cond->__data.__lock); lll_mutex_lock (cbuffer->cond->__data.__lock);
/* This thread is not waiting anymore. Adjust the sequence counters /* This thread is not waiting anymore. Adjust the sequence counters
appropriately. */ appropriately. */
++cond->__data.__wakeup_seq; ++cbuffer->cond->__data.__wakeup_seq;
++cond->__data.__woken_seq; ++cbuffer->cond->__data.__woken_seq;
/* We are done. */ /* We are done. */
lll_mutex_unlock (cond->__data.__lock); lll_mutex_unlock (cbuffer->cond->__data.__lock);
/* Get the mutex before returning unless asynchronous cancellation
is in effect. */
if (!(cbuffer->oldtype & CANCELTYPE_BITMASK))
__pthread_mutex_lock_internal (cbuffer->mutex);
} }
@ -52,19 +65,30 @@ __pthread_cond_wait (cond, mutex)
pthread_mutex_t *mutex; pthread_mutex_t *mutex;
{ {
struct _pthread_cleanup_buffer buffer; struct _pthread_cleanup_buffer buffer;
struct _condvar_cleanup_buffer cbuffer;
int err;
/* Make sure we are along. */ /* Make sure we are along. */
lll_mutex_lock (cond->__data.__lock); lll_mutex_lock (cond->__data.__lock);
/* Now we can release the mutex. */ /* Now we can release the mutex. */
__pthread_mutex_unlock_internal (mutex); err = __pthread_mutex_unlock_internal (mutex);
if (err)
{
lll_mutex_unlock (cond->__data.__lock);
return err;
}
/* We have one new user of the condvar. */ /* We have one new user of the condvar. */
++cond->__data.__total_seq; ++cond->__data.__total_seq;
/* Prepare structure passed to cancellation handler. */
cbuffer.cond = cond;
cbuffer.mutex = mutex;
/* Before we block we enable cancellation. Therefore we have to /* Before we block we enable cancellation. Therefore we have to
install a cancellation handler. */ install a cancellation handler. */
__pthread_cleanup_push (&buffer, __condvar_cleanup, cond); __pthread_cleanup_push (&buffer, __condvar_cleanup, &cbuffer);
/* The current values of the wakeup counter. The "woken" counter /* The current values of the wakeup counter. The "woken" counter
must exceed this value. */ must exceed this value. */
@ -88,14 +112,14 @@ __pthread_cond_wait (cond, mutex)
lll_mutex_unlock (cond->__data.__lock); lll_mutex_unlock (cond->__data.__lock);
/* Enable asynchronous cancellation. Required by the standard. */ /* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel (); cbuffer.oldtype = __pthread_enable_asynccancel ();
/* Wait until woken by signal or broadcast. Note that we /* Wait until woken by signal or broadcast. Note that we
truncate the 'val' value to 32 bits. */ truncate the 'val' value to 32 bits. */
lll_futex_wait (futex, (unsigned int) val); lll_futex_wait (futex, (unsigned int) val);
/* Disable asynchronous cancellation. */ /* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype); __pthread_disable_asynccancel (cbuffer.oldtype);
/* We are going to look at shared data again, so get the lock. */ /* We are going to look at shared data again, so get the lock. */
lll_mutex_lock(cond->__data.__lock); lll_mutex_lock(cond->__data.__lock);

View File

@ -37,6 +37,8 @@ pthread_rwlock_timedrdlock (rwlock, abstime)
while (1) while (1)
{ {
int err;
/* Get the rwlock if there is no writer... */ /* Get the rwlock if there is no writer... */
if (rwlock->__data.__writer == 0 if (rwlock->__data.__writer == 0
/* ...and if either no writer is waiting or we prefer readers. */ /* ...and if either no writer is waiting or we prefer readers. */
@ -111,14 +113,14 @@ pthread_rwlock_timedrdlock (rwlock, abstime)
lll_mutex_unlock (rwlock->__data.__lock); lll_mutex_unlock (rwlock->__data.__lock);
/* Wait for the writer to finish. */ /* Wait for the writer to finish. */
result = lll_futex_timed_wait (&rwlock->__data.__readers_wakeup, err = lll_futex_timed_wait (&rwlock->__data.__readers_wakeup,
waitval, &rt); waitval, &rt);
/* Get the lock. */ /* Get the lock. */
lll_mutex_lock (rwlock->__data.__lock); lll_mutex_lock (rwlock->__data.__lock);
/* Did the futex call time out? */ /* Did the futex call time out? */
if (result == -ETIMEDOUT) if (err == -ETIMEDOUT)
{ {
/* Yep, report it. */ /* Yep, report it. */
result = ETIMEDOUT; result = ETIMEDOUT;

View File

@ -17,5 +17,26 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */ 02111-1307 USA. */
/* No difference to lowlevellock.c */ #include <errno.h>
#include "lowlevellock.c" #include <sysdep.h>
#include <lowlevellock.h>
#include <sys/time.h>
void
___lll_lock (futex, newval)
int *futex;
int newval;
{
do
{
int oldval;
lll_futex_wait (futex, newval);
lll_compare_and_swap (futex, oldval, newval, "lr %2,%1; ahi %2,-1");
}
while (newval != 0);
*futex = -1;
}
hidden_proto (___lll_lock)

View File

@ -42,7 +42,6 @@ ___lll_lock (futex, newval)
hidden_proto (___lll_lock) hidden_proto (___lll_lock)
/* XXX Should not be in libc.so */
int int
lll_unlock_wake_cb (futex) lll_unlock_wake_cb (futex)
int *futex; int *futex;
@ -58,7 +57,6 @@ lll_unlock_wake_cb (futex)
hidden_proto (lll_unlock_wake_cb) hidden_proto (lll_unlock_wake_cb)
/* XXX Should not be in libc.so */
int int
___lll_timedwait_tid (ptid, abstime) ___lll_timedwait_tid (ptid, abstime)
int *ptid; int *ptid;

View File

@ -34,7 +34,7 @@ __new_sem_post (sem_t *sem)
lll_compare_and_swap ((int *) sem, oldval, newval, "lr %2,%1; ahi %2,1"); lll_compare_and_swap ((int *) sem, oldval, newval, "lr %2,%1; ahi %2,1");
err = lll_futex_wake(((int *) sem), newval); err = lll_futex_wake(((int *) sem), newval);
if (err != 0) if (err < 0)
{ {
__set_errno(-err); __set_errno(-err);
return -1; return -1;

521
po/gl.po

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,13 @@
# GNU libc message catalog for swedish # GNU libc message catalog for swedish
# Copyright © 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc. # Copyright © 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
# Jan Djärv <jan.h.d@swipnet.se>, 1996, 1998, 2001, 2002, 2003. # Jan Djärv <jan.h.d@swipnet.se>, 1996, 1998, 2001, 2002, 2003.
# Revision: 1.44 # Revision: 1.45
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: libc 2.3.2\n" "Project-Id-Version: libc 2.3.2\n"
"POT-Creation-Date: 2003-02-22 15:34-0800\n" "POT-Creation-Date: 2003-02-22 15:34-0800\n"
"PO-Revision-Date: 2003-03-03 19:14+0100\n" "PO-Revision-Date: 2003-03-03 21:11+0100\n"
"Last-Translator: Jan Djärv <jan.h.d@swipnet.se>\n" "Last-Translator: Jan Djärv <jan.h.d@swipnet.se>\n"
"Language-Team: Swedish <sv@li.org>\n" "Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -4714,7 +4714,7 @@ msgid ""
"Group Members :\n" "Group Members :\n"
msgstr "" msgstr ""
"\n" "\n"
"Guppmedlemmar:\n" "Gruppmedlemmar:\n"
#: nis/nis_print.c:266 #: nis/nis_print.c:266
#, c-format #, c-format