From: Rich Felker Date: Sun, 6 Jul 2014 03:29:55 +0000 (-0400) Subject: eliminate use of cached pid from thread structure X-Git-Tag: v1.1.4~60 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=83dc6eb087633abcf5608ad651d3b525ca2ec35e;p=oweals%2Fmusl.git eliminate use of cached pid from thread structure the main motivation for this change is to remove the assumption that the tid of the main thread is also the pid of the process. (the value returned by the set_tid_address syscall was used to fill both fields despite it semantically being the tid.) this is historically and presently true on linux and unlikely to change, but it conceivably could be false on other systems that otherwise reproduce the linux syscall api/abi. only a few parts of the code were actually still using the cached pid. in a couple places (aio and synccall) it was a minor optimization to avoid a syscall. caching could be reintroduced, but lazily as part of the public getpid function rather than at program startup, if it's deemed important for performance later. in other places (cancellation and pthread_kill) the pid was completely unnecessary; the tkill syscall can be used instead of tgkill. this is actually a rather subtle issue, since tgkill is supposedly a solution to race conditions that can affect use of tkill. however, as documented in the commit message for commit 7779dbd2663269b465951189b4f43e70839bc073, tgkill does not actually solve this race; it just limits it to happening within one process rather than between processes. we use a lock that avoids the race in pthread_kill, and the use in the cancellation signal handler is self-targeted and thus not subject to tid reuse races, so both are safe regardless of which syscall (tgkill or tkill) is used. --- diff --git a/src/aio/aio_readwrite.c b/src/aio/aio_readwrite.c index 0de3d4fb..22782265 100644 --- a/src/aio/aio_readwrite.c +++ b/src/aio/aio_readwrite.c @@ -17,7 +17,7 @@ static void notify_signal(struct sigevent *sev) .si_signo = sev->sigev_signo, .si_value = sev->sigev_value, .si_code = SI_ASYNCIO, - .si_pid = __pthread_self()->pid, + .si_pid = getpid(), .si_uid = getuid() }; __syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si); diff --git a/src/aio/lio_listio.c b/src/aio/lio_listio.c index 61d7f20e..75ed2257 100644 --- a/src/aio/lio_listio.c +++ b/src/aio/lio_listio.c @@ -44,7 +44,7 @@ static void notify_signal(struct sigevent *sev) .si_signo = sev->sigev_signo, .si_value = sev->sigev_value, .si_code = SI_ASYNCIO, - .si_pid = __pthread_self()->pid, + .si_pid = getpid(), .si_uid = getuid() }; __syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si); diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c index efa07284..6cca9685 100644 --- a/src/env/__init_tls.c +++ b/src/env/__init_tls.c @@ -15,7 +15,7 @@ int __init_tp(void *p) if (r < 0) return -1; if (!r) libc.can_do_threads = 1; libc.has_thread_pointer = 1; - td->tid = td->pid = __syscall(SYS_set_tid_address, &td->tid); + td->tid = __syscall(SYS_set_tid_address, &td->tid); td->locale = &libc.global_locale; return 0; } diff --git a/src/process/fork.c b/src/process/fork.c index f8cf21e7..43c52bc4 100644 --- a/src/process/fork.c +++ b/src/process/fork.c @@ -24,7 +24,7 @@ pid_t fork(void) #endif if (libc.has_thread_pointer && !ret) { pthread_t self = __pthread_self(); - self->tid = self->pid = __syscall(SYS_getpid); + self->tid = __syscall(SYS_gettid); memset(&self->robust_list, 0, sizeof self->robust_list); libc.threads_minus_1 = 0; } diff --git a/src/thread/cancel_impl.c b/src/thread/cancel_impl.c index 41cf2b8c..069b2796 100644 --- a/src/thread/cancel_impl.c +++ b/src/thread/cancel_impl.c @@ -52,7 +52,7 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx) __cancel(); } - __syscall(SYS_tgkill, self->pid, self->tid, SIGCANCEL); + __syscall(SYS_tkill, self->tid, SIGCANCEL); } void __testcancel() diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index a7493c10..64151254 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -206,7 +206,6 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp new->map_size = size; new->stack = stack; new->stack_size = stack - stack_limit; - new->pid = self->pid; new->start = entry; new->start_arg = arg; new->self = new; diff --git a/src/thread/pthread_kill.c b/src/thread/pthread_kill.c index d9a5096a..acdb1ea6 100644 --- a/src/thread/pthread_kill.c +++ b/src/thread/pthread_kill.c @@ -4,7 +4,7 @@ int pthread_kill(pthread_t t, int sig) { int r; __lock(t->killlock); - r = t->dead ? ESRCH : -__syscall(SYS_tgkill, t->pid, t->tid, sig); + r = t->dead ? ESRCH : -__syscall(SYS_tkill, t->tid, sig); __unlock(t->killlock); return r; } diff --git a/src/thread/synccall.c b/src/thread/synccall.c index a21578dc..c4149904 100644 --- a/src/thread/synccall.c +++ b/src/thread/synccall.c @@ -1,5 +1,6 @@ #include "pthread_impl.h" #include +#include static struct chain { struct chain *next; @@ -13,12 +14,11 @@ static sem_t chainlock, chaindone; static void handler(int sig, siginfo_t *si, void *ctx) { struct chain ch; - pthread_t self = __pthread_self(); int old_errno = errno; if (chainlen == libc.threads_minus_1) return; - sigqueue(self->pid, SIGSYNCCALL, (union sigval){0}); + sigqueue(getpid(), SIGSYNCCALL, (union sigval){0}); sem_init(&ch.sem, 0, 0); sem_init(&ch.sem2, 0, 0); @@ -39,7 +39,6 @@ static void handler(int sig, siginfo_t *si, void *ctx) void __synccall(void (*func)(void *), void *ctx) { - pthread_t self; struct sigaction sa; struct chain *next; sigset_t oldmask; @@ -65,8 +64,7 @@ void __synccall(void (*func)(void *), void *ctx) sigfillset(&sa.sa_mask); __libc_sigaction(SIGSYNCCALL, &sa, 0); - self = __pthread_self(); - sigqueue(self->pid, SIGSYNCCALL, (union sigval){0}); + sigqueue(getpid(), SIGSYNCCALL, (union sigval){0}); while (sem_wait(&chaindone)); sa.sa_flags = 0;