Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[BZ #357]
Update.
2004-09-02  Steven Munroe  <sjmunroe@us.ibm.com>

	[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.
  • Loading branch information
Ulrich Drepper committed Sep 2, 2004
1 parent 86aca5a commit 73f7c32
Show file tree
Hide file tree
Showing 28 changed files with 643 additions and 96 deletions.
11 changes: 11 additions & 0 deletions ChangeLog
@@ -1,3 +1,14 @@
2004-09-02 Steven Munroe <sjmunroe@us.ibm.com>

[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.

2004-09-01 Andreas Schwab <schwab@suse.de>

* sysdeps/unix/sysv/linux/ia64/sys/ucontext.h [g++ >= 3.5]: Use
Expand Down
59 changes: 59 additions & 0 deletions nptl/ChangeLog
@@ -1,3 +1,62 @@
2004-09-02 Ulrich Drepper <drepper@redhat.com>

* sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h (pthread_cond_t):
Rename __data.__clock to __data.__nwaiters, make it unsigned int.
* sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h (pthread_cond_t):
Likewise.
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S:
Decrement __nwaiters. If pthread_cond_destroy has been called and
this is the last waiter, signal pthread_cond_destroy caller and
avoid using the pthread_cond_t structure after unlock.
* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
Read clock type from the least significant bits of __nwaiters instead
of __clock.
* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
* sysdeps/unix/sysv/linux/internaltypes.h: Define COND_CLOCK_BITS.

2004-08-31 Jakub Jelinek <jakub@redhat.com>

[BZ #342]
* Makefile (tests): Add tst-cond20 and tst-cond21.
* tst-cond20.c: New test.
* tst-cond21.c: New test.
* sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
(pthread_cond_t): Rename __data.__clock to __data.__nwaiters, make
it unsigned int.
* sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h (pthread_cond_t):
Likewise.
* sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
(pthread_cond_t): Likewise.
* sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h (pthread_cond_t):
Likewise.
* sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h (pthread_cond_t):
Likewise.
* sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h (pthread_cond_t):
Likewise.
* sysdeps/unix/sysv/linux/lowlevelcond.sym (cond_clock): Remove.
(cond_nwaiters): New.
(clock_bits): New.
* pthread_cond_destroy.c (__pthread_cond_destroy): Return EBUSY
if there are waiters not signalled yet.
Wait until all already signalled waiters wake up.
* sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Decrement
__nwaiters. If pthread_cond_destroy has been called and this is the
last waiter, signal pthread_cond_destroy caller and avoid using
the pthread_cond_t structure after unlock.
(__pthread_cond_wait): Increment __nwaiters in the beginning,
decrement it when leaving. If pthread_cond_destroy has been called
and this is the last waiter, signal pthread_cond_destroy caller.
* sysdeps/pthread/pthread_cond_timedwait.c (__pthread_cond_timedwait):
Likewise. Read clock type from the least significant bits of
__nwaiters instead of __clock.
* pthread_condattr_setclock.c (pthread_condattr_setclock): Check
whether clock ID can be encoded in COND_CLOCK_BITS bits.
* pthread_condattr_getclock.c (pthread_condattr_getclock): Decode
clock type just from the last COND_CLOCK_BITS bits of value.
* pthread_cond_init.c (__pthread_cond_init): Initialize __nwaiters
instead of __clock, just from second bit of condattr's value.

2004-08-30 Jakub Jelinek <jakub@redhat.com>

* sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Include
Expand Down
1 change: 1 addition & 0 deletions nptl/Makefile
Expand Up @@ -193,6 +193,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 \
tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
tst-cond20 tst-cond21 \
tst-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \
tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \
tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \
Expand Down
32 changes: 31 additions & 1 deletion nptl/pthread_cond_destroy.c
@@ -1,4 +1,4 @@
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
/* 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.
Expand All @@ -17,6 +17,7 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */

#include <errno.h>
#include <shlib-compat.h>
#include "pthreadP.h"

Expand All @@ -25,6 +26,35 @@ int
__pthread_cond_destroy (cond)
pthread_cond_t *cond;
{
/* Make sure we are alone. */
lll_mutex_lock (cond->__data.__lock);

if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
{
/* If there are still some waiters which have not been
woken up, this is an application bug. */
lll_mutex_unlock (cond->__data.__lock);
return EBUSY;
}

/* Tell pthread_cond_*wait that this condvar is being destroyed. */
cond->__data.__total_seq = -1ULL;

/* If there are waiters which have been already signalled or
broadcasted, but still are using the pthread_cond_t structure,
pthread_cond_destroy needs to wait for them. */
unsigned int nwaiters = cond->__data.__nwaiters;
while (nwaiters >= (1 << COND_CLOCK_BITS))
{
lll_mutex_unlock (cond->__data.__lock);

lll_futex_wait (&cond->__data.__nwaiters, nwaiters);

lll_mutex_lock (cond->__data.__lock);

nwaiters = cond->__data.__nwaiters;
}

return 0;
}
versioned_symbol (libpthread, __pthread_cond_destroy,
Expand Down
5 changes: 3 additions & 2 deletions nptl/pthread_cond_init.c
Expand Up @@ -32,8 +32,9 @@ __pthread_cond_init (cond, cond_attr)

cond->__data.__lock = LLL_MUTEX_LOCK_INITIALIZER;
cond->__data.__futex = 0;
cond->__data.__clock = (icond_attr == NULL
? CLOCK_REALTIME : (icond_attr->value & 0xfe) >> 1);
cond->__data.__nwaiters = (icond_attr != NULL
&& ((icond_attr->value & (COND_CLOCK_BITS << 1))
>> 1));
cond->__data.__total_seq = 0;
cond->__data.__wakeup_seq = 0;
cond->__data.__woken_seq = 0;
Expand Down
6 changes: 3 additions & 3 deletions nptl/pthread_condattr_getclock.c
@@ -1,4 +1,4 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
/* 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.
Expand All @@ -25,7 +25,7 @@ pthread_condattr_getclock (attr, clock_id)
const pthread_condattr_t *attr;
clockid_t *clock_id;
{
*clock_id = ((((const struct pthread_condattr *) attr)->value) & 0xfe) >> 1;

*clock_id = (((((const struct pthread_condattr *) attr)->value) >> 1)
& ((1 << COND_CLOCK_BITS) - 1));
return 0;
}
13 changes: 9 additions & 4 deletions nptl/pthread_condattr_setclock.c
@@ -1,4 +1,4 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
/* 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.
Expand All @@ -17,6 +17,7 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */

#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <time.h>
Expand Down Expand Up @@ -45,8 +46,7 @@ pthread_condattr_setclock (attr, clock_id)

INTERNAL_SYSCALL_DECL (err);
int val;
val = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC,
&ts);
val = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts);
avail = INTERNAL_SYSCALL_ERROR_P (val, err) ? -1 : 1;
}

Expand All @@ -57,11 +57,16 @@ pthread_condattr_setclock (attr, clock_id)
#endif
}
else if (clock_id != CLOCK_REALTIME)
/* If more clocks are allowed some day the storing of the clock ID
in the pthread_cond_t structure needs to be adjusted. */
return EINVAL;

/* Make sure the value fits in the bits we reserved. */
assert (clock_id < (1 << COND_CLOCK_BITS));

int *valuep = &((struct pthread_condattr *) attr)->value;

*valuep = (*valuep & ~0xfe) | (clock_id << 1);
*valuep = (*valuep & ~(1 << (COND_CLOCK_BITS + 1)) & ~1) | (clock_id << 1);

return 0;
}
14 changes: 13 additions & 1 deletion nptl/sysdeps/pthread/pthread_cond_timedwait.c
Expand Up @@ -67,6 +67,7 @@ __pthread_cond_timedwait (cond, mutex, abstime)
/* We have one new user of the condvar. */
++cond->__data.__total_seq;
++cond->__data.__futex;
cond->__data.__nwaiters += 1 << COND_CLOCK_BITS;

