diff options
author | Neal H. Walfield <neal@gnu.org> | 2007-11-20 16:23:24 +0000 |
---|---|---|
committer | Thomas Schwinge <tschwinge@gnu.org> | 2009-04-07 23:05:35 +0200 |
commit | 43e3246eb6a26162ef931dadcd4a8a649c57289b (patch) | |
tree | 80cac95ce1c8b948f2a2a4ff980385b0dcbeec43 /sysdeps | |
parent | 7373049ff9aac3dbfe088da7d30b2724d15fa67a (diff) | |
parent | 8caaa8379e5a1500863792514189d6e8f414dcaf (diff) |
2007-11-20 Neal H. Walfield <neal@gnu.org>
Merge changes from mainline Hurd. Update L4 bits to compile with
those changes.
* sysdeps/l4/pt-block.c (__pthread_block): Call l4_receive, not
L4_Receive.
* sysdeps/l4/pt-create-np.c (pthread_create_from_l4_tid_np): Don't
pass TID to __pthread_create_internal. Emit a warning.
* sysdeps/l4/pt-stack-alloc.c (allocate_page): Remove function.
(__pthread_stack_alloc): Don't require that STACKSIZE is equal to
__pthread_stacksize. Call mmap.
* sysdeps/l4/pt-thread-halt.c (__pthread_thread_halt): Take
additional argument, need_dealloc. Call __pthread_dealloc. Stop
the thread.
* sysdeps/l4/hurd/pt-sysdep.c (init_routine): When calling
__pthread_create_internal, don't pass the tid.
* tests/test-1.c (main): Use pthread_mutex_init, not
PTHREAD_MUTEX_INITIALIZER.
* pthread/pt-alloc.c: Don't include <bits/atomic.h>. Include
<atomic.h>.
(__pthread_free_threads): Make it an atomicptr_t, not an
__atomicptr_t.
(__pthread_alloc): Don't use __atomicptr_compare_and_swap, use
atomic_compare_and_exchange_val_acq.
* pthread/pt-create.c: Don't include <bits/atomic.h>. Include
<atomic.h>.
(__pthread_total): Make it an atomic_fast32_t, not an __atomic_t.
(__pthread_create_internal): Use atomic_increment and
atomic_decrement, not __atomic_inc and __atomic_dec.
* pthread/pt-dealloc.c: Don't include <bits/atomic.h>. Include
<atomic.h>.
(__pthread_free_threads): Make it an atomicptr_t, not an
__atomicptr_t.
(__pthread_dealloc): Use atomic_compare_and_exchange_val_acq, not
__atomicptr_compare_and_swap.
* pthread/pt-exit.c: Don't include <bits/atomic.h>. Include
<atomic.h>.
(pthread_exit): Use atomic_decrement_and_test, not
__atomic_dec_and_test.
* pthread/pt-internal.h: Don't include <bits/atomic.h>. Include
<atomic.h>.
(__pthread_total): Make it an atomic_fast32_t, not an __atomic_t.
* sysdeps/powerpc/bits/atomic.h: Remove file.
* sysdeps/ia32/bits/atomic.h: Likewise.
Diffstat (limited to 'sysdeps')
49 files changed, 712 insertions, 370 deletions
diff --git a/sysdeps/generic/bits/condition.h b/sysdeps/generic/bits/condition.h index a194b05d..f3b09be4 100644 --- a/sysdeps/generic/bits/condition.h +++ b/sysdeps/generic/bits/condition.h @@ -1,5 +1,5 @@ /* Condition type. Generic version. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 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 diff --git a/sysdeps/generic/bits/mutex.h b/sysdeps/generic/bits/mutex.h index ecbcff8b..1aaf80ed 100644 --- a/sysdeps/generic/bits/mutex.h +++ b/sysdeps/generic/bits/mutex.h @@ -1,5 +1,5 @@ /* Mutex type. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 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 @@ -52,8 +52,7 @@ struct __pthread_mutex /* Initializer for a mutex. N.B. this also happens to be compatible with the cthread mutex initializer. */ # define __PTHREAD_MUTEX_INITIALIZER \ - { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, \ - NULL, 0, 0 } + { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0, 0 } # endif #endif /* Not __pthread_mutex_defined. */ @@ -63,76 +62,6 @@ struct __pthread_mutex #include <errno.h> #include <stddef.h> -#ifdef __USE_EXTERN_INLINES - -# ifndef _EXTERN_INLINE -# define _EXTERN_INLINE extern __inline -# endif - -_EXTERN_INLINE int -pthread_mutex_init (struct __pthread_mutex *__mutex, - const pthread_mutexattr_t *attr) -{ - extern int _pthread_mutex_init (struct __pthread_mutex *, - const pthread_mutexattr_t *); - - if (attr) - return _pthread_mutex_init (__mutex, attr); - - *__mutex = (struct __pthread_mutex) __PTHREAD_MUTEX_INITIALIZER; - return 0; -} - -_EXTERN_INLINE int -pthread_mutex_destroy (struct __pthread_mutex *__mutex) -{ - extern int _pthread_mutex_destroy (struct __pthread_mutex *); - - if (__mutex->attr || __mutex->data) - return _pthread_mutex_destroy (__mutex); - - return 0; -} - -_EXTERN_INLINE int -__pthread_mutex_lock (struct __pthread_mutex *__mutex) -{ - extern int _pthread_mutex_lock (struct __pthread_mutex *); - - if (__mutex->attr == NULL - && __mutex->data == NULL - && __pthread_spin_trylock (&__mutex->__held) == 0) - return 0; - - return _pthread_mutex_lock (__mutex); -} - -extern inline int -__pthread_mutex_trylock (struct __pthread_mutex *__mutex) -{ - extern int _pthread_mutex_trylock (struct __pthread_mutex *); - - if (__mutex->attr == NULL - && __mutex->data == NULL) - return __pthread_spin_trylock (&__mutex->__held); - - return _pthread_mutex_trylock (__mutex); -} - -extern inline int -pthread_mutex_lock (struct __pthread_mutex *__mutex) -{ - return __pthread_mutex_lock (__mutex); -} - -extern inline int -pthread_mutex_trylock (struct __pthread_mutex *__mutex) -{ - return __pthread_mutex_trylock (__mutex); -} - -#endif /* Use extern inlines. */ - #endif #endif /* bits/mutex.h */ diff --git a/sysdeps/generic/bits/pthread.h b/sysdeps/generic/bits/pthread.h index 740325d0..3f9df13d 100644 --- a/sysdeps/generic/bits/pthread.h +++ b/sysdeps/generic/bits/pthread.h @@ -24,7 +24,7 @@ typedef int pthread_t; /* Return true if __T1 and __T2 both name the same thread. Otherwise, false. */ -extern inline int +extern __inline int pthread_equal (pthread_t __t1, pthread_t __t2) { return __t1 == __t2; diff --git a/sysdeps/generic/bits/rwlock.h b/sysdeps/generic/bits/rwlock.h index d089b0c6..696f9c25 100644 --- a/sysdeps/generic/bits/rwlock.h +++ b/sysdeps/generic/bits/rwlock.h @@ -1,5 +1,5 @@ /* rwlock type. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -40,34 +40,7 @@ struct __pthread_rwlock /* Initializer for a rwlock. */ #define __PTHREAD_RWLOCK_INITIALIZER \ - ((struct __pthread_rwlock) \ - { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0 }) + { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0 } -_EXTERN_INLINE int -pthread_rwlock_init (struct __pthread_rwlock *__rwlock, - const struct __pthread_rwlockattr *__attr) -{ - extern int _pthread_rwlock_init (struct __pthread_rwlock *, - const struct __pthread_rwlockattr *); - - if (__attr) - return _pthread_rwlock_init (__rwlock, __attr); - - *__rwlock = __PTHREAD_RWLOCK_INITIALIZER; - return 0; -} - -_EXTERN_INLINE int -pthread_rwlock_destroy (struct __pthread_rwlock *__rwlock) -{ - extern int _pthread_rwlock_destroy (struct __pthread_rwlock *); - - if (__rwlock->__attr - || __rwlock->__data) - return _pthread_rwlock_destroy (__rwlock); - - return 0; -} - #endif /* bits/rwlock.h */ diff --git a/sysdeps/generic/bits/semaphore.h b/sysdeps/generic/bits/semaphore.h new file mode 100644 index 00000000..b53f47e3 --- /dev/null +++ b/sysdeps/generic/bits/semaphore.h @@ -0,0 +1,43 @@ +/* Semaphore type. Generic version. + 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 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. */ + +#ifndef _BITS_SEMAPHORE_H +#define _BITS_SEMAPHORE_H 1 + +#ifndef _SEMAPHORE_H +#error Never include <bits/semaphore.h> directly. +#endif + +#include <pthread.h> + +/* User visible part of a semaphore. */ +struct __semaphore + { + __pthread_spinlock_t __lock; + struct __pthread *__queue; + int __pshared; + int __value; + void *__data; + }; + +/* Initializer for a semaphore. */ +#define __SEMAPHORE_INITIALIZER(pshared, value) \ + { __SPIN_LOCK_INITIALIZER, NULL, (pshared), (value), NULL } + +#endif /* bits/mutex.h */ diff --git a/sysdeps/generic/pt-barrier-init.c b/sysdeps/generic/pt-barrier-init.c index 57911d51..c42b3bb6 100644 --- a/sysdeps/generic/pt-barrier-init.c +++ b/sysdeps/generic/pt-barrier-init.c @@ -1,5 +1,5 @@ /* pthread_barrier_init. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -28,8 +28,6 @@ pthread_barrier_init (pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned count) { - assert (attr->pshared == PTHREAD_PROCESS_PRIVATE); - if (count == 0) return EINVAL; @@ -39,5 +37,17 @@ pthread_barrier_init (pthread_barrier_t *barrier, barrier->pending = count; barrier->count = count; + if (! attr + || memcmp (attr, &__pthread_default_barrierattr, sizeof (*attr) == 0)) + /* Use the default attributes. */ + return 0; + + /* Non-default attributes. */ + + barrier->attr = malloc (sizeof *attr); + if (! barrier->attr) + return ENOMEM; + + *barrier->attr = *attr; return 0; } diff --git a/sysdeps/generic/pt-cond-init.c b/sysdeps/generic/pt-cond-init.c index a01a94ba..b9e9fb7a 100644 --- a/sysdeps/generic/pt-cond-init.c +++ b/sysdeps/generic/pt-cond-init.c @@ -19,6 +19,7 @@ #include <pthread.h> #include <assert.h> +#include <string.h> #include <pt-internal.h> @@ -26,9 +27,19 @@ int pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr) { - if (attr) - assert (attr->pshared == PTHREAD_PROCESS_PRIVATE); + *cond = (pthread_cond_t) __PTHREAD_COND_INITIALIZER; - *cond = (struct __pthread_cond) __PTHREAD_COND_INITIALIZER; + if (! attr + || memcmp (attr, &__pthread_default_condattr, sizeof (*attr) == 0)) + /* Use the default attributes. */ + return 0; + + /* Non-default attributes. */ + + cond->__attr = malloc (sizeof *attr); + if (! cond->__attr) + return ENOMEM; + + *cond->__attr = *attr; return 0; } diff --git a/sysdeps/generic/pt-cond-timedwait.c b/sysdeps/generic/pt-cond-timedwait.c index 4abeb71c..c10bdb30 100644 --- a/sysdeps/generic/pt-cond-timedwait.c +++ b/sysdeps/generic/pt-cond-timedwait.c @@ -1,5 +1,5 @@ /* Wait on a condition. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 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 @@ -58,6 +58,9 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond, __pthread_mutex_lock (mutex); } + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + struct __pthread *self = _pthread_self (); /* Add ourselves to the list of waiters. */ @@ -74,8 +77,6 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond, if (abstime) { - error_t err; - err = __pthread_timedblock (self, abstime); if (err) /* We timed out. We may need to disconnect ourself from the @@ -91,8 +92,6 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond, if (self->prevp) __pthread_dequeue (self); __pthread_spin_unlock (&mutex->__lock); - - return err; } } else diff --git a/sysdeps/generic/pt-mutex-destroy.c b/sysdeps/generic/pt-mutex-destroy.c index d9fb59ce..72faefe6 100644 --- a/sysdeps/generic/pt-mutex-destroy.c +++ b/sysdeps/generic/pt-mutex-destroy.c @@ -32,4 +32,4 @@ _pthread_mutex_destroy (pthread_mutex_t *mutex) return 0; } -weak_alias (_pthread_mutex_destroy, pthread_mutex_destroy); +strong_alias (_pthread_mutex_destroy, pthread_mutex_destroy); diff --git a/sysdeps/generic/pt-mutex-init.c b/sysdeps/generic/pt-mutex-init.c index 100f485f..da1781bf 100644 --- a/sysdeps/generic/pt-mutex-init.c +++ b/sysdeps/generic/pt-mutex-init.c @@ -1,5 +1,5 @@ /* Initialize a mutex. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 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 @@ -28,7 +28,7 @@ int _pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { - *mutex = (struct __pthread_mutex) __PTHREAD_MUTEX_INITIALIZER; + *mutex = (pthread_mutex_t) __PTHREAD_MUTEX_INITIALIZER; if (! attr || memcmp (attr, &__pthread_default_mutexattr, sizeof (*attr) == 0)) @@ -45,4 +45,4 @@ _pthread_mutex_init (pthread_mutex_t *mutex, return 0; } -weak_alias (_pthread_mutex_init, pthread_mutex_init); +strong_alias (_pthread_mutex_init, pthread_mutex_init); diff --git a/sysdeps/generic/pt-mutex-lock.c b/sysdeps/generic/pt-mutex-lock.c index 58d3827c..60fc55ab 100644 --- a/sysdeps/generic/pt-mutex-lock.c +++ b/sysdeps/generic/pt-mutex-lock.c @@ -33,5 +33,5 @@ __pthread_mutex_lock (struct __pthread_mutex *mutex) return __pthread_mutex_timedlock_internal (mutex, 0); } -weak_alias (__pthread_mutex_lock, _pthread_mutex_lock); -weak_alias (__pthread_mutex_lock, pthread_mutex_lock); +strong_alias (__pthread_mutex_lock, _pthread_mutex_lock); +strong_alias (__pthread_mutex_lock, pthread_mutex_lock); diff --git a/sysdeps/generic/pt-mutex-timedlock.c b/sysdeps/generic/pt-mutex-timedlock.c index 3603986c..5e222bd3 100644 --- a/sysdeps/generic/pt-mutex-timedlock.c +++ b/sysdeps/generic/pt-mutex-timedlock.c @@ -1,5 +1,5 @@ /* Lock a mutex with a timeout. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 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 @@ -24,13 +24,6 @@ #define LOSE do { * (int *) 0 = 0; } while (1) -int -pthread_mutex_timedlock (struct __pthread_mutex *mutex, - const struct timespec *abstime) -{ - return __pthread_mutex_timedlock_internal (mutex, abstime); -} - /* Try to lock MUTEX, block until *ABSTIME if it is already held. As a GNU extension, if TIMESPEC is NULL then wait forever. */ int @@ -96,6 +89,9 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, } } + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + /* Add ourselves to the queue. */ __pthread_enqueue (&mutex->__queue, self); __pthread_spin_unlock (&mutex->__lock); @@ -146,3 +142,10 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, return 0; } + +int +pthread_mutex_timedlock (struct __pthread_mutex *mutex, + const struct timespec *abstime) +{ + return __pthread_mutex_timedlock_internal (mutex, abstime); +} diff --git a/sysdeps/generic/pt-mutex-trylock.c b/sysdeps/generic/pt-mutex-trylock.c index b3c3fe3a..d56f6e1c 100644 --- a/sysdeps/generic/pt-mutex-trylock.c +++ b/sysdeps/generic/pt-mutex-trylock.c @@ -1,5 +1,5 @@ /* Try to Lock a mutex. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -23,7 +23,7 @@ #define LOSE do { * (int *) 0 = 0; } while (1) -/* Lock MUTEX, block if we can't get it. */ +/* Lock MUTEX, return EBUSY if we can't get it. */ int __pthread_mutex_trylock (struct __pthread_mutex *mutex) { @@ -65,8 +65,9 @@ __pthread_mutex_trylock (struct __pthread_mutex *mutex) break; case PTHREAD_MUTEX_ERRORCHECK: - if (mutex->owner == self) - err = EDEADLK; + /* We could check if MUTEX->OWNER is SELF, however, POSIX + does not permit pthread_mutex_trylock to return EDEADLK + instead of EBUSY, only pthread_mutex_lock. */ break; case PTHREAD_MUTEX_RECURSIVE: @@ -82,8 +83,10 @@ __pthread_mutex_trylock (struct __pthread_mutex *mutex) } } + __pthread_spin_unlock (&mutex->__lock); + return err; } -weak_alias (__pthread_mutex_trylock, _pthread_mutex_trylock); -weak_alias (__pthread_mutex_trylock, pthread_mutex_trylock); +strong_alias (__pthread_mutex_trylock, _pthread_mutex_trylock); +strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock); diff --git a/sysdeps/generic/pt-mutex-unlock.c b/sysdeps/generic/pt-mutex-unlock.c index bbbe2b8f..2f719d3e 100644 --- a/sysdeps/generic/pt-mutex-unlock.c +++ b/sysdeps/generic/pt-mutex-unlock.c @@ -78,5 +78,5 @@ __pthread_mutex_unlock (pthread_mutex_t *mutex) return 0; } -weak_alias (__pthread_mutex_unlock, _pthread_mutex_unlock); -weak_alias (__pthread_mutex_unlock, pthread_mutex_unlock); +strong_alias (__pthread_mutex_unlock, _pthread_mutex_unlock); +strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock); diff --git a/sysdeps/generic/pt-rwlock-destroy.c b/sysdeps/generic/pt-rwlock-destroy.c index f63c84d9..034d9300 100644 --- a/sysdeps/generic/pt-rwlock-destroy.c +++ b/sysdeps/generic/pt-rwlock-destroy.c @@ -26,4 +26,4 @@ _pthread_rwlock_destroy (pthread_rwlock_t *rwlock) return 0; } -weak_alias (_pthread_rwlock_destroy, pthread_rwlock_destroy); +strong_alias (_pthread_rwlock_destroy, pthread_rwlock_destroy); diff --git a/sysdeps/generic/pt-rwlock-init.c b/sysdeps/generic/pt-rwlock-init.c index 8fe87644..8aa495ec 100644 --- a/sysdeps/generic/pt-rwlock-init.c +++ b/sysdeps/generic/pt-rwlock-init.c @@ -1,5 +1,5 @@ /* Initialize a rwlock. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -18,14 +18,28 @@ Boston, MA 02111-1307, USA. */ #include <pthread.h> +#include <string.h> #include <pt-internal.h> int _pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) { - *rwlock = __PTHREAD_RWLOCK_INITIALIZER; + *rwlock = (pthread_rwlock_t) __PTHREAD_RWLOCK_INITIALIZER; + + if (! attr + || memcmp (attr, &__pthread_default_rwlockattr, sizeof (*attr) == 0)) + /* Use the default attributes. */ + return 0; + + /* Non-default attributes. */ + + rwlock->__attr = malloc (sizeof *attr); + if (! rwlock->__attr) + return ENOMEM; + + *rwlock->__attr = *attr; return 0; } -weak_alias (_pthread_rwlock_init, pthread_rwlock_init); +strong_alias (_pthread_rwlock_init, pthread_rwlock_init); diff --git a/sysdeps/generic/pt-rwlock-rdlock.c b/sysdeps/generic/pt-rwlock-rdlock.c index d060c38f..480cf489 100644 --- a/sysdeps/generic/pt-rwlock-rdlock.c +++ b/sysdeps/generic/pt-rwlock-rdlock.c @@ -1,5 +1,5 @@ /* Acquire a rwlock for reading. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -21,7 +21,7 @@ #include <pt-internal.h> /* Implemented in pt-rwlock-timedrdlock.c. */ -extern int __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *mutex, +extern int __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock, const struct timespec *abstime); /* Acquire RWLOCK for reading, block if we can't get it. */ diff --git a/sysdeps/generic/pt-rwlock-timedrdlock.c b/sysdeps/generic/pt-rwlock-timedrdlock.c index 85cb9468..ba610fa5 100644 --- a/sysdeps/generic/pt-rwlock-timedrdlock.c +++ b/sysdeps/generic/pt-rwlock-timedrdlock.c @@ -1,5 +1,5 @@ /* Acquire a rwlock for reading. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -22,13 +22,6 @@ #include <pt-internal.h> -int -pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock, - const struct timespec *abstime) -{ - return __pthread_rwlock_timedrdlock_internal (rwlock, abstime); -} - /* Acquire the rwlock *RWLOCK for reading blocking until *ABSTIME if it is already held. As a GNU extension, if TIMESPEC is NULL then wait forever. */ @@ -66,6 +59,9 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock, /* Better be blocked by a writer. */ assert (rwlock->readers == 0); + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + self = _pthread_self (); /* Add ourself to the queue. */ @@ -108,3 +104,10 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock, return 0; } + +int +pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock, + const struct timespec *abstime) +{ + return __pthread_rwlock_timedrdlock_internal (rwlock, abstime); +} diff --git a/sysdeps/generic/pt-rwlock-timedwrlock.c b/sysdeps/generic/pt-rwlock-timedwrlock.c index edf6413f..04eab51f 100644 --- a/sysdeps/generic/pt-rwlock-timedwrlock.c +++ b/sysdeps/generic/pt-rwlock-timedwrlock.c @@ -1,5 +1,5 @@ /* Acquire a rwlock for writing. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -22,13 +22,6 @@ #include <pt-internal.h> -int -pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock, - const struct timespec *abstime) -{ - return __pthread_rwlock_timedwrlock_internal (rwlock, abstime); -} - /* Acquire RWLOCK for writing blocking until *ABSTIME if we cannot get it. As a special GNU extension, if ABSTIME is NULL then the wait shall not time out. */ @@ -52,6 +45,9 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock, /* The lock is busy. */ + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + self = _pthread_self (); /* Add ourselves to the queue. */ @@ -90,3 +86,10 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock, return 0; } + +int +pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock, + const struct timespec *abstime) +{ + return __pthread_rwlock_timedwrlock_internal (rwlock, abstime); +} diff --git a/sysdeps/generic/pt-setschedparam.c b/sysdeps/generic/pt-setschedparam.c index 6b624a31..a70b0796 100644 --- a/sysdeps/generic/pt-setschedparam.c +++ b/sysdeps/generic/pt-setschedparam.c @@ -1,5 +1,5 @@ /* Set the scheduling parameters for a thread. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -21,7 +21,7 @@ #include <pt-internal.h> int -pthread_setschedparam (pthread_t thread, int *policy, +pthread_setschedparam (pthread_t thread, int policy, const struct sched_param *param) { return ENOSYS; diff --git a/sysdeps/generic/sem-close.c b/sysdeps/generic/sem-close.c new file mode 100644 index 00000000..9f48032f --- /dev/null +++ b/sysdeps/generic/sem-close.c @@ -0,0 +1,32 @@ +/* Close a named semaphore. Generic version. + 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 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 <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_close (sem_t *sem) +{ + errno = EOPNOTSUPP; + return -1; +} + +strong_alias (__sem_close, sem_close); diff --git a/sysdeps/generic/sem-destroy.c b/sysdeps/generic/sem-destroy.c new file mode 100644 index 00000000..985f4ad3 --- /dev/null +++ b/sysdeps/generic/sem-destroy.c @@ -0,0 +1,38 @@ +/* Destroy a semaphore. Generic version. + 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 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 <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_destroy (sem_t *sem) +{ + if (sem->__queue) + /* There are threads waiting on *SEM. */ + { + errno = EBUSY; + return -1; + } + + return 0; +} + +strong_alias (__sem_destroy, sem_destroy); diff --git a/sysdeps/generic/sem-getvalue.c b/sysdeps/generic/sem-getvalue.c new file mode 100644 index 00000000..8e418e38 --- /dev/null +++ b/sysdeps/generic/sem-getvalue.c @@ -0,0 +1,33 @@ +/* Get the value of a semaphore. Generic version. + 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 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 <semaphore.h> +#include <pt-internal.h> + +int +__sem_getvalue (sem_t *restrict sem, int *restrict value) +{ + __pthread_spin_lock (&sem->__lock); + *value = sem->__value; + __pthread_spin_unlock (&sem->__lock); + + return 0; +} + +strong_alias (__sem_getvalue, sem_getvalue); diff --git a/sysdeps/generic/sem-init.c b/sysdeps/generic/sem-init.c new file mode 100644 index 00000000..6c6d79e7 --- /dev/null +++ b/sysdeps/generic/sem-init.c @@ -0,0 +1,46 @@ +/* Initialize a semaphore. Generic version. + 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 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 <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_init (sem_t *sem, int pshared, unsigned value) +{ + if (pshared != 0) + { + errno = EOPNOTSUPP; + return -1; + } + +#ifdef SEM_VALUE_MAX + if (value > SEM_VALUE_MAX) + { + errno = EINVAL; + return -1; + } +#endif + + *sem = (sem_t) __SEMAPHORE_INITIALIZER (pshared, value); + return 0; +} + +strong_alias (__sem_init, sem_init); diff --git a/sysdeps/generic/sem-open.c b/sysdeps/generic/sem-open.c new file mode 100644 index 00000000..9eb13aae --- /dev/null +++ b/sysdeps/generic/sem-open.c @@ -0,0 +1,32 @@ +/* Open a named semaphore. Generic version. + 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 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 <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +sem_t * +__sem_open (const char *name, int open_flags, ...) +{ + errno = EOPNOTSUPP; + return SEM_FAILED; +} + +strong_alias (__sem_open, sem_open); diff --git a/sysdeps/generic/sem-post.c b/sysdeps/generic/sem-post.c new file mode 100644 index 00000000..0e20ea7a --- /dev/null +++ b/sysdeps/generic/sem-post.c @@ -0,0 +1,62 @@ +/* Post a semaphore. Generic version. + 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 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 <semaphore.h> +#include <assert.h> + +#include <pt-internal.h> + +int +__sem_post (sem_t *sem) +{ + struct __pthread *wakeup; + + __pthread_spin_lock (&sem->__lock); + if (sem->__value > 0) + /* Do a quick up. */ + { + assert (! sem->__queue); + sem->__value ++; + __pthread_spin_unlock (&sem->__lock); + return 0; + } + + if (! sem->__queue) + /* No one waiting. */ + { + sem->__value = 1; + __pthread_spin_unlock (&sem->__lock); + return 0; + } + + /* Wake someone up. */ + + /* First dequeue someone. */ + wakeup = sem->__queue; + __pthread_dequeue (wakeup); + + /* Then drop the lock and transfer control. */ + __pthread_spin_unlock (&sem->__lock); + + __pthread_wakeup (wakeup); + + return 0; +} + +strong_alias (__sem_post, sem_post); diff --git a/sysdeps/generic/sem-timedwait.c b/sysdeps/generic/sem-timedwait.c new file mode 100644 index 00000000..d01bfdb0 --- /dev/null +++ b/sysdeps/generic/sem-timedwait.c @@ -0,0 +1,92 @@ +/* Wait on a semaphore with a timeout. Generic version. + 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 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 <semaphore.h> +#include <error.h> +#include <errno.h> +#include <assert.h> + +#include <pt-internal.h> + +int +__sem_timedwait_internal (sem_t *restrict sem, + const struct timespec *restrict timeout) +{ + struct __pthread *self; + + __pthread_spin_lock (&sem->__lock); + if (sem->__value > 0) + /* Successful down. */ + { + sem->__value --; + __pthread_spin_unlock (&sem->__lock); + return 0; + } + + if (timeout && (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000)) + { + errno = EINVAL; + return -1; + } + + /* Add ourselves to the queue. */ + self = _pthread_self (); + + __pthread_enqueue (&sem->__queue, self); + __pthread_spin_unlock (&sem->__lock); + + /* Block the thread. */ + if (timeout) + { + error_t err; + + err = __pthread_timedblock (self, timeout); + if (err) + /* We timed out. We may need to disconnect ourself from the + waiter queue. + + FIXME: What do we do if we get a wakeup message before we + disconnect ourself? It may remain until the next time we + block. */ + { + assert (err == ETIMEDOUT); + + __pthread_spin_lock (&sem->__lock); + if (self->prevp) + __pthread_dequeue (self); + __pthread_spin_unlock (&sem->__lock); + + errno = err; + return -1; + } + } + else + __pthread_block (self); + + return 0; +} + +int +__sem_timedwait (sem_t *restrict sem, + const struct timespec *restrict timeout) +{ + return __sem_timedwait_internal (sem, timeout); +} + +strong_alias (__sem_timedwait, sem_timedwait); diff --git a/sysdeps/generic/sem-trywait.c b/sysdeps/generic/sem-trywait.c new file mode 100644 index 00000000..199f317b --- /dev/null +++ b/sysdeps/generic/sem-trywait.c @@ -0,0 +1,42 @@ +/* Lock a semaphore if it does not require blocking. Generic version. + 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 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 <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_trywait (sem_t *sem) +{ + __pthread_spin_lock (&sem->__lock); + if (sem->__value > 0) + /* Successful down. */ + { + sem->__value --; + __pthread_spin_unlock (&sem->__lock); + return 0; + } + __pthread_spin_unlock (&sem->__lock); + + errno = EAGAIN; + return -1; +} + +strong_alias (__sem_trywait, sem_trywait); diff --git a/sysdeps/generic/sem-unlink.c b/sysdeps/generic/sem-unlink.c new file mode 100644 index 00000000..519f4f7b --- /dev/null +++ b/sysdeps/generic/sem-unlink.c @@ -0,0 +1,32 @@ +/* Unlink a named semaphore. Generic version. + 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 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 <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_unlink (const char *name) +{ + errno = EOPNOTSUPP; + return -1; +} + +strong_alias (__sem_unlink, sem_unlink); diff --git a/sysdeps/generic/sem-wait.c b/sysdeps/generic/sem-wait.c new file mode 100644 index 00000000..50752f32 --- /dev/null +++ b/sysdeps/generic/sem-wait.c @@ -0,0 +1,32 @@ +/* Wait on a semaphore. Generic version. + 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 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 <semaphore.h> +#include <pt-internal.h> + +extern int __sem_timedwait_internal (sem_t *restrict sem, + const struct timespec *restrict timeout); + +int +__sem_wait (sem_t *sem) +{ + return __sem_timedwait_internal (sem, 0); +} + +strong_alias (__sem_wait, sem_wait); diff --git a/sysdeps/hurd/pt-destroy-specific.c b/sysdeps/hurd/pt-destroy-specific.c index 2006f2b8..23c7fbc0 100644 --- a/sysdeps/hurd/pt-destroy-specific.c +++ b/sysdeps/hurd/pt-destroy-specific.c @@ -71,10 +71,9 @@ __pthread_destroy_specific (struct __pthread *thread) /* This may take a very long time. Let those blocking on pthread_key_create or pthread_key_delete make progress. */ - /* FIXME what should we do with this one? */ - /* sched_yield (); */ + sched_yield (); } - + hurd_ihash_free (thread->thread_specifics); thread->thread_specifics = 0; } diff --git a/sysdeps/hurd/pt-setspecific.c b/sysdeps/hurd/pt-setspecific.c index bd752250..89ca4d7f 100644 --- a/sysdeps/hurd/pt-setspecific.c +++ b/sysdeps/hurd/pt-setspecific.c @@ -30,12 +30,12 @@ pthread_setspecific (pthread_key_t key, const void *value) if (! self->thread_specifics) { - err = ihash_create (&self->thread_specifics); + err = hurd_ihash_create (&self->thread_specifics, HURD_IHASH_NO_LOCP); if (err) return ENOMEM; } - err = ihash_add (self->thread_specifics, key, (void *) value, 0); + err = hurd_ihash_add (self->thread_specifics, key, (void *) value); if (err) return ENOMEM; diff --git a/sysdeps/ia32/bits/atomic.h b/sysdeps/ia32/bits/atomic.h deleted file mode 100644 index 0dfc1f60..00000000 --- a/sysdeps/ia32/bits/atomic.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Atomic operations. i386 version. - Copyright (C) 2000 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. */ - -#ifndef _BITS_ATOMIC_H -#define _BITS_ATOMIC_H 1 - -typedef __volatile int __atomic_t; - -static inline void -__atomic_inc (__atomic_t *__var) -{ - __asm__ __volatile ("lock; incl %0" : "=m" (*__var) : "m" (*__var)); -} - -static inline void -__atomic_dec (__atomic_t *__var) -{ - __asm__ __volatile ("lock; decl %0" : "=m" (*__var) : "m" (*__var)); -} - -static inline int -__atomic_dec_and_test (__atomic_t *__var) -{ - unsigned char __ret; - - __asm__ __volatile ("lock; decl %0; sete %1" - : "=m" (*__var), "=qm" (__ret) : "m" (*__var)); - return __ret != 0; -} - -/* We assume that an __atomicptr_t is only used for pointers to - word-aligned objects, and use the lowest bit for a simple lock. */ -typedef __volatile int * __atomicptr_t; - -/* Actually we don't implement that yet, and assume that we run on - something that has the i486 instruction set. */ -static inline int -__atomicptr_compare_and_swap (__atomicptr_t *__ptr, void *__oldval, - void * __newval) -{ - char __ret; - int __dummy; - - __asm__ __volatile ("lock; cmpxchgl %3, %1; sete %0" - : "=q" (__ret), "=m" (*__ptr), "=a" (__dummy) - : "r" (__newval), "m" (*__ptr), "a" (__oldval)); - return __ret; -} - -#endif diff --git a/sysdeps/l4/hurd/pt-sysdep.c b/sysdeps/l4/hurd/pt-sysdep.c index f23a137a..265592ca 100644 --- a/sysdeps/l4/hurd/pt-sysdep.c +++ b/sysdeps/l4/hurd/pt-sysdep.c @@ -43,7 +43,7 @@ init_routine (void) __pthread_initialize (); /* Create the pthread structure for the main thread (i.e. us). */ - err = __pthread_create_internal (&thread, 0, 0, 0, 0); + err = __pthread_create_internal (&thread, 0, 0, 0); assert_perror (err); __pthread_initialize (); diff --git a/sysdeps/l4/pt-block.c b/sysdeps/l4/pt-block.c index 5992dc14..933cc285 100644 --- a/sysdeps/l4/pt-block.c +++ b/sysdeps/l4/pt-block.c @@ -25,5 +25,5 @@ void __pthread_block (struct __pthread *thread) { - l4_receive (l4_anylocalthread); + L4_Receive (L4_anylocalthread); } diff --git a/sysdeps/l4/pt-create-np.c b/sysdeps/l4/pt-create-np.c index 57c782cc..68b8b004 100644 --- a/sysdeps/l4/pt-create-np.c +++ b/sysdeps/l4/pt-create-np.c @@ -36,7 +36,8 @@ pthread_create_from_l4_tid_np (pthread_t *thread, int err; struct __pthread *pthread; - err = __pthread_create_internal (&pthread, attr, (void *) &tid, +#warning Does not use TID. + err = __pthread_create_internal (&pthread, attr, start_routine, arg); if (! err) *thread = pthread->thread; diff --git a/sysdeps/l4/pt-pool-np.c b/sysdeps/l4/pt-pool-np.c index c72f2eb2..f59a3e2b 100644 --- a/sysdeps/l4/pt-pool-np.c +++ b/sysdeps/l4/pt-pool-np.c @@ -26,13 +26,14 @@ _L4_thread_id_t pool_list = l4_nilthread; /* Add the thread TID to the pthread kernel thread pool. */ int -pthread_pool_add_np (_L4_thread_id_t tid) +pthread_pool_add_np (_L4_thread_id_t tid, bool stop) { __pthread_mutex_lock (&pool_lock); /* FIXME: Do error checking. */ l4_set_user_defined_handle_of (tid, pool_list); pool_list = tid; __pthread_mutex_unlock (&pool_lock); + return 0; } diff --git a/sysdeps/l4/pt-stack-alloc.c b/sysdeps/l4/pt-stack-alloc.c index 9a254141..2ede58fd 100644 --- a/sysdeps/l4/pt-stack-alloc.c +++ b/sysdeps/l4/pt-stack-alloc.c @@ -1,5 +1,5 @@ /* Allocate a new stack. L4 Hurd version. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 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 @@ -19,22 +19,12 @@ #include <l4.h> #include <errno.h> -#include <sys/mman.h> #include <pt-internal.h> -#define __pthread_stacksize __pthread_default_attr.stacksize - - -static void * -allocate_page (void) -{ - return mmap - (NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); -} - +#include <sys/mman.h> -/* Allocate a new stack of size STACKSIZE. If successfull, store the +/* Allocate a new stack of size STACKSIZE. If successful, store the address of the newly allocated stack in *STACKADDR and return 0. Otherwise return an error code (EINVAL for an invalid stack size, EAGAIN if the system lacked the necessary resources to allocate a @@ -42,12 +32,11 @@ allocate_page (void) int __pthread_stack_alloc (void **stackaddr, size_t stacksize) { - if (stacksize != __pthread_stacksize) - return EINVAL; - - *stackaddr = allocate_page (); - if (! *stackaddr) + void *buffer = mmap (0, stacksize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (buffer == MAP_FAILED) return EAGAIN; - + + *stackaddr = buffer; return 0; } diff --git a/sysdeps/l4/pt-thread-halt.c b/sysdeps/l4/pt-thread-halt.c index 991123c2..aa2bf43d 100644 --- a/sysdeps/l4/pt-thread-halt.c +++ b/sysdeps/l4/pt-thread-halt.c @@ -24,8 +24,22 @@ /* Deallocate the kernel thread resources associated with THREAD. */ void -__pthread_thread_halt (struct __pthread *thread) +__pthread_thread_halt (struct __pthread *thread, int need_dealloc) { - l4_stop (thread->threadid); - pthread_pool_add_np (thread->threadid); + l4_thread_id_t tid = thread->threadid; + + if (need_dealloc) + __pthread_dealloc (thread); + + /* There is potential race here: once if TID is the current thread, + then once we add TID to the pool, someone can reallocate it + before we call stop. However, to start the thread, the caller + atomically starts and sets the sp and ip, thus, if the stop has + not yet executed at that point, it won't. */ + + if (tid != l4_myself ()) + l4_stop (tid); + pthread_pool_add_np (tid); + if (tid == l4_myself ()) + l4_stop (tid); } diff --git a/sysdeps/mach/bits/spin-lock.h b/sysdeps/mach/bits/spin-lock.h index f295df7a..e137c244 100644 --- a/sysdeps/mach/bits/spin-lock.h +++ b/sysdeps/mach/bits/spin-lock.h @@ -70,10 +70,10 @@ __pthread_spin_trylock (__pthread_spinlock_t *__lock) return __spin_try_lock (__lock) ? 0 : __EBUSY; } -extern inline int __pthread_spin_lock (__pthread_spinlock_t *__lock); +extern __inline int __pthread_spin_lock (__pthread_spinlock_t *__lock); extern int _pthread_spin_lock (__pthread_spinlock_t *__lock); -extern inline int +extern __inline int __pthread_spin_lock (__pthread_spinlock_t *__lock) { if (__pthread_spin_trylock (__lock)) diff --git a/sysdeps/mach/hurd/ia32/pt-setup.c b/sysdeps/mach/hurd/ia32/pt-setup.c index 9a855847..32ace6ad 100644 --- a/sysdeps/mach/hurd/ia32/pt-setup.c +++ b/sysdeps/mach/hurd/ia32/pt-setup.c @@ -1,5 +1,5 @@ /* Setup thread stack. Hurd/i386 version. - Copyright (C) 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 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 @@ -58,7 +58,7 @@ stack_setup (struct __pthread *thread, top -= __hurd_threadvar_max; /* Save the self pointer. */ - top[_HURD_THREADVAR_THREAD] = thread; + top[_HURD_THREADVAR_THREAD] = (void *) thread; if (start_routine) { diff --git a/sysdeps/mach/hurd/pt-sysdep.c b/sysdeps/mach/hurd/pt-sysdep.c index b42fe255..5e070067 100644 --- a/sysdeps/mach/hurd/pt-sysdep.c +++ b/sysdeps/mach/hurd/pt-sysdep.c @@ -1,5 +1,5 @@ /* System dependent pthreads code. Hurd version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 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 @@ -29,16 +29,16 @@ #include <pt-internal.h> /* Forward. */ -static int init_routine (void); +static void *init_routine (void); /* OK, the name of this variable isn't really appropriate, but I don't want to change it yet. */ -int (*_cthread_init_routine)(void) = &init_routine; +void *(*_cthread_init_routine)(void) = &init_routine; /* This function is called from the Hurd-specific startup code. It should return a new stack pointer for the main thread. The caller will switch to this new stack before doing anything serious. */ -static int +static void * init_routine (void) { struct __pthread *thread; @@ -68,5 +68,5 @@ init_routine (void) = (__pthread_default_attr.stacksize - __hurd_threadvar_max * sizeof (uintptr_t)); - return (int) thread->mcontext.sp; + return thread->mcontext.sp; } diff --git a/sysdeps/mach/hurd/pt-sysdep.h b/sysdeps/mach/hurd/pt-sysdep.h index 18de9c55..83bad963 100644 --- a/sysdeps/mach/hurd/pt-sysdep.h +++ b/sysdeps/mach/hurd/pt-sysdep.h @@ -53,6 +53,7 @@ }) extern inline void +__attribute__((__always_inline__)) __pthread_stack_dealloc (void *stackaddr, size_t stacksize) { __vm_deallocate (__mach_task_self (), (vm_offset_t) stackaddr, stacksize); diff --git a/sysdeps/mach/pt-spin.c b/sysdeps/mach/pt-spin.c index 010faca8..d9a2a32a 100644 --- a/sysdeps/mach/pt-spin.c +++ b/sysdeps/mach/pt-spin.c @@ -1,5 +1,5 @@ /* Spin locks. Mach version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -33,3 +33,4 @@ _pthread_spin_lock (__pthread_spinlock_t *lock) } weak_alias (_pthread_spin_lock, pthread_spin_lock); +weak_alias (_pthread_spin_lock, __pthread_spin_lock); diff --git a/sysdeps/mach/pt-thread-alloc.c b/sysdeps/mach/pt-thread-alloc.c index a191c712..1acba98a 100644 --- a/sysdeps/mach/pt-thread-alloc.c +++ b/sysdeps/mach/pt-thread-alloc.c @@ -1,5 +1,5 @@ /* Start thread. Mach version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 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 @@ -50,8 +50,8 @@ create_wakeupmsg (struct __pthread *thread) MACH_MSG_TYPE_MAKE_SEND); if (err) { - __mach_port_deallocate (__mach_task_self (), - thread->wakeupmsg.msgh_remote_port); + __mach_port_destroy (__mach_task_self (), + thread->wakeupmsg.msgh_remote_port); return EAGAIN; } @@ -86,7 +86,8 @@ __pthread_thread_alloc (struct __pthread *thread) { assert (__pthread_total == 0); thread->kernel_thread = __mach_thread_self (); - /* We implicitly hold a reference. */ + /* We implicitly hold a reference drop the one that we just + acquired. */ __mach_port_deallocate (__mach_task_self (), thread->kernel_thread); } else diff --git a/sysdeps/mach/pt-thread-dealloc.c b/sysdeps/mach/pt-thread-dealloc.c new file mode 100644 index 00000000..55d8c4d5 --- /dev/null +++ b/sysdeps/mach/pt-thread-dealloc.c @@ -0,0 +1,41 @@ +/* Deallocate the kernel thread resources. Mach version. + 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 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 <assert.h> +#include <errno.h> +#include <mach.h> + +#include <pt-internal.h> + +/* Deallocate any kernel resources associated with THREAD except don't + halt the thread itself. On return, the thread will be marked as + dead and __pthread_halt will be called. */ +void +__pthread_thread_dealloc (struct __pthread *thread) +{ + /* Why no assert? Easy. When Mach kills a task, it starts by + invalidating the task port and then terminating the threads one + by one. But while it is terminating them, they are still + eligible to be scheduled. Imagine we have two threads, one calls + exit, one calls pthread_exit. The second one may run this after + the mask port can been destroyed thus gratuitously triggering the + assert. */ + __mach_port_destroy (__mach_task_self (), + thread->wakeupmsg.msgh_remote_port); +} diff --git a/sysdeps/mach/pt-thread-halt.c b/sysdeps/mach/pt-thread-halt.c index 84e6ac8e..9f860247 100644 --- a/sysdeps/mach/pt-thread-halt.c +++ b/sysdeps/mach/pt-thread-halt.c @@ -1,5 +1,5 @@ /* Deallocate the kernel thread resources. Mach version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 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 @@ -23,17 +23,21 @@ #include <pt-internal.h> +/* Stop the kernel thread associated with THREAD. If NEED_DEALLOC is + true, the function must call __pthread_dealloc on THREAD. -/* Deallocate the kernel thread resources associated with THREAD. */ + NB: The thread executing this function may be the thread which is + being halted, thus the last action should be halting the thread + itself. */ void -__pthread_thread_halt (struct __pthread *thread) +__pthread_thread_halt (struct __pthread *thread, int need_dealloc) { error_t err; + thread_t tid = thread->kernel_thread; - err = __mach_port_deallocate (__mach_task_self (), - thread->wakeupmsg.msgh_remote_port); - assert_perror (err); + if (need_dealloc) + __pthread_dealloc (thread); - err = __thread_terminate (thread->kernel_thread); + err = __thread_terminate (tid); assert_perror (err); } diff --git a/sysdeps/mach/pt-timedblock.c b/sysdeps/mach/pt-timedblock.c index 6324ae76..ddb8baec 100644 --- a/sysdeps/mach/pt-timedblock.c +++ b/sysdeps/mach/pt-timedblock.c @@ -1,5 +1,5 @@ /* Block a thread with a timeout. Mach version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 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 @@ -34,7 +34,7 @@ __pthread_timedblock (struct __pthread *thread, { error_t err; mach_msg_header_t msg; - mach_msg_timeout_t ms; + mach_msg_timeout_t timeout; struct timeval now; /* We have an absolute time and now we have to convert it to a @@ -43,15 +43,23 @@ __pthread_timedblock (struct __pthread *thread, err = gettimeofday(&now, NULL); assert (! err); - ms = abstime->tv_sec * 1000 + (abstime->tv_nsec + 999999) / 1000000 - - now.tv_sec * 1000 - (now.tv_usec + 999) / 1000; - - if (ms <= 0) + if (now.tv_sec > abstime->tv_sec + || (now.tv_sec == abstime->tv_sec + && now.tv_usec > ((abstime->tv_nsec + 999) / 1000))) return ETIMEDOUT; + timeout = (abstime->tv_sec - now.tv_sec) * 1000; + + if (((abstime->tv_nsec + 999) / 1000) >= now.tv_usec) + timeout -= (((abstime->tv_nsec + 999) / 1000) - now.tv_usec + 999) / 1000; + else + /* Need to do a carry. */ + timeout -= 1000 + ((abstime->tv_nsec + 999999) / 1000000) + - (now.tv_usec + 999) / 1000; + err = __mach_msg (&msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof msg, thread->wakeupmsg.msgh_remote_port, - ms, MACH_PORT_NULL); + timeout, MACH_PORT_NULL); if (err == EMACH_RCV_TIMED_OUT) return ETIMEDOUT; diff --git a/sysdeps/powerpc/bits/atomic.h b/sysdeps/powerpc/bits/atomic.h deleted file mode 100644 index 5ba19cd0..00000000 --- a/sysdeps/powerpc/bits/atomic.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Atomic operations. PowerPC 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 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. */ - -#ifndef _BITS_ATOMIC_H -#define _BITS_ATOMIC_H 1 - -typedef __volatile int __atomic_t; - -static inline void -__atomic_inc (__atomic_t *__var) -{ - int tmp; - __asm__ ("\n\ -0: lwarx %0,0,%1 \n\ - add%I2 %0,%0,%2 \n\ - stwcx. %0,0,%1 \n\ - bne- 0b \n\ -" : "=&b"(tmp) : "r" (__var), "Ir"(1) : "cr0", "memory"); -} - -static inline void -__atomic_dec (__atomic_t *__var) -{ - int tmp; - __asm__ ("\n\ -0: lwarx %0,0,%1 \n\ - add%I2 %0,%0,%2 \n\ - stwcx. %0,0,%1 \n\ - bne- 0b \n\ -" : "=&b"(tmp) : "r" (__var), "Ir"(-1) : "cr0", "memory"); -} - -static inline int -__atomic_dec_and_test (__atomic_t *__var) -{ - unsigned char __ret; - -#if 0 - __asm__ __volatile ("lock; decl %0; sete %1" - : "=m" (*__var), "=qm" (__ret) : "m" (*__var)); -#endif - return __ret != 0; -} - -/* We assume that an __atomicptr_t is only used for pointers to - word-aligned objects, and use the lowest bit for a simple lock. */ -typedef __volatile int * __atomicptr_t; - -/* Actually we don't implement that yet, and assume that we run on - something that has the i486 instruction set. */ -static inline int -__atomicptr_compare_and_swap (__atomicptr_t *__ptr, void *__oldval, - void * __newval) -{ - int __ret; - __asm__ ("\n\ -0: lwarx %0,0,%1 \n\ - sub%I2c. %0,%0,%2 \n\ - cntlzw %0,%0 \n\ - bne- 1f \n\ - stwcx. %3,0,%1 \n\ - bne- 0b \n\ -1: \n\ -" : "=&b"(__ret) : "r"(__ptr), "Ir"(__oldval), "r"(__newval) : "cr0", "memory"); - return __ret >> 5; -} - -#endif |