Age | Commit message (Collapse) | Author |
|
This patch solves two issues. The first one is cancellation handling
when a cancellation request is sent before reaching a cancellation
point (namely, pthread_cond_{timed,}wait). Cancellation is implemented
by pushing an appropriate cleanup handler and switching to
PTHREAD_CANCEL_ASYNCHRONOUS type. The main problem is that it doesn't
handle pending requests, only a cancellation that occurs while blocking.
Other problems occur when trying to correctly handle a timeout and a
cancellation request through the cleanup routine.
The other issue is correctly handling timeouts. This problem was already
well known, as explained by the following comment :
"FIXME: What do we do if we get a wakeup message before we disconnect
ourself? It may remain until the next time we block."
In addition, the prevp thread member is inconsistently used. It is
sometimes accessed while protected by the appropriate queue lock to
determine whether a thread is still queued, while at times, threads
are unqueued without holding a lock, as in pthread_cond_broadcast :
/* We can safely walk the list of waiting threads without holding
the lock since it is now decoupled from the condition. */
__pthread_dequeuing_iterate (wakeup, wakeup)
__pthread_wakeup (wakeup);
This is the root cause that triggers some assertion failures.
The solution brought by this patch is to consistently use the prevp link
to determine if both a thread has been unqueued and if a wakeup message
has been sent (both are needed to wake up a thread). A thread unblocked
because of a timeout can now accurately determine if it needs to drain
its message queue. A direct improvement is that the message queue size
can be limited to one message, and wakeups are guaranteed to be
non-blocking, which allows safely calling __pthread_wakeup from critical
sections.
As it now affects the cleanup cancellation routine of
__pthread_cond_timedwait_internal, cancellation is reworked as well.
Cancellation type is forced to PTHREAD_CANCEL_DEFERRED during the call,
and actually checked on both entry and return. A hook is set by the
blocking thread so that the waker doesn't need to know about the call
implementation. Cancellation members are now protected with a mutex for
truely safe access.
* pthread/pt-alloc.c (initialize_pthread): Initialize the new `cancel_lock',
`cancel_hook' and `cancel_hook_args' fields.
* pthread/pt-cancel.c (pthread_cancel): Rework cancellation handling.
* pthread/pt-internal.h (struct __pthread): Add `cancel_lock', `cancel_hook'
and `cancel_hook_args' fields.
(__pthread_dequeue): Assert thread->prevp isn't NULL.
* pthread/pt-join.c (pthread_join): Describe how the cancellation point is
implemented.
* pthread/pt-setcancelstate.c (__pthread_setcancelstate): Lock the given
thread cancellation lock when switching state.
* pthread/pt-setcanceltype.c (__pthread_setcanceltype): Likewise for
cancellation type.
* pthread/pt-testcancel.c (pthread_testcancel): Likewise for pending
cancellations.
* sysdeps/generic/pt-cond-brdcast.c (__pthread_cond_broadcast): Dequeue
and wake up threads with condition locked.
* sysdeps/generic/pt-cond-signal.c (cond_signal): Remove function, move
implementation to ...
(__pthread_cond_signal): ... this function. Remove unused `unblocked'
variable.
* sysdeps/generic/pt-cond-timedwait.c (struct cancel_ctx): New structure.
(cancel_hook): New static function.
(__pthread_cond_timedwait_internal): Fix cancellation and timeout handling.
* sysdeps/generic/pt-mutex-timedlock.c
(__pthread_mutex_timedlock_internal): Fix timeout handling.
* sysdeps/generic/pt-rwlock-timedrdlock.c
(__pthread_rwlock_timedrdlock_internal): Likewise.
* sysdeps/generic/pt-rwlock-timedwrlock.c
(__pthread_rwlock_timedwrlock_internal): Likewise.
* sysdeps/generic/pt-rwlock-unlock.c (pthread_rwlock_unlock): Dequeue and
wake up threads with rwlock internal lock held.
* sysdeps/generic/sem-timedwait.c (__sem_timedwait_internal): Fix timeout
handling.
* sysdeps/mach/hurd/pt-docancel.c (__pthread_do_cancel): Unlock the given
thread cancellation lock.
* sysdeps/mach/pt-thread-alloc.c (create_wakeupmsg): Limit the message
queue size of the wakeup port to 1.
* sysdeps/mach/pt-wakeup.c (__pthread_wakeup): Call __mach_msg in a
non-blocking way.
|
|
To make `__pthread_timedblock' properly measure time using the right
clock, add a new argument representing the clock to use.
* pthread/pt-internal.h (__pthread_timedblock): New argument CLOCK_ID.
* sysdeps/l4/pt-timedblock.c (__pthread_timedblock): Likewise.
* sysdeps/mach/pt-timedblock.c (__pthread_timedblock): Likewise.
* sysdeps/generic/pt-cond-timedwait.c
(__pthread_cond_timedwait_internal): Pass the clock of the
`pthread_cond' to `__pthread_timedblock'.
* sysdeps/generic/pt-mutex-timedlock.c
(__pthread_mutex_timedlock_internal): Pass CLOCK_REALTIME to
`__pthread_timedblock'.
* sysdeps/generic/pt-rwlock-timedrdlock.c
(__pthread_rwlock_timedrdlock_internal): Likewise.
* sysdeps/generic/pt-rwlock-timedwrlock.c
(__pthread_rwlock_timedwrlock_internal): Likewise.
* sysdeps/generic/sem-timedwait.c (__sem_timedwait_internal):
Likewise.
|
|
Merge in Samuel Thibault's changes from the main line.
* Makefile.am (libpthread_a_SOURCES): Add pt-getattr.c.
* headers.m4: Link libpthread/include/pthread/pthreadtypes.h to
sysroot/include/pthread/pthreadtypes.h and
libpthread/sysdeps/${arch}/bits/spin-lock-inline.h. to
sysroot/include/bits/spin-lock-inline.h.
* include/pthread/pthread.h: Include <sys/cdefs.h>.
(__extern_inline): If not defined, define appropriately.
2008-08-04 Samuel Thibault <samuel.thibault@ens-lyon.org>
* include/pthread/pthreadtypes.h (__pthread_inheritsched): Remove
comma at end of enumeration.
2008-08-03 Samuel Thibault <samuel.thibault@ens-lyon.org>
* Makefile (sysdeps_headers): Add spin-lock-inline.h.
(SYSDEP_PATH): Move sysdeps/ia32 right after
sysdeps/$(MICROKERNEL)/ia32.
* include/pthread/pthread.h: Include <bits/spin-lock-inline.h>.
* sysdeps/ia32/bits/spin-lock.h: Move inlines to...
* sysdeps/ia32/bits/spin-lock-inline.h: ... new file.
2008-08-02 Samuel Thibault <samuel.thibault@ens-lyon.org>
* sysdeps/generic/bits/mutex.h: Do not include <errno.h> and
<stddef.h>
* sysdeps/ia32/bits/memory.h (__memory_barrier): Add memory clobber.
* sysdeps/ia32/bits/spin-lock.h (__pthread_spin_trylock,
__pthread_spin_unlock): Add memory clobbers.
* sysdeps/l4/hurd/ia32/pt-setup.c (stack_setup): Fix reservation of
stack room for initial frame.
2008-07-18 Samuel Thibault <samuel.thibault@ens-lyon.org>
* Makefile (sysdeps_headers): add pthread/pthreadtypes.h
2008-06-27 Samuel Thibault <samuel.thibault@ens-lyon.org>
* include/pthread/pthread.h: Do not define __need_clockid_t, include
<time.h>, and define clockid_t if __clockid_defined is not defined.
Include <pthread/pthreadtypes.h>
(pthread_equal): New extern inline.
(pthread_cleanup_push, pthread_cleanup_pop): New macros.
(__pthread_process_shared, __pthread_inheritsched,
__pthread_contentionscope, __pthread_detachstate,
__pthread_mutex_protocol, __pthread_mutex_type,
pthread_attr_t, pthread_mutex_attr_t, pthread_mutex_t,
pthread_condattr_t, pthread_cond_t, pthread_spinlock_t,
pthread_rwlockattr_t, pthread_rwlock_t, pthread_barrierattr_t,
pthread_barrier_t, pthread_key_t, pthread_once_t): Move enums and
typedefs to...
* include/pthread/pthreadtypes.h: ... new file.
* sysdeps/generic/bits/cancelation.h (pthread_cleanup_push): Rename
macro to __pthread_cleanup_push.
(pthread_cleanup_pop): Rename macro to __pthread_cleanup_pop.
* sysdeps/generic/bits/barrier-attr.h (__pthread_process_shared):
Forward-declare enum.
* sysdeps/generic/bits/condition-attr.h (__pthread_process_shared):
Likewise.
* sysdeps/generic/bits/mutex-attr.h (__pthread_mutex_protocol,
__pthread_process_shared, __pthread_mutex_type):
Likewise.
* sysdeps/generic/bits/rwlock-attr.h (__pthread_process_shared):
Likewise.
* sysdeps/generic/bits/thread-attr.h (__pthread_detachstate,
__pthread_inheritsched, __pthread_contentionscope):
Likewise.
* sysdeps/generic/bits/pthread.h (pthread_t): Rename type to
__pthread_t.
(pthread_equal): Rename to __pthread_equal.
2008-06-27 Samuel Thibault <samuel.thibault@ens-lyon.org>
* sysdeps/generic/bits/thread-barrier.h: Remove unused file.
2008-05-17 Samuel Thibault <samuel.thibault@ens-lyon.org>
* include/pthread/pthread.h (pthread_getattr_np): New declaration.
* pthread/pt-getattr.c: New file.
* Makefile (SRCS): Add pt-getattr.c.
2008-03-16 Samuel Thibault <samuel.thibault@ens-lyon.org>
* include/libc-symbols.h (HAVE_ASM_PREVIOUS_DIRECTIVE): Define.
2008-02-29 Samuel Thibault <samuel.thibault@ens-lyon.org>
* sysdeps/l4/hurd/ia32/pt-setup.c (stack_setup): Align stack on 0x10
for MMX operations.
2008-01-01 Samuel Thibault <samuel.thibault@ens-lyon.org>
* include/pthread/pthread.h (pthread_spin_destroy, pthread_spin_init,
pthread_spin_lock, pthread_spin_trylock, pthread_spin_unlock): Use
__extern_inline macro instead of extern __inline.
* sysdeps/ia32/bits/spin-lock.h (__PT_SPIN_INLINE,
__pthread_spin_lock): Likewise
* sysdeps/generic/bits/pthread.h (pthread_equal): Declare ; only
provide inline when __USE_EXTERN_INLINES is defined. Use __extern_inline
macro instead of extern __inline.
* sysdeps/ia32/bits/memory.h (__memory_barrier): Add static to inline.
|
|
* sysdeps/generic/sem-timedwait.c: Don't include <error.h>.
|
|
|
|
Do not let other libraries (like libX11) override libpthread's
pthread_mutex_*, pthread_rwlock_* and sem_* dynamic symbols.
* libpthread/sysdeps/generic/pt-mutex-destroy.c
(pthread_mutex_destroy): Make the alias strong.
* libpthread/sysdeps/generic/pt-mutex-init.c
(pthread_mutex_init): Likewise.
* libpthread/sysdeps/generic/pt-mutex-lock.c
(_pthread_mutex_lock, pthread_mutex_lock): Likewise.
* libpthread/sysdeps/generic/pt-mutex-trylock.c
(_pthread_mutex_trylock, pthread_mutex_trylock): Likewise.
* libpthread/sysdeps/generic/pt-mutex-unlock.c
(_pthread_mutex_lock, pthread_mutex_unlock): Likewise.
* libpthread/sysdeps/generic/pt-rwlock-destroy.c
(pthread_rwlock_destroy): Likewise.
* libpthread/sysdeps/generic/pt-rwlock-init.c
(pthread_rwlock_init): Likewise.
* libpthread/sysdeps/generic/sem-destroy.c (sem_destroy): Likewise.
* libpthread/sysdeps/generic/sem-getvalue.c (sem_getvalue): Likewise.
* libpthread/sysdeps/generic/sem-init.c (sem_init): Likewise.
* libpthread/sysdeps/generic/sem-open.c (sem_open): Likewise.
* libpthread/sysdeps/generic/sem-post.c (sem_post): Likewise.
* libpthread/sysdeps/generic/sem-timedwait.c (sem_timedwait): Likewise.
* libpthread/sysdeps/generic/sem-trywait.c (sem_trywait): Likewise.
* libpthread/sysdeps/generic/sem-unlink.c (sem_unlink): Likewise.
* libpthread/sysdeps/generic/sem-wait.c (sem_wait): Likewise.
|
|
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 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.
|