/* Remember the mutex we are using here. If there is already a
different address store this is a bad user bug. Do not store
Expand Down Expand Up @@ -98,7 +99,8 @@ __pthread_cond_timedwait (cond, mutex, abstime)
INTERNAL_SYSCALL_DECL (err);
int ret;
ret = INTERNAL_SYSCALL (clock_gettime, err, 2,
cond->__data.__clock, &rt);
cond->__data.__nwaiters & COND_CLOCK_BITS,
&rt);
# ifndef __ASSUME_POSIX_TIMERS
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (ret, err), 0))
{
Expand Down Expand Up @@ -185,6 +187,16 @@ __pthread_cond_timedwait (cond, mutex, abstime)
++cond->__data.__woken_seq;

bc_out:

cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS;

/* If pthread_cond_destroy was called on this variable already,
notify the pthread_cond_destroy caller all waiters have left
and it can be successfully destroyed. */
if (cond->__data.__total_seq == -1ULL
&& cond->__data.__nwaiters < (1 << COND_CLOCK_BITS))
lll_futex_wake (&cond->__data.__nwaiters, 1);

/* We are done with the condvar. */
lll_mutex_unlock (cond->__data.__lock);

Expand Down
28 changes: 27 additions & 1 deletion nptl/sysdeps/pthread/pthread_cond_wait.c
Expand Up @@ -42,6 +42,7 @@ __condvar_cleanup (void *arg)
{
struct _condvar_cleanup_buffer *cbuffer =
(struct _condvar_cleanup_buffer *) arg;
unsigned int destroying;

/* We are going to modify shared data. */
lll_mutex_lock (cbuffer->cond->__data.__lock);
Expand All @@ -55,11 +56,25 @@ __condvar_cleanup (void *arg)
++cbuffer->cond->__data.__futex;
}

