summaryrefslogtreecommitdiff
path: root/lib/librthread/rthread.c
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2015-11-10 04:31:00 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2015-11-10 04:31:00 +0000
commitf4c862a2e72bfacff5dcfbc873e4d27a4d848b02 (patch)
tree55ce8d828a416a6311793064b0650abf78062d59 /lib/librthread/rthread.c
parent2de40dc0593bdf96a17ccf05b725d8b4260ec0e1 (diff)
Split the intra-thread functionality from kill(2) into its own syscall
thrkill(2), rolling the kill(2) syscall number with the ABI change to avoid breaking binaries during during the transition. thrkill(2) includes a 'tcb' argument that eliminates the need for locking in pthread_kill() and simplifies pthread_cancel(). Switch __stack_smash_handler() to use thrkill(2) and explicitly unblock SIGABRT. Minor bump to both libc and libpthread: make sure you install a new kernel! ok semarie@
Diffstat (limited to 'lib/librthread/rthread.c')
-rw-r--r--lib/librthread/rthread.c48
1 files changed, 11 insertions, 37 deletions
diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c
index 3d8f0e642cc..5a30a608fbb 100644
--- a/lib/librthread/rthread.c
+++ b/lib/librthread/rthread.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread.c,v 1.86 2015/11/01 03:52:17 guenther Exp $ */
+/* $OpenBSD: rthread.c,v 1.87 2015/11/10 04:30:59 guenther Exp $ */
/*
* Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -283,7 +283,7 @@ restart:
_rthread_debug(3, "rthread reaping %p stack %p\n",
(void *)thread, (void *)thread->stack);
_rthread_free_stack(thread->stack);
- _rtld_free_tls(thread->arg,
+ _rtld_free_tls(thread->tcb,
sizeof(struct thread_control_block), sizeof(void *));
free(thread);
goto restart;
@@ -320,11 +320,6 @@ pthread_exit(void *retval)
LIST_REMOVE(thread, threads);
_spinunlock(&_thread_lock);
-#ifdef TCB_GET
- thread->arg = TCB_GET();
-#else
- thread->arg = __get_tcb();
-#endif
_spinlock(&thread->flags_lock);
if (thread->flags & THREAD_DETACHED) {
_spinunlock(&thread->flags_lock);
@@ -440,6 +435,7 @@ pthread_create(pthread_t *threadp, const pthread_attr_t *attr,
goto fail2;
}
TCB_INIT(tcb, thread, &thread->myerrno);
+ thread->tcb = tcb;
param.tf_tcb = tcb;
param.tf_tid = &thread->tid;
@@ -475,27 +471,11 @@ fail1:
int
pthread_kill(pthread_t thread, int sig)
{
- pid_t tid;
- int ret;
-
- /* killing myself? do it without locking */
- if (thread == TCB_THREAD())
- return (kill(thread->tid, sig) == 0 ? 0 : errno);
-
- /* block the other thread from exiting */
- _spinlock(&thread->flags_lock);
- if (thread->flags & THREAD_DYING)
- ret = (thread->flags & THREAD_DETACHED) ? ESRCH : 0;
- else {
- tid = thread->tid;
- if (tid == 0) {
- /* should be impossible without DYING being set */
- ret = ESRCH;
- } else
- ret = kill(tid, sig) == 0 ? 0 : errno;
- }
- _spinunlock(&thread->flags_lock);
- return (ret);
+ if (sig == SIGTHR)
+ return (EINVAL);
+ if (_thread_sys_thrkill(thread->tid, sig, thread->tcb))
+ return (errno);
+ return (0);
}
int
@@ -516,15 +496,9 @@ pthread_cancel(pthread_t thread)
thread->flags |= THREAD_CANCELED;
if (thread->flags & THREAD_CANCEL_ENABLE) {
-
- /* canceling myself? release the lock first */
- if (thread == TCB_THREAD()) {
- _spinunlock(&thread->flags_lock);
- kill(tid, SIGTHR);
- return (0);
- }
-
- kill(tid, SIGTHR);
+ _spinunlock(&thread->flags_lock);
+ _thread_sys_thrkill(tid, SIGTHR, thread->tcb);
+ return (0);
}
}
_spinunlock(&thread->flags_lock);