summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog336
-rw-r--r--Makefile37
-rw-r--r--Makefile.am6
-rw-r--r--TODO5
-rw-r--r--headers.m42
-rw-r--r--include/pthread/pthread.h222
-rw-r--r--include/semaphore.h69
-rw-r--r--pthread/pt-alloc.c28
-rw-r--r--pthread/pt-create.c33
-rw-r--r--pthread/pt-dealloc.c8
-rw-r--r--pthread/pt-detach.c4
-rw-r--r--pthread/pt-exit.c13
-rw-r--r--pthread/pt-internal.h60
-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
-rw-r--r--tests/test-1.c2
63 files changed, 1360 insertions, 547 deletions
diff --git a/ChangeLog b/ChangeLog
index 982acfa..2f022a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,339 @@
+2007-11-20 Neal H. Walfield <neal@gnu.org>
+
+ Also merge semaphore changes from mainline Hurd.
+
+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.
+
+2007-11-19 Thomas Schwinge <tschwinge@gnu.org>
+
+ * Makefile (CFLAGS): Don't set and instead...
+ (CPPFLAGS): ... append the inclusion stuff to these.
+
+2007-08-02 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * sysdeps/generic/bits/mutex.h (pthread_mutex_init)
+ (pthread_mutex_destroy, __pthread_mutex_lock, __pthread_mutex_trylock)
+ (pthread_mutex_lock, pthread_mutex_trylock): Remove inline
+ definitions.
+ * sysdeps/generic/bits/rwlock.h (pthread_rwlock_init)
+ (pthread_rwlock_destroy): Likewise.
+
+2007-06-24 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * include/semaphore.h (sem_timedwait): Declare only if __USE_XOPEN2K
+ is defined.
+ * include/pthread/pthread.h (pthread_attr_getstack)
+ (pthread_attr_setstack, pthread_mutex_timedlock)
+ (pthread_condattr_getclock, pthread_condattr_setclock)
+ (pthread_rwlock_timedrdlock, pthread_rwlock_timedwrlock)
+ (pthread_barrierattr_t, pthread_barrierattr_init)
+ (pthread_barrierattr_destroy, pthread_barrierattr_getpshared)
+ (pthread_barrierattr_setpshared, pthread_barrier_t)
+ (PTHREAD_BARRIER_SERIAL_THREAD, pthread_barrier_init)
+ (pthread_barrier_destroy, pthread_barrier_wait)
+ (pthread_getcpuclockid): Declare only if __USE_XOPEN2K is defined.
+ (pthread_mutexattr_getprioceiling, pthread_mutexattr_setprioceiling)
+ (pthread_mutexattr_getprotocol, pthread_mutexattr_setprotocol)
+ (pthread_mutexattr_gettype, pthread_mutexattr_settype)
+ (pthread_mutex_getprioceiling, pthread_mutex_setprioceiling)
+ (pthread_setconcurrency, pthread_getconcurrency): Declare only if
+ __USE_UNIX98 is defined.
+ (pthread_rwlockattr_t, pthread_rwlockattr_init)
+ (pthread_rwlockattr_destroy, pthread_rwlockattr_getpshared)
+ (pthread_rwlockattr_setpshared, pthread_rwlock_t, pthread_rwlock_init)
+ (pthread_rwlock_destroy, pthread_rwlock_rdlock)
+ (pthread_rwlock_tryrdlock, pthread_rwlock_wrlock)
+ (pthread_rwlock_trywrlock, pthread_rwlock_unlock): Declare only if
+ __USE_UNIX98 or __USE_XOPEN2K are defined.
+ (PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT, PTHREAD_PRIO_PROTECT)
+ (PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_ERRORCHECK)
+ (PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_DEFAULT):
+ Define only if __USE_UNIX98 is defined.
+ (PTHREAD_MUTEX_FAST_NP): Define for compatibility when __USE_GNU is
+ defined.
+ * sysdeps/generic/bits/rwlock.h (pthread_rwlock_init)
+ (pthread_rwlock_destroy): Declare only if __USE_UNIX98 or
+ __USE_XOPEN2K are defined.
+ * TODO: Drop that TODO item.
+
+2006-03-04 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * sysdeps/i386/machine-sp.h (thread_stack_pointer):
+ Optimize esp read.
+ * i386/cthreads.h (cthread_sp): Likewise.
+ * include/pthread/pthread.h: Add the restrict keyword where
+ appropriate for full compliance.
+ * pthread/pt-internal.h: Likewise.
+ * sysdeps/generic/bits/mutex.h: Likewise.
+ * sysdeps/generic/bits/rwlock.h: Likewise.
+ * TODO: Drop that TODO item.
+
+2006-01-20 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ Do not let other libraries (like libX11) override libpthread's
+ pthread_mutex_*, pthread_rwlock_* and sem_* dynamic symbols.
+ * sysdeps/generic/pt-mutex-destroy.c
+ (pthread_mutex_destroy): Make the alias strong.
+ * sysdeps/generic/pt-mutex-init.c
+ (pthread_mutex_init): Likewise.
+ * sysdeps/generic/pt-mutex-lock.c
+ (_pthread_mutex_lock, pthread_mutex_lock): Likewise.
+ * sysdeps/generic/pt-mutex-trylock.c
+ (_pthread_mutex_trylock, pthread_mutex_trylock): Likewise.
+ * sysdeps/generic/pt-mutex-unlock.c
+ (_pthread_mutex_lock, pthread_mutex_unlock): Likewise.
+ * sysdeps/generic/pt-rwlock-destroy.c
+ (pthread_rwlock_destroy): Likewise.
+ * sysdeps/generic/pt-rwlock-init.c
+ (pthread_rwlock_init): Likewise.
+ * sysdeps/generic/sem-destroy.c (sem_destroy): Likewise.
+ * sysdeps/generic/sem-getvalue.c (sem_getvalue): Likewise.
+ * sysdeps/generic/sem-init.c (sem_init): Likewise.
+ * sysdeps/generic/sem-open.c (sem_open): Likewise.
+ * sysdeps/generic/sem-post.c (sem_post): Likewise.
+ * sysdeps/generic/sem-timedwait.c (sem_timedwait): Likewise.
+ * sysdeps/generic/sem-trywait.c (sem_trywait): Likewise.
+ * sysdeps/generic/sem-unlink.c (sem_unlink): Likewise.
+ * sysdeps/generic/sem-wait.c (sem_wait): Likewise.
+
+2006-03-27 Thomas Schwinge <tschwinge@gnu.org>
+
+ * Makefile (SRCS): Don't define two times and only list `pt-attr.c'
+ once. Reported by Jeff Bailey <jbailey@gnu.org>.
+
+2005-08-28 Neal H. Walfield <neal@gnu.org>
+
+ * include/semaphore.h: Use __restrict, not restrict.
+
+2005-05-31 Neal H. Walfield <neal@gnu.org>
+
+ * include/pthread/pthread.h: If clockid_t is still not defined
+ after including <time.h>, define it manually.
+
+2005-05-17 Neal H. Walfield <neal@gnu.org>
+
+ * include/pthread/pthread.h: Define __need_clockid_t before
+ including <time.h>.
+
+2005-05-12 Neal H. Walfield <neal@gnu.org>
+
+ * include/pthread/pthread.h (pthread_exit): Add noreturn
+ attribute.
+
+ * sysdeps/generic/bits/condition.h (__PTHREAD_COND_INITIALIZER):
+ Don't create a compound literal.
+ * sysdeps/generic/bits/mutex.h (__PTHREAD_MUTEX_INITIALIZER):
+ Don't create a compound literal.
+ (pthread_mutex_init): Don't assign to *__MUTEX directly.
+ Initialize an intermediate local variable and then copy the
+ result.
+ * sysdeps/generic/bits/rwlock.h (__PTHREAD_RWLOCK_INITIALIZER):
+ Don't create a compound literal.
+ (pthread_rwlock_init): Don't assign to *__RWLOCK directly.
+ Initialize an intermediate local variable and then copy the
+ result.
+ * sysdeps/i386/bits/spin-lock.h (__SPIN_LOCK_INITIALIZER):
+ Don't create a compound literal.
+
+ * pthread/pt-alloc.c (initialize_pthread): Cast
+ PTHREAD_MUTEX_INITIALIZER and PTHREAD_COND_INITIALIZER to create a
+ compound literal.
+ * tests/test-1.c (main): Use pthread_mutex_init, not
+ PTHREAD_MUTEX_INIT for mutex initialization
+
+ * sysdeps/generic/pt-barrier-init.c (pthread_barrier_init): Remove
+ assert. Copy ATTR if non-defaults are used.
+ * sysdeps/generic/pt-cond-init.c (pthread_cond_init): Include
+ <string.h>. Remove assert. Copy ATTR if non-defaults are used.
+ * sysdeps/generic/pt-mutex-init.c (_pthread_mutex_init): Cast
+ PTHREAD_MUTEX_INITIALIZER to create a compound literal.
+ * sysdeps/generic/pt-rwlock-init.c: Include <string.h>.
+ (_pthread_rwlock_init): Cast __PTHREAD_RWLOCK_INITIALIZER to
+ create a compound literal. Copy ATTR if non-defaults are used.
+
+ * sysdeps/generic/pt-cond-timedwait.c
+ (__pthread_cond_timedwait_internal): Check that ABSTIME->TV_NSEC
+ is valid. Don't shadow ERR. Don't return before cleaning up.
+ * sysdeps/generic/pt-mutex-timedlock.c (pthread_mutex_timedlock):
+ Move after __pthread_mutex_timedlock_internal. Check that
+ ABSTIME->TV_NSEC is valid.
+ * sysdeps/generic/pt-rwlock-timedrdlock.c
+ (pthread_rwlock_timedrdlock): Move after.
+ __pthread_rwlock_timedrdlock_internal.
+ (__pthread_rwlock_timedrdlock_internal): Check that
+ ABSTIME->TV_NSEC is valid.
+ * sysdeps/generic/pt-rwlock-timedwrlock.c
+ (pthread_rwlock_timedwrlock): Move after
+ __pthread_rwlock_timedwrlock_internal.
+ (__pthread_rwlock_timedwrlock_internal): Check that
+ ABSTIME->TV_NSEC is valid.
+ * sysdeps/generic/sem-timedwait.c (__sem_timedwait_internal):
+ Check that TIMEOUT->TV_NSEC is valid before enqueuing the thread.
+
+ * sysdeps/generic/pt-rwlock-rdlock.c
+ (__pthread_rwlock_timedrdlock_internal): Fix declaration.
+
+ * sysdeps/generic/pt-mutex-trylock.c (__pthread_mutex_trylock):
+ Don't return EDEADLK. POSIX does not allow it.
+
+ * sysdeps/mach/pt-timedblock.c (__pthread_timedblock): Calculate
+ the relative timeout without overflowing.
+
+ * sysdeps/mach/hurd/i386/pt-setup.c (stack_setup): Cast THREAD.
+
+2005-05-12 Neal H. Walfield <neal@gnu.org>
+
+ * Makefile (SRCS): Add sem-close.c, sem-destroy.c, sem-getvalue.c,
+ sem-init.c, sem-open.c, sem-post.c, sem-timedwait.c, sem-trywait.c,
+ sem-unlink.c and sem-wait.c.
+ (sysdeps_headers): Add semaphore.h and bits/semaphore.h.
+ * include/semaphore.h: New file.
+ * sysdeps/generic/sem-close.c: New file.
+ * sysdeps/generic/sem-destroy.c: New file.
+ * sysdeps/generic/sem-getvalue.c: New file.
+ * sysdeps/generic/sem-init.c: New file.
+ * sysdeps/generic/sem-open.c: New file.
+ * sysdeps/generic/sem-post.c: New file.
+ * sysdeps/generic/sem-timedwait.c: New file.
+ * sysdeps/generic/sem-trywait.c: New file.
+ * sysdeps/generic/sem-unlink.c: New file.
+ * sysdeps/generic/sem-wait.c: New file.
+ * sysdeps/generic/bits/semaphore.h: New file.
+
+2005-05-04 Neal H. Walfield <neal@gnu.org>
+
+ * Makefile (SRCS): Add pt-thread_dealloc.c.
+ * sysdeps/mach/pt-thread-dealloc.c: New file.
+ * pthread/pt-internal.h (__pthread_thread_dealloc): New
+ declaration.
+ (__pthread_thread_halt): Add parameter NEED_DEALLOC. Update
+ callers.
+ * sysdeps/mach/pt-thread-halt.c (__pthread_thread_halt): Respect
+ new NEED_DEALLOC parameter. Move code which deallocates kernel
+ resources from here ...
+ * sysdeps/mach/pt-thread-dealloc.c (__pthread_thread_dealloc):
+ ...to here.
+ * pthread/pt-create.c (__pthread_create_internal): Call
+ __pthread_thread_dealloc on failure.
+ * pthread/pt-exit.c (pthread_exit): Call __pthread_thread_dealloc.
+
+ * sysdeps/mach/pt-thread-alloc.c (create_wakeupmsg): Call
+ __mach_port_destroy to deallocate the receive right.
+ __mach_port_deallocate won't do it.
+
+ * pthread/pt-detach.c (pthread_detach): Don't call
+ __pthread_thread_halt a second time.
+
+ * sysdeps/mach/hurd/pt-sysdep.c (_cthread_init_routine): Fix
+ declaration.
+ (init_routine): Update declaration and remove gratuitous cast.
+
+2005-05-02 Neal H. Walfield <neal@gnu.org>
+
+ * pthread/pt-alloc.c (__pthread_alloc): Set the thread id to the
+ table index plus one.
+ * pthread/pt-internal.h (__pthread_getid): Index __pthread_threads
+ using THREAD - 1, not THREAD.
+ (__pthread_setid): Likewise.
+ * pthread/pt-create.c (__pthread_create_internal): Likewise.
+
+ * sysdeps/generic/pt-mutex-trylock.c (__pthread_mutex_trylock):
+ When returning EBUSY, don't forget to first unlock MUTEX->__HELD.
+
+2005-04-20 Neal H. Walfield <neal@gnu.org>
+
+ * sysdeps/generic/pt-setschedparam.c: policy's type is int, not
+ int *.
+ * include/pthread/pthread.h: Likewise.
+ Reported by Christopher `Physicman' Bodenstein <cb@physicman.net>.
+
+2005-01-21 Michael Banck <mbanck@debian.org>
+
+ * Makefile ($(libdir)/libpthread2.a): Install linker script
+ from $(srcdir) instead of current directory.
+ ($(libdir)/libpthread2_pic.a): Likewise.
+
+2005-02-08 Neal H. Walfield <neal@gnu.org>
+
+ * sysdeps/mach/pt-spin.c (__pthread_spin_lock): Make a weak alias
+ to _pthread_spin_lock.
+ * sysdeps/posix/pt-spin.c (__pthread_spin_lock): Likewise.
+
+2005-01-18 Neal H. Walfield <neal@gnu.org>
+
+ * sysdeps/mach/hurd/pt-sysdep.h (__pthread_stack_dealloc): Add
+ __always_inline__ attribute.
+ * sysdeps/l4/hurd/pt-sysdep.h (_pthread_self): Likewise.
+ (__pthread_stack_dealloc): Likewise.
+
+2005-01-12 Pietro Ferrari <pietro@bastardi.net>
+
+ * include/pthread/pthread.h (pthread_spin_destroy): Replace extern
+ inline with extern __inline.
+ (pthread_spin_init): Likewise.
+ (pthread_spin_lock): Likewise.
+ (pthread_spin_trylock): Likewise.
+ (pthread_spin_unlock): Likewise.
+ * sysdeps/mach/bits/spin-lock.h (__pthread_spin_lock): Likewise.
+ * sysdeps/i386/bits/spin-lock.h (__pthread_spin_lock): Likewise.
+ * sysdeps/generic/bits/mutex.h (__pthread_mutex_trylock):
+ Likewise.
+ (pthread_mutex_lock): Likewise.
+ (pthread_mutex_trylock): Likewise.
+ * sysdeps/generic/bits/pthread.h (pthread_equal): Likewise.
+
+2003-08-17 Marcus Brinkmann <marcus@gnu.org>
+
+ * sysdeps/hurd/pt-key.h (PTHREAD_KEY_MEMBERS): Change type of
+ THREAD_SPECIFICS to hurd_ihash_t.
+ * sysdeps/hurd/pt-setspecific.c (pthread_setspecific): Call
+ hurd_ihash_create instead ihash_create, and hurd_ihash_add instead
+
2007-08-06 Neal H. Walfield <neal@gnu.org>
* sysdeps/l4/bits/pthread-np.h (pthread_create_from_l4_tid_np):
diff --git a/Makefile b/Makefile
index b6eebf4..4944e13 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,6 @@
#
-# Copyright (C) 1994,95,96,97,2000,02 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 2000, 2002, 2004, 2005, 2006, 2007
+# Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
@@ -21,8 +22,6 @@ makemode := library
MICROKERNEL := mach
SYSDEPS := lockfile.c
-SRCS :=
-
LCLHDRS :=
SRCS := pt-attr.c pt-attr-destroy.c pt-attr-getdetachstate.c \
@@ -32,7 +31,7 @@ SRCS := pt-attr.c pt-attr-destroy.c pt-attr-getdetachstate.c \
pt-attr-init.c pt-attr-setdetachstate.c pt-attr-setguardsize.c \
pt-attr-setinheritsched.c pt-attr-setschedparam.c \
pt-attr-setschedpolicy.c pt-attr-setscope.c pt-attr-setstack.c \
- pt-attr-setstackaddr.c pt-attr-setstacksize.c pt-attr.c \
+ pt-attr-setstackaddr.c pt-attr-setstacksize.c \
\
pt-barrier-destroy.c pt-barrier-init.c pt-barrier-wait.c \
pt-barrier.c pt-barrierattr-destroy.c pt-barrierattr-init.c \
@@ -96,6 +95,7 @@ SRCS := pt-attr.c pt-attr-destroy.c pt-attr-getdetachstate.c \
\
pt-stack-alloc.c \
pt-thread-alloc.c \
+ pt-thread-dealloc.c \
pt-thread-start.c \
pt-thread-halt.c \
\
@@ -120,6 +120,10 @@ SRCS := pt-attr.c pt-attr-destroy.c pt-attr-getdetachstate.c \
\
pt-getschedparam.c pt-setschedparam.c pt-setschedprio.c \
\
+ sem-close.c sem-destroy.c sem-getvalue.c sem-init.c sem-open.c \
+ sem-post.c sem-timedwait.c sem-trywait.c sem-unlink.c \
+ sem-wait.c \
+ \
cthreads-compat.c \
$(SYSDEPS)
@@ -132,6 +136,7 @@ libname = libpthread
sysdeps_headers = \
pthread.h \
pthread/pthread.h \
+ semaphore.h \
\
bits/pthread.h \
bits/mutex.h \
@@ -146,7 +151,8 @@ sysdeps_headers = \
bits/once.h \
bits/mutex-attr.h \
bits/rwlock.h \
- bits/rwlock-attr.h
+ bits/rwlock-attr.h \
+ bits/semaphore.h
SYSDEP_PATH = $(srcdir)/sysdeps/$(MICROKERNEL)/hurd/ia32 \
$(srcdir)/sysdeps/$(MICROKERNEL)/ia32 \
@@ -163,16 +169,17 @@ VPATH += $(SYSDEP_PATH)
HURDLIBS = ihash
-CFLAGS := -D_IO_MTSAFE_IO \
- $(addprefix -I, $(SYSDEP_PATH)) \
- -imacros $(srcdir)/include/libc-symbols.h \
- -imacros $(srcdir)/not-in-libc.h
-
installhdrs :=
-installhdrsubdir = .
+installhdrsubdir := .
include ../Makeconf
+CPPFLAGS += \
+ $(addprefix -I, $(SYSDEP_PATH)) \
+ -imacros $(srcdir)/include/libc-symbols.h \
+ -imacros $(srcdir)/not-in-libc.h
+
+
install: install-headers $(libdir)/libpthread2.a $(libdir)/libpthread2_pic.a
install-headers: $(addprefix $(includedir)/, $(sysdeps_headers))
@@ -181,14 +188,16 @@ install-headers: $(addprefix $(includedir)/, $(sysdeps_headers))
.PHONY: $(libdir)/libpthread.a $(libdir)/libpthread_pic.a
# XXX: These rules are a hack. But it is better than messing with
-# ../Makeconf at the moment.
+# ../Makeconf at the moment. Note that the linker scripts
+# $(srcdir)/libpthread.a and $(srcdir)/libpthread_pic.a get overwritten
+# when building in $(srcdir) and not a seperate build directory.
$(libdir)/libpthread2.a: $(libdir)/libpthread.a
mv $< $@
- $(INSTALL_DATA) libpthread.a $<
+ $(INSTALL_DATA) $(srcdir)/libpthread.a $<
$(libdir)/libpthread2_pic.a: $(libdir)/libpthread_pic.a
mv $< $@
- $(INSTALL_DATA) libpthread_pic.a $<
+ $(INSTALL_DATA) $(srcdir)/libpthread_pic.a $<
.PHONY: $(addprefix $(includedir)/, $(sysdeps_headers))
diff --git a/Makefile.am b/Makefile.am
index e9cedcb..bef3f17 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -126,5 +126,7 @@ libpthread_a_SOURCES = pt-attr.c pt-attr-destroy.c pt-attr-getdetachstate.c \
pt-atfork.c \
pt-kill.c \
pt-getcpuclockid.c \
- pt-getschedparam.c pt-setschedparam.c pt-setschedprio.c
-
+ pt-getschedparam.c pt-setschedparam.c pt-setschedprio.c \
+ sem-close.c sem-init.c sem-timedwait.c sem-wait.c \
+ sem-destroy.c sem-open.c sem-trywait.c sem-getvalue.c \
+ sem-post.c sem-unlink.c \ No newline at end of file
diff --git a/TODO b/TODO
index 5f35b67..45b4cdc 100644
--- a/TODO
+++ b/TODO
@@ -5,7 +5,6 @@
pthread_kill and pthread_sigmask are defined in <pthread.h> and not
<signal.h> as they should be. Once we are compiled with glibc,
this should be eaiser.
-** Must add the restrict keyword where appropriate for full compliance.
* Test cases. Can never have enough.
@@ -14,10 +13,6 @@
platforms.
* Implementation details
-** Feature test macros
- This is most likely wrong. We need a standards expert to really
- look over this or someone who can outline what I need to do.
-
** pthread_atfork
This cannot be implemented without either changing glibc to export
some hooks (c.f. libc/sysdeps/mach/hurd/fork.c) or by providing a
diff --git a/headers.m4 b/headers.m4
index df49c84..3c90788 100644
--- a/headers.m4
+++ b/headers.m4
@@ -31,4 +31,6 @@ AC_CONFIG_LINKS([
include/bits/thread-barrier.h:libpthread/sysdeps/generic/bits/thread-barrier.h
include/bits/thread-specific.h:libpthread/sysdeps/generic/bits/thread-specific.h
include/bits/pthread-np.h:libpthread/sysdeps/l4/bits/pthread-np.h
+ include/semaphore.h:libpthread/include/semaphore.h
+ include/bits/semaphore.h:libpthread/sysdeps/generic/bits/semaphore.h
])
diff --git a/include/pthread/pthread.h b/include/pthread/pthread.h
index dc7565a..9875c47 100644
--- a/include/pthread/pthread.h
+++ b/include/pthread/pthread.h
@@ -1,4 +1,4 @@
-/* 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
@@ -26,8 +26,19 @@
#include <features.h>
#include <sched.h>
+#define __need_clockid_t
#include <time.h>
+/* If we are in a mode where clockid_t is not automatically defined
+ and another header has already included <time.h> then defining
+ __need_clockid_t was not enough. */
+#ifndef __clockid_t_defined
+# define __clockid_t_defined 1
+# include <bits/types.h>
+/* Clock ID used in clock and timer functions. */
+typedef __clockid_t clockid_t;
+#endif
+
__BEGIN_DECLS
#include <bits/pthread.h>
@@ -85,8 +96,8 @@ extern int pthread_attr_destroy (pthread_attr_t *attr);
/* Return the value of the inheritsched attribute in *ATTR in
*INHERITSCHED. */
-extern int pthread_attr_getinheritsched (const pthread_attr_t *attr,
- int *inheritsched);
+extern int pthread_attr_getinheritsched (const pthread_attr_t *__restrict attr,
+ int *__restrict inheritsched);
/* Set the value of the inheritsched attribute in *ATTR to
INHERITSCHED. */
@@ -95,17 +106,17 @@ extern int pthread_attr_setinheritsched (pthread_attr_t *attr,
/* Return the value of the schedparam attribute in *ATTR in *PARAM. */
-extern int pthread_attr_getschedparam (const pthread_attr_t *attr,
- struct sched_param *param);
+extern int pthread_attr_getschedparam (const pthread_attr_t *__restrict attr,
+ struct sched_param *__restrict param);
/* Set the value of the schedparam attribute in *ATTR to PARAM. */
-extern int pthread_attr_setschedparam (pthread_attr_t *attr,
- const struct sched_param *param);
+extern int pthread_attr_setschedparam (pthread_attr_t *__restrict attr,
+ const struct sched_param *__restrict param);
/* Return the value of the schedpolicy attribute in *ATTR to *POLICY. */
-extern int pthread_attr_getschedpolicy (const pthread_attr_t *attr,
- int *policy);
+extern int pthread_attr_getschedpolicy (const pthread_attr_t *__restrict attr,
+ int *__restrict policy);
/* Set the value of the schedpolicy attribute in *ATTR to POLICY. */
extern int pthread_attr_setschedpolicy (pthread_attr_t *attr,
@@ -114,8 +125,8 @@ extern int pthread_attr_setschedpolicy (pthread_attr_t *attr,
/* Return the value of the contentionscope attribute in *ATTR in
*CONTENTIONSCOPE. */
-extern int pthread_attr_getscope (const pthread_attr_t *attr,
- int *contentionscope);
+extern int pthread_attr_getscope (const pthread_attr_t *__restrict attr,
+ int *__restrict contentionscope);
/* Set the value of the contentionscope attribute in *ATTR to
CONTENTIONSCOPE. */
@@ -125,25 +136,27 @@ extern int pthread_attr_setscope (pthread_attr_t *attr,
/* Return the value of the stackaddr attribute in *ATTR in
*STACKADDR. */
-extern int pthread_attr_getstackaddr (const pthread_attr_t *attr,
- void **stackaddr);
+extern int pthread_attr_getstackaddr (const pthread_attr_t *__restrict attr,
+ void **__restrict stackaddr);
/* Set the value of the stackaddr attribute in *ATTR to STACKADDR. */
extern int pthread_attr_setstackaddr (pthread_attr_t *attr,
void *stackaddr);
+#ifdef __USE_XOPEN2K
/* Return the value of the stackaddr and stacksize attributes in *ATTR
in *STACKADDR and *STACKSIZE respectively. */
-extern int pthread_attr_getstack (const pthread_attr_t *attr,
- void **stackaddr,
- size_t *stacksize);
+extern int pthread_attr_getstack (const pthread_attr_t *__restrict attr,
+ void **__restrict stackaddr,
+ size_t *__restrict stacksize);
/* Set the value of the stackaddr and stacksize attributes in *ATTR to
STACKADDR and STACKSIZE respectively. */
extern int pthread_attr_setstack (pthread_attr_t *attr,
void *stackaddr,
size_t stacksize);
+#endif
/* Return the value of the detachstate attribute in *ATTR in
@@ -159,8 +172,8 @@ extern int pthread_attr_setdetachstate (pthread_attr_t *attr,
/* Return the value of the guardsize attribute in *ATTR in
*GUARDSIZE. */
-extern int pthread_attr_getguardsize (const pthread_attr_t *attr,
- size_t *guardsize);
+extern int pthread_attr_getguardsize (const pthread_attr_t *__restrict attr,
+ size_t *__restrict guardsize);
/* Set the value of the guardsize attribute in *ATTR to GUARDSIZE. */
extern int pthread_attr_setguardsize (pthread_attr_t *attr,
@@ -169,8 +182,8 @@ extern int pthread_attr_setguardsize (pthread_attr_t *attr,
/* Return the value of the stacksize attribute in *ATTR in
*STACKSIZE. */
-extern int pthread_attr_getstacksize (const pthread_attr_t *attr,
- size_t *stacksize);
+extern int pthread_attr_getstacksize (const pthread_attr_t *__restrict attr,
+ size_t *__restrict stacksize);
/* Set the value of the stacksize attribute in *ATTR to STACKSIZE. */
extern int pthread_attr_setstacksize (pthread_attr_t *attr,
@@ -179,13 +192,14 @@ extern int pthread_attr_setstacksize (pthread_attr_t *attr,
/* Create a thread with attributes given by ATTR, executing
START_ROUTINE with argument ARG. */
-extern int pthread_create (pthread_t *__threadp,
- __const pthread_attr_t *__attr,
- void *(*__start_routine)(void *), void *__arg);
+extern int pthread_create (pthread_t *__restrict __threadp,
+ __const pthread_attr_t *__restrict __attr,
+ void *(*__start_routine)(void *),
+ void *__restrict __arg);
/* Terminate the current thread and make STATUS available to any
thread that might join us. */
-extern void pthread_exit (void *__status);
+extern void pthread_exit (void *__status) __attribute__ ((noreturn));
/* Make calling thread wait for termination of thread THREAD. Return
the exit status of the thread in *STATUS. */
@@ -207,23 +221,33 @@ extern pthread_t pthread_self (void);
enum __pthread_mutex_protocol
{
- PTHREAD_PRIO_NONE = 0,
-#define PTHREAD_PRIO_NONE 0
- PTHREAD_PRIO_INHERIT,
-#define PTHREAD_PRIO_INHERIT 1
- PTHREAD_PRIO_PROTECT
-#define PTHREAD_PRIO_PROTECT 2
+ PTHREAD_PRIO_NONE_NP = 0,
+ PTHREAD_PRIO_INHERIT_NP,
+ PTHREAD_PRIO_PROTECT_NP
+#ifdef __USE_UNIX98
+ ,
+ PTHREAD_PRIO_NONE = PTHREAD_PRIO_NONE_NP,
+ PTHREAD_PRIO_INHERIT = PTHREAD_PRIO_INHERIT_NP,
+ PTHREAD_PRIO_PROTECT = PTHREAD_PRIO_PROTECT_NP
+#endif
};
enum __pthread_mutex_type
{
- PTHREAD_MUTEX_NORMAL = 0,
-#define PTHREAD_MUTEX_NORMAL 0
-#define PTHREAD_MUTEX_DEFAULT 0
- PTHREAD_MUTEX_ERRORCHECK,
-#define PTHREAD_MUTEX_ERRORCHECK 1
- PTHREAD_MUTEX_RECURSIVE,
-#define PTHREAD_MUTEX_RECURSIVE 2
+ PTHREAD_MUTEX_TIMED_NP = 0,
+ PTHREAD_MUTEX_ERRORCHECK_NP,
+ PTHREAD_MUTEX_RECURSIVE_NP
+#ifdef __USE_UNIX98
+ ,
+ PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
+ PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
+ PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
+ PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
+#endif
+#ifdef __USE_GNU
+ /* For compatibility. */
+ , PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
+#endif
};
#include <bits/mutex-attr.h>
@@ -238,10 +262,11 @@ extern int pthread_mutexattr_init(pthread_mutexattr_t *attr);
extern int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
+#ifdef __USE_UNIX98
/* Return the value of the prioceiling attribute in *ATTR in
*PRIOCEILING. */
-extern int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr,
- int *prioceiling);
+extern int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *__restrict attr,
+ int *__restrict prioceiling);
/* Set the value of the prioceiling attribute in *ATTR to
PRIOCEILING. */
@@ -251,18 +276,19 @@ extern int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr,
/* Return the value of the protocol attribute in *ATTR in
*PROTOCOL. */
-extern int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr,
- int *protocol);
+extern int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *__restrict attr,
+ int *__restrict protocol);
/* Set the value of the protocol attribute in *ATTR to PROTOCOL. */
extern int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr,
int protocol);
+#endif
/* Return the value of the process shared attribute in *ATTR in
*PSHARED. */
-extern int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr,
- int *pshared);
+extern int pthread_mutexattr_getpshared(const pthread_mutexattr_t *__restrict attr,
+ int *__restrict pshared);
/* Set the value of the process shared attribute in *ATTR to
PSHARED. */
@@ -270,13 +296,15 @@ extern int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr,
int pshared);
+#ifdef __USE_UNIX98
/* Return the value of the type attribute in *ATTR in *TYPE. */
-extern int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr,
- int *type);
+extern int pthread_mutexattr_gettype(const pthread_mutexattr_t *__restrict attr,
+ int *__restrict type);
/* Set the value of the type attribute in *ATTR to TYPE. */
extern int pthread_mutexattr_settype(pthread_mutexattr_t *attr,
int type);
+#endif
/* Mutexes. */
@@ -289,8 +317,8 @@ typedef struct __pthread_mutex pthread_mutex_t;
/* Create a mutex with attributes given by ATTR and store it in
*__MUTEX. */
-extern int pthread_mutex_init (struct __pthread_mutex *__mutex,
- const pthread_mutexattr_t *attr);
+extern int pthread_mutex_init (struct __pthread_mutex *__restrict __mutex,
+ const pthread_mutexattr_t *__restrict attr);
/* Destroy the mutex __MUTEX. */
extern int pthread_mutex_destroy (struct __pthread_mutex *__mutex);
@@ -301,23 +329,27 @@ extern int pthread_mutex_lock (pthread_mutex_t *__mutex);
/* Try to lock MUTEX. */
extern int pthread_mutex_trylock (pthread_mutex_t *__mutex);
+#ifdef __USE_XOPEN2K
/* Try to lock MUTEX, block until *ABSTIME if it is already held. */
-extern int pthread_mutex_timedlock (struct __pthread_mutex *mutex,
- const struct timespec *abstime);
+extern int pthread_mutex_timedlock (struct __pthread_mutex *__restrict mutex,
+ const struct timespec *__restrict abstime);
+#endif
/* Unlock MUTEX. */
extern int pthread_mutex_unlock (pthread_mutex_t *__mutex);
+#ifdef __USE_UNIX98
/* Return the priority ceiling of mutex *MUTEX in *PRIOCEILING. */
-extern int pthread_mutex_getprioceiling (const pthread_mutex_t *mutex,
- int *prioceiling);
+extern int pthread_mutex_getprioceiling (const pthread_mutex_t *__restrict mutex,
+ int *__restrict prioceiling);
/* After acquiring the mutex *MUTEX, set its priority ceiling to PRIO
and return the old priority ceiling in *OLDPRIO. Before returning,
release the mutex. */
-extern int pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prio,
- int *oldprio);
+extern int pthread_mutex_setprioceiling (pthread_mutex_t *__restrict mutex,
+ int prio, int *__restrict oldprio);
+#endif
@@ -335,19 +367,21 @@ extern int pthread_condattr_init (pthread_condattr_t *attr);
extern int pthread_condattr_destroy (pthread_condattr_t *attr);
+#ifdef __USE_XOPEN2K
/* Return the value of the clock attribute in *ATTR in *CLOCK_ID. */
-extern int pthread_condattr_getclock (const pthread_condattr_t *attr,
- clockid_t *clock_id);
+extern int pthread_condattr_getclock (const pthread_condattr_t *__restrict attr,
+ clockid_t *__restrict clock_id);
/* Set the value of the clock attribute in *ATTR to CLOCK_ID. */
extern int pthread_condattr_setclock (pthread_condattr_t *attr,
clockid_t clock_id);
+#endif
/* Return the value of the process shared attribute in *ATTR in
*PSHARED. */
-extern int pthread_condattr_getpshared (const pthread_condattr_t *attr,
- int *pshared);
+extern int pthread_condattr_getpshared (const pthread_condattr_t *__restrict attr,
+ int *__restrict pshared);
/* Set the value of the process shared attribute in *ATTR to
PSHARED. */
@@ -363,8 +397,8 @@ typedef struct __pthread_cond pthread_cond_t;
#define PTHREAD_COND_INITIALIZER __PTHREAD_COND_INITIALIZER
-extern int pthread_cond_init (pthread_cond_t *cond,
- const pthread_condattr_t *attr);
+extern int pthread_cond_init (pthread_cond_t *__restrict cond,
+ const pthread_condattr_t *__restrict attr);
extern int pthread_cond_destroy (pthread_cond_t *cond);
@@ -378,16 +412,16 @@ extern int pthread_cond_broadcast (pthread_cond_t *__cond);
/* Block on condition variable COND. MUTEX should be held by the
calling thread. On success, MUTEX will be held by the calling
thread. */
-extern int pthread_cond_wait (pthread_cond_t *__cond,
- pthread_mutex_t *__mutex);
+extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
+ pthread_mutex_t *__restrict __mutex);
/* Block on condition variable COND. MUTEX should be held by the
calling thread. On success, MUTEX will be held by the calling
thread. If the time specified by ABSTIME passes, ETIMEDOUT is
returned, and MUTEX will nevertheless be held. */
-extern int pthread_cond_timedwait (pthread_cond_t *__cond,
- pthread_mutex_t *__mutex,
- __const struct timespec *__abstime);
+extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
+ pthread_mutex_t *__restrict __mutex,
+ __const struct timespec *__restrict __abstime);
/* Spin locks. */
@@ -420,31 +454,31 @@ extern int pthread_spin_unlock (pthread_spinlock_t *__lock);
# ifdef __USE_EXTERN_INLINES
-extern inline int
+extern __inline int
pthread_spin_destroy (pthread_spinlock_t *__lock)
{
return __pthread_spin_destroy (__lock);
}
-extern inline int
+extern __inline int
pthread_spin_init (pthread_spinlock_t *__lock, int __pshared)
{
return __pthread_spin_init (__lock, __pshared);
}
-extern inline int
+extern __inline int
pthread_spin_lock (pthread_spinlock_t *__lock)
{
return __pthread_spin_lock (__lock);
}
-extern inline int
+extern __inline int
pthread_spin_trylock (pthread_spinlock_t *__lock)
{
return __pthread_spin_trylock (__lock);
}
-extern inline int
+extern __inline int
pthread_spin_unlock (pthread_spinlock_t *__lock)
{
return __pthread_spin_unlock (__lock);
@@ -457,6 +491,8 @@ pthread_spin_unlock (pthread_spinlock_t *__lock)
/* rwlock attributes. */
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+
#include <bits/rwlock-attr.h>
typedef struct __pthread_rwlockattr pthread_rwlockattr_t;
@@ -471,8 +507,8 @@ extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *attr);
/* Return the value of the process shared attribute in *ATTR in
*PSHARED. */
-extern int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr,
- int *pshared);
+extern int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *__restrict attr,
+ int *__restrict pshared);
/* Set the value of the process shared atrribute in *ATTR to
PSHARED. */
@@ -488,8 +524,8 @@ typedef struct __pthread_rwlock pthread_rwlock_t;
/* Create a rwlock object with attributes given by ATTR and strore the
result in *RWLOCK. */
-extern int pthread_rwlock_init (pthread_rwlock_t *rwlock,
- const pthread_rwlockattr_t *attr);
+extern int pthread_rwlock_init (pthread_rwlock_t *__restrict rwlock,
+ const pthread_rwlockattr_t *__restrict attr);
/* Destroy the rwlock *RWLOCK. */
extern int pthread_rwlock_destroy (pthread_rwlock_t *rwlock);
@@ -500,10 +536,12 @@ extern int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock);
/* Acquire the rwlock *RWLOCK for reading. */
extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock);
+# ifdef __USE_XOPEN2K
/* Acquire the rwlock *RWLOCK for reading blocking until *ABSTIME if
it is already held. */
-extern int pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock,
- const struct timespec *abstime);
+extern int pthread_rwlock_timedrdlock (struct __pthread_rwlock *__restrict rwlock,
+ const struct timespec *__restrict abstime);
+# endif
/* Acquire the rwlock *RWLOCK for writing. */
extern int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock);
@@ -511,13 +549,18 @@ extern int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock);
/* Try to acquire the rwlock *RWLOCK for writing. */
extern int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock);
+# ifdef __USE_XOPEN2K
/* Acquire the rwlock *RWLOCK for writing blocking until *ABSTIME if
it is already held. */
-extern int pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock,
- const struct timespec *abstime);
+extern int pthread_rwlock_timedwrlock (struct __pthread_rwlock *__restrict rwlock,
+ const struct timespec *__restrict abstime);
+# endif
/* Release the lock held by the current thread on *RWLOCK. */
extern int pthread_rwlock_unlock (pthread_rwlock_t *rwlock);
+
+#endif /* __USE_UNIX98 || __USE_XOPEN2K */
+
/* Cancelation. */
@@ -557,6 +600,8 @@ extern void pthread_testcancel (void);
/* Barriers attributes. */
+#ifdef __USE_XOPEN2K
+
#include <bits/barrier-attr.h>
typedef struct __pthread_barrierattr pthread_barrierattr_t;
@@ -571,8 +616,8 @@ extern int pthread_barrierattr_destroy (pthread_barrierattr_t *attr);
/* Return the value of the process shared attribute in *ATTR in
*PSHARED. */
-extern int pthread_barrierattr_getpshared (const pthread_barrierattr_t *attr,
- int *pshared);
+extern int pthread_barrierattr_getpshared (const pthread_barrierattr_t *__restrict attr,
+ int *__restrict pshared);
/* Set the value of the process shared atrribute in *ATTR to
PSHARED. */
@@ -591,8 +636,8 @@ typedef struct __pthread_barrier pthread_barrier_t;
#define PTHREAD_BARRIER_SERIAL_THREAD -1
/* Initialize barrier BARRIER. */
-extern int pthread_barrier_init (pthread_barrier_t *barrier,
- const pthread_barrierattr_t *attr,
+extern int pthread_barrier_init (pthread_barrier_t *__restrict barrier,
+ const pthread_barrierattr_t *__restrict attr,
unsigned count);
/* Destroy barrier BARRIER. */
@@ -600,6 +645,9 @@ extern int pthread_barrier_destroy (pthread_barrier_t *barrier);
/* Wait on barrier BARRIER. */
extern int pthread_barrier_wait (pthread_barrier_t *barrier);
+
+#endif /* __USE_XOPEN2K */
+
/* Thread specific data. */
@@ -641,11 +689,13 @@ extern int pthread_once (pthread_once_t *once_control,
/* Concurrency. */
+#ifdef __USE_UNIX98
/* Set the desired concurrency level to NEW_LEVEL. */
extern int pthread_setconcurrency (int new_level);
/* Get the current concurrency level. */
extern int pthread_getconcurrency (void);
+#endif
/* Forking. */
@@ -669,25 +719,25 @@ extern int pthread_kill (pthread_t thread, int signo);
/* Time. */
+#ifdef __USE_XOPEN2K
/* Return the thread cpu clock. */
extern int pthread_getcpuclockid (pthread_t thread, clockid_t *clock);
+#endif
/* Scheduling. */
/* Return thread THREAD's scheduling paramters. */
-extern int pthread_getschedparam (pthread_t thread, int *policy,
- struct sched_param *param);
+extern int pthread_getschedparam (pthread_t thread, int *__restrict policy,
+ struct sched_param *__restrict param);
/* Set thread THREAD's scheduling paramters. */
-extern int pthread_setschedparam (pthread_t thread, int *policy,
+extern int pthread_setschedparam (pthread_t thread, int policy,
const struct sched_param *param);
/* Set thread THREAD's scheduling priority. */
extern int pthread_setschedprio (pthread_t thread, int prio);
-
-#include <bits/pthread-np.h>
__END_DECLS
diff --git a/include/semaphore.h b/include/semaphore.h
new file mode 100644
index 0000000..06c9e73
--- /dev/null
+++ b/include/semaphore.h
@@ -0,0 +1,69 @@
+/* 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 _SEMAPHORE_H
+#define _SEMAPHORE_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+#include <bits/semaphore.h>
+
+#define SEM_FAILED ((void *) 0)
+
+typedef struct __semaphore sem_t;
+
+/* Initialize semaphore *SEM with value VALUE. */
+extern int sem_init (sem_t *sem, int pshared, unsigned value);
+
+/* Destroy semaphore *SEM created with sem_init. */
+extern int sem_destroy (sem_t *sem);
+
+/* Store the value of semaphore *SEM in *VALUE. */
+extern int sem_getvalue (sem_t *__restrict sem, int *__restrict value);
+
+/* Perform a down operation on semaphore *SEM. */
+extern int sem_wait (sem_t *sem);
+
+/* Perform a down operation on semaphore *SEM if it can be done so
+ without blocking. */
+extern int sem_trywait (sem_t *sem);
+
+#ifdef __USE_XOPEN2K
+/* Perform a down operation on semaphore *SEM but don't wait longer
+ than TIMEOUT. */
+extern int sem_timedwait (sem_t *__restrict sem,
+ const struct timespec *__restrict timeout);
+#endif
+
+/* Perform an up operation on semaphore *SEM. */
+extern int sem_post (sem_t *sem);
+
+/* Open a named semaphore. */
+extern sem_t *sem_open (const char *name, int open_flags, ...);
+
+/* Close a semaphore returned by sem_open. */
+extern int sem_close (sem_t *sem);
+
+/* Unlink a named semaphore. */
+extern int sem_unlink (const char *name);
+
+__END_DECLS
+
+#endif /* semaphore.h */
diff --git a/pthread/pt-alloc.c b/pthread/pt-alloc.c
index 615b728..6cf9106 100644
--- a/pthread/pt-alloc.c
+++ b/pthread/pt-alloc.c
@@ -1,5 +1,5 @@
/* Allocate a new thread structure.
- Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2005, 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
@@ -46,7 +46,7 @@ pthread_rwlock_t __pthread_threads_lock;
/* List of thread structures corresponding to free thread IDs. */
-uatomicptr_t __pthread_free_threads;
+atomicptr_t __pthread_free_threads;
static inline error_t
initialize_pthread (struct __pthread *new, int recycling)
@@ -69,8 +69,8 @@ initialize_pthread (struct __pthread *new, int recycling)
new->stack = 0;
- new->state_lock = (struct __pthread_mutex) PTHREAD_MUTEX_INITIALIZER;
- new->state_cond = (struct __pthread_cond) PTHREAD_COND_INITIALIZER;
+ new->state_lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
+ new->state_cond = (pthread_cond_t) PTHREAD_COND_INITIALIZER;
new->cancelation_handlers = 0;
@@ -98,7 +98,9 @@ __pthread_alloc (struct __pthread **pthread)
while ((new = (struct __pthread *)__pthread_free_threads))
{
if (atomic_compare_and_exchange_val_acq (&__pthread_free_threads,
- new, new->next))
+ (uintptr_t) new->next,
+ (uintptr_t) new)
+ == (uintptr_t) new)
{
/* Yes, we managed to get one. The thread number in the
thread structure still refers to the correct slot. */
@@ -111,7 +113,9 @@ __pthread_alloc (struct __pthread **pthread)
{
new->next = (struct __pthread *)__pthread_free_threads;
if (atomic_compare_and_exchange_val_acq
- (&__pthread_free_threads, new->next, new))
+ (&__pthread_free_threads,
+ (uintptr_t) new, (uintptr_t) new->next)
+ == (uintptr_t) new->next)
break;
}
@@ -139,10 +143,10 @@ __pthread_alloc (struct __pthread **pthread)
if (__pthread_num_threads < __pthread_max_threads)
{
- /* We have a free slot. Use the slot number as
- the thread ID for the new thread. */
- new->thread = __pthread_num_threads++;
- __pthread_threads[new->thread] = NULL;
+ /* We have a free slot. Use the slot number plus one as the
+ thread ID for the new thread. */
+ new->thread = 1 + __pthread_num_threads++;
+ __pthread_threads[new->thread - 1] = NULL;
pthread_rwlock_unlock (&__pthread_threads_lock);
@@ -203,8 +207,8 @@ __pthread_alloc (struct __pthread **pthread)
__pthread_threads = threads;
/* And allocate ourselves one of the newly created slots. */
- new->thread = __pthread_num_threads++;
- __pthread_threads[new->thread] = NULL;
+ new->thread = 1 + __pthread_num_threads++;
+ __pthread_threads[new->thread - 1] = NULL;
pthread_rwlock_unlock (&__pthread_threads_lock);
diff --git a/pthread/pt-create.c b/pthread/pt-create.c
index 8d348fb..4f8d043 100644
--- a/pthread/pt-create.c
+++ b/pthread/pt-create.c
@@ -1,5 +1,5 @@
/* Thread creation.
- Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2005, 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
@@ -33,7 +33,7 @@
/* The total number of pthreads currently active. This is defined
here since it would be really stupid to have a threads-using
program that doesn't call `pthread_create'. */
-uatomic32_t __pthread_total;
+atomic_fast32_t __pthread_total;
/* The entry-point for new threads. */
@@ -57,7 +57,7 @@ pthread_create (pthread_t *thread, const pthread_attr_t *attr,
int err;
struct __pthread *pthread;
- err = __pthread_create_internal (&pthread, attr, 0, start_routine, arg);
+ err = __pthread_create_internal (&pthread, attr, start_routine, arg);
if (! err)
*thread = pthread->thread;
@@ -69,7 +69,6 @@ pthread_create (pthread_t *thread, const pthread_attr_t *attr,
int
__pthread_create_internal (struct __pthread **thread,
const pthread_attr_t *attr,
- void *provided_thread,
void *(*start_routine)(void *), void *arg)
{
int err;
@@ -123,20 +122,10 @@ __pthread_create_internal (struct __pthread **thread,
pthread->stack = 1;
}
- /* Allocate the kernel thread and other required resources
- if they were not provided with this call. */
- if (!provided_thread)
- {
- err = __pthread_thread_alloc (pthread);
- if (err)
- goto failed_thread_alloc;
- }
- else
- {
- err = __pthread_init_provided_thread (pthread, provided_thread);
- if (err)
- goto failed_thread_alloc;
- }
+ /* Allocate the kernel thread and other required resources. */
+ err = __pthread_thread_alloc (pthread);
+ if (err)
+ goto failed_thread_alloc;
/* And initialize the rest of the machine context. This may include
additional machine- and system-specific initializations that
@@ -157,8 +146,7 @@ __pthread_create_internal (struct __pthread **thread,
shall be empty." If the currnet thread is not a pthread then we
just inherit the process' sigmask. */
if (__pthread_num_threads == 1)
- /* FIXME no sigprocmask yet */
- err = 0; /* sigprocmask (0, 0, &sigset); */
+ err = sigprocmask (0, 0, &sigset);
else
err = __pthread_sigstate (_pthread_self (), 0, 0, &sigset, 0);
assert_perror (err);
@@ -180,7 +168,7 @@ __pthread_create_internal (struct __pthread **thread,
other thread should be using this entry (we also assume that the
store is atomic). */
pthread_rwlock_rdlock (&__pthread_threads_lock);
- __pthread_threads[pthread->thread] = pthread;
+ __pthread_threads[pthread->thread - 1] = pthread;
pthread_rwlock_unlock (&__pthread_threads_lock);
/* At this point it is possible to guess our pthread ID. We have to
@@ -204,7 +192,8 @@ __pthread_create_internal (struct __pthread **thread,
failed_sigstate:
__pthread_sigstate_destroy (pthread);
failed_setup:
- __pthread_thread_halt (pthread);
+ __pthread_thread_dealloc (pthread);
+ __pthread_thread_halt (pthread, 0);
failed_thread_alloc:
__pthread_stack_dealloc (pthread->stackaddr, pthread->stacksize);
pthread->stack = 0;
diff --git a/pthread/pt-dealloc.c b/pthread/pt-dealloc.c
index f89f354..879608b 100644
--- a/pthread/pt-dealloc.c
+++ b/pthread/pt-dealloc.c
@@ -26,7 +26,7 @@
#include <atomic.h>
/* List of thread structures corresponding to free thread IDs. */
-extern uatomicptr_t __pthread_free_threads;
+extern atomicptr_t __pthread_free_threads;
/* Deallocate the thread structure for PTHREAD and the resources
associated with it. */
@@ -55,8 +55,10 @@ __pthread_dealloc (struct __pthread *pthread)
{
pthread->next = (struct __pthread *)__pthread_free_threads;
if (atomic_compare_and_exchange_val_acq (&__pthread_free_threads,
- pthread->next, pthread))
- return;
+ (uintptr_t) pthread,
+ (uintptr_t) pthread->next)
+ == (uintptr_t) pthread->next)
+ break;
}
/* NOTREACHED */
diff --git a/pthread/pt-detach.c b/pthread/pt-detach.c
index c22f6a0..42a8408 100644
--- a/pthread/pt-detach.c
+++ b/pthread/pt-detach.c
@@ -1,5 +1,5 @@
/* Detach a thread.
- 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
@@ -58,8 +58,6 @@ pthread_detach (pthread_t thread)
__pthread_mutex_unlock (&pthread->state_lock);
- __pthread_thread_halt (pthread);
-
assert (pthread->stack);
__pthread_stack_dealloc (pthread->stackaddr, pthread->stacksize);
pthread->stack = 0;
diff --git a/pthread/pt-exit.c b/pthread/pt-exit.c
index 68f596d..a8f85b1 100644
--- a/pthread/pt-exit.c
+++ b/pthread/pt-exit.c
@@ -1,5 +1,5 @@
/* Thread termination.
- Copyright (C) 2000, 2002, 2004 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
@@ -35,6 +35,7 @@ pthread_exit (void *status)
struct __pthread *self = _pthread_self ();
struct __pthread_cancelation_handler **handlers;
int oldstate;
+ int need_dealloc;
/* Run any cancelation handlers. According to POSIX, the
cancellation cleanup handlers should be called with cancellation
@@ -69,10 +70,13 @@ pthread_exit (void *status)
if (self->cancel_state == PTHREAD_CANCEL_ENABLE && self->cancel_pending)
status = PTHREAD_CANCELED;
+ __pthread_thread_dealloc (self);
+
switch (self->state)
{
default:
- assert (! "This cannot happen!");
+ assert (! "Consistency error: unexpected self->state");
+ abort ();
break;
case PTHREAD_DETACHED:
@@ -82,7 +86,7 @@ pthread_exit (void *status)
deallocate our own stack. However, it will eventually be
reused when this thread structure is recycled. */
__pthread_mutex_unlock (&self->state_lock);
- __pthread_dealloc (self);
+ need_dealloc = 1;
break;
@@ -99,6 +103,7 @@ pthread_exit (void *status)
waiting to join us. */
pthread_cond_broadcast (&self->state_cond);
__pthread_mutex_unlock (&self->state_lock);
+ need_dealloc = 0;
break;
}
@@ -108,7 +113,7 @@ pthread_exit (void *status)
This means that before freeing any resources, such a thread
should make sure that this thread is really halted. */
- __pthread_thread_halt (self);
+ __pthread_thread_halt (self, need_dealloc);
/* NOTREACHED */
abort ();
diff --git a/pthread/pt-internal.h b/pthread/pt-internal.h
index 436f870..0dd4e9a 100644
--- a/pthread/pt-internal.h
+++ b/pthread/pt-internal.h
@@ -1,5 +1,5 @@
/* Internal defenitions for pthreads library.
- Copyright (C) 2000, 2004 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
@@ -21,12 +21,11 @@
#define _PT_INTERNAL_H 1
#include <pthread.h>
-#if 0
#include <stddef.h>
#include <sched.h>
#include <signal.h>
#include <assert.h>
-#endif
+
#include <atomic.h>
#include <pt-key.h>
@@ -126,7 +125,7 @@ __pthread_dequeue (struct __pthread *thread)
element = element->next)
/* The total number of threads currently active. */
-extern uatomic32_t __pthread_total;
+extern atomic_fast32_t __pthread_total;
/* The total number of thread IDs currently in use, or on the list of
available thread IDs. */
@@ -135,20 +134,23 @@ extern int __pthread_num_threads;
/* Concurrency hint. */
extern int __pthread_concurrency;
-/* Array of __pthread structures and its lock. */
+/* Array of __pthread structures and its lock. Indexed by the pthread
+ id minus one. (Why not just use the pthread id? Because some
+ brain-dead users of the pthread interface incorrectly assume that 0
+ is an invalid pthread id.) */
extern struct __pthread **__pthread_threads;
extern pthread_rwlock_t __pthread_threads_lock;
#define __pthread_getid(thread) \
({ struct __pthread *__t; \
pthread_rwlock_rdlock (&__pthread_threads_lock); \
- __t = __pthread_threads[thread]; \
+ __t = __pthread_threads[thread - 1]; \
pthread_rwlock_unlock (&__pthread_threads_lock); \
__t; })
#define __pthread_setid(thread, pthread) \
pthread_rwlock_wrlock (&__pthread_threads_lock); \
- __pthread_threads[thread] = pthread; \
+ __pthread_threads[thread - 1] = pthread; \
pthread_rwlock_unlock (&__pthread_threads_lock);
/* Similar to pthread_self, but returns the thread descriptor instead
@@ -163,11 +165,10 @@ extern void __pthread_initialize (void);
/* Internal version of pthread_create. Rather than return the new
tid, we return the whole __pthread structure in *PTHREAD. */
-extern int __pthread_create_internal (struct __pthread **pthread,
- const pthread_attr_t *attr,
- void *provided_thread,
+extern int __pthread_create_internal (struct __pthread **__restrict pthread,
+ const pthread_attr_t *__restrict attr,
void *(*start_routine)(void *),
- void *arg);
+ void *__restrict arg);
/* Allocate a new thread structure and a pthread thread ID (but not a
kernel thread or a stack). */
@@ -188,33 +189,41 @@ extern void __pthread_stack_dealloc (void *stackaddr, size_t stacksize);
/* Setup thread THREAD's context. */
-extern int __pthread_setup (struct __pthread *thread,
+extern int __pthread_setup (struct __pthread *__restrict thread,
void (*entry_point)(void *(*)(void *),
void *),
- void *(*start_routine)(void *), void *arg);
+ void *(*start_routine)(void *),
+ void *__restrict arg);
-/* Allocate a kernel thread for THREAD; it must not be placed on the
- run queue. */
+/* Allocate a kernel thread (and any miscellaneous system dependent
+ resources) for THREAD; it must not be placed on the run queue. */
extern int __pthread_thread_alloc (struct __pthread *thread);
+/* 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. */
+extern void __pthread_thread_dealloc (struct __pthread *thread);
+
/* Start THREAD making it eligible to run. */
extern int __pthread_thread_start (struct __pthread *thread);
-/* Stop thread thread and deallocate any kernel resources associated
- with THREAD. */
-extern void __pthread_thread_halt (struct __pthread *thread);
+/* Stop the kernel thread associated with THREAD. If NEED_DEALLOC is
+ true, the function must call __pthread_dealloc on 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. */
+extern void __pthread_thread_halt (struct __pthread *thread,
+ int need_dealloc);
-/* Initialize provided kernel thread. */
-extern int __pthread_init_provided_thread (struct __pthread *thread,
- void *p);
/* Block THREAD. */
extern void __pthread_block (struct __pthread *thread);
/* Block THREAD until *ABSTIME is reached. */
-extern error_t __pthread_timedblock (struct __pthread *thread,
- const struct timespec *abstime);
+extern error_t __pthread_timedblock (struct __pthread *__restrict thread,
+ const struct timespec *__restrict abstime);
/* Wakeup THREAD. */
extern void __pthread_wakeup (struct __pthread *thread);
@@ -242,8 +251,9 @@ extern error_t __pthread_sigstate_init (struct __pthread *thread);
extern void __pthread_sigstate_destroy (struct __pthread *thread);
/* Modify thread *THREAD's signal state. */
-extern error_t __pthread_sigstate (struct __pthread *thread, int how,
- const sigset_t *set, sigset_t *oset,
+extern error_t __pthread_sigstate (struct __pthread *__restrict thread, int how,
+ const sigset_t *__restrict set,
+ sigset_t *__restrict oset,
int clear_pending);
diff --git a/sysdeps/generic/bits/condition.h b/sysdeps/generic/bits/condition.h
index a194b05..f3b09be 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 ecbcff8..1aaf80e 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 740325d..3f9df13 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 d089b0c..696f9c2 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 0000000..b53f47e
--- /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 57911d5..c42b3bb 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 a01a94b..b9e9fb7 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 4abeb71..c10bdb3 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 d9fb59c..72faefe 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 100f485..da1781b 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 58d3827..60fc55a 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 3603986..5e222bd 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 b3c3fe3..d56f6e1 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 bbbe2b8..2f719d3 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 f63c84d..034d930 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 8fe8764..8aa495e 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 d060c38..480cf48 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 85cb946..ba610fa 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 edf6413..04eab51 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 6b624a3..a70b079 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 0000000..9f48032
--- /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 0000000..985f4ad
--- /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 0000000..8e418e3
--- /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 0000000..6c6d79e
--- /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 0000000..9eb13aa
--- /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 0000000..0e20ea7
--- /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 0000000..d01bfdb
--- /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 0000000..199f317
--- /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 0000000..519f4f7
--- /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 0000000..50752f3
--- /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 2006f2b..23c7fbc 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 bd75225..89ca4d7 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 0dfc1f6..0000000
--- 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 f23a137..265592c 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 5992dc1..933cc28 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 57c782c..68b8b00 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 c72f2eb..f59a3e2 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 9a25414..2ede58f 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 991123c..aa2bf43 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 f295df7..e137c24 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 9a85584..32ace6a 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 b42fe25..5e07006 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 18de9c5..83bad96 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 010faca..d9a2a32 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 a191c71..1acba98 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 0000000..55d8c4d
--- /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 84e6ac8..9f86024 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 6324ae7..ddb8bae 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 5ba19cd..0000000
--- 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
diff --git a/tests/test-1.c b/tests/test-1.c
index 86c7c97..318fd6e 100644
--- a/tests/test-1.c
+++ b/tests/test-1.c
@@ -27,7 +27,7 @@ main (int argc, char **argv)
for (i = 0; i < THREADS; i ++)
{
- mutex[i] = PTHREAD_MUTEX_INITIALIZER;
+ pthread_mutex_init (&mutex[i], 0);
pthread_mutex_lock (&mutex[i]);
err = pthread_create (&tid[i], 0, foo, &mutex[i]);
if (err)