cbuffer->cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS;

/* If pthread_cond_destroy was called on this variable already,
notify the pthread_cond_destroy caller all waiters have left
and it can be successfully destroyed. */
destroying = 0;
if (cbuffer->cond->__data.__total_seq == -1ULL
&& cbuffer->cond->__data.__nwaiters < (1 << COND_CLOCK_BITS))
{
lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1);
destroying = 1;
}

/* We are done. */
lll_mutex_unlock (cbuffer->cond->__data.__lock);

/* Wake everybody to make sure no condvar signal gets lost. */
lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX);
if (! destroying)
lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX);

/* Get the mutex before returning unless asynchronous cancellation
is in effect. */
Expand Down Expand Up @@ -90,6 +105,7 @@ __pthread_cond_wait (cond, mutex)
/* We have one new user of the condvar. */
++cond->__data.__total_seq;
++cond->__data.__futex;
cond->__data.__nwaiters += 1 << COND_CLOCK_BITS;

/* Remember the mutex we are using here. If there is already a
different address store this is a bad user bug. Do not store
Expand Down Expand Up @@ -145,6 +161,16 @@ __pthread_cond_wait (cond, mutex)
++cond->__data.__woken_seq;

bc_out:

cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS;

/* If pthread_cond_destroy was called on this varaible already,
notify the pthread_cond_destroy caller all waiters have left
and it can be successfully destroyed. */
if (cond->__data.__total_seq == -1ULL
&& cond->__data.__nwaiters < (1 << COND_CLOCK_BITS))
lll_futex_wake (&cond->__data.__nwaiters, 1);

/* We are done with the condvar. */
lll_mutex_unlock (cond->__data.__lock);

Expand Down
2 changes: 1 addition & 1 deletion nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
Expand Up @@ -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];
Expand Down
2 changes: 1 addition & 1 deletion nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h
Expand Up @@ -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];
Expand Down

0 comments on commit 73f7c32

Please sign in to comment.