summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@gnu.org>2007-11-20 16:23:24 +0000
committerThomas Schwinge <tschwinge@gnu.org>2009-04-07 23:05:35 +0200
commit43e3246eb6a26162ef931dadcd4a8a649c57289b (patch)
tree80cac95ce1c8b948f2a2a4ff980385b0dcbeec43 /sysdeps
parent7373049ff9aac3dbfe088da7d30b2724d15fa67a (diff)
parent8caaa8379e5a1500863792514189d6e8f414dcaf (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')
-rw-r--r--sysdeps/generic/bits/condition.h2
-rw-r--r--sysdeps/generic/bits/mutex.h75
-rw-r--r--sysdeps/generic/bits/pthread.h2
-rw-r--r--sysdeps/generic/bits/rwlock.h31
-rw-r--r--sysdeps/generic/bits/semaphore.h43
-rw-r--r--sysdeps/generic/pt-barrier-init.c16
-rw-r--r--sysdeps/generic/pt-cond-init.c17
-rw-r--r--sysdeps/generic/pt-cond-timedwait.c9
-rw-r--r--sysdeps/generic/pt-mutex-destroy.c2
-rw-r--r--sysdeps/generic/pt-mutex-init.c6
-rw-r--r--sysdeps/generic/pt-mutex-lock.c4
-rw-r--r--sysdeps/generic/pt-mutex-timedlock.c19
-rw-r--r--sysdeps/generic/pt-mutex-trylock.c15
-rw-r--r--sysdeps/generic/pt-mutex-unlock.c4
-rw-r--r--sysdeps/generic/pt-rwlock-destroy.c2
-rw-r--r--sysdeps/generic/pt-rwlock-init.c20
-rw-r--r--sysdeps/generic/pt-rwlock-rdlock.c4
-rw-r--r--sysdeps/generic/pt-rwlock-timedrdlock.c19
-rw-r--r--sysdeps/generic/pt-rwlock-timedwrlock.c19
-rw-r--r--sysdeps/generic/pt-setschedparam.c4
-rw-r--r--sysdeps/generic/sem-close.c32
-rw-r--r--sysdeps/generic/sem-destroy.c38
-rw-r--r--sysdeps/generic/sem-getvalue.c33
-rw-r--r--sysdeps/generic/sem-init.c46
-rw-r--r--sysdeps/generic/sem-open.c32
-rw-r--r--sysdeps/generic/sem-post.c62
-rw-r--r--sysdeps/generic/sem-timedwait.c92
-rw-r--r--sysdeps/generic/sem-trywait.c42
-rw-r--r--sysdeps/generic/sem-unlink.c32
-rw-r--r--sysdeps/generic/sem-wait.c32
-rw-r--r--sysdeps/hurd/pt-destroy-specific.c5
-rw-r--r--sysdeps/hurd/pt-setspecific.c4
-rw-r--r--sysdeps/ia32/bits/atomic.h66
-rw-r--r--sysdeps/l4/hurd/pt-sysdep.c2
-rw-r--r--sysdeps/l4/pt-block.c2
-rw-r--r--sysdeps/l4/pt-create-np.c3
-rw-r--r--sysdeps/l4/pt-pool-np.c3
-rw-r--r--sysdeps/l4/pt-stack-alloc.c27
-rw-r--r--sysdeps/l4/pt-thread-halt.c20
-rw-r--r--sysdeps/mach/bits/spin-lock.h4
-rw-r--r--sysdeps/mach/hurd/ia32/pt-setup.c4
-rw-r--r--sysdeps/mach/hurd/pt-sysdep.c10
-rw-r--r--sysdeps/mach/hurd/pt-sysdep.h1
-rw-r--r--sysdeps/mach/pt-spin.c3
-rw-r--r--sysdeps/mach/pt-thread-alloc.c9
-rw-r--r--sysdeps/mach/pt-thread-dealloc.c41
-rw-r--r--sysdeps/mach/pt-thread-halt.c18
-rw-r--r--sysdeps/mach/pt-timedblock.c22
-rw-r--r--sysdeps/powerpc/bits/atomic.h84
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