提交 83dc6eb0 编写于 作者: R Rich Felker

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 7779dbd2, 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.
上级 4c48501e
...@@ -17,7 +17,7 @@ static void notify_signal(struct sigevent *sev) ...@@ -17,7 +17,7 @@ static void notify_signal(struct sigevent *sev)
.si_signo = sev->sigev_signo, .si_signo = sev->sigev_signo,
.si_value = sev->sigev_value, .si_value = sev->sigev_value,
.si_code = SI_ASYNCIO, .si_code = SI_ASYNCIO,
.si_pid = __pthread_self()->pid, .si_pid = getpid(),
.si_uid = getuid() .si_uid = getuid()
}; };
__syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si); __syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si);
......
...@@ -44,7 +44,7 @@ static void notify_signal(struct sigevent *sev) ...@@ -44,7 +44,7 @@ static void notify_signal(struct sigevent *sev)
.si_signo = sev->sigev_signo, .si_signo = sev->sigev_signo,
.si_value = sev->sigev_value, .si_value = sev->sigev_value,
.si_code = SI_ASYNCIO, .si_code = SI_ASYNCIO,
.si_pid = __pthread_self()->pid, .si_pid = getpid(),
.si_uid = getuid() .si_uid = getuid()
}; };
__syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si); __syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si);
......
...@@ -15,7 +15,7 @@ int __init_tp(void *p) ...@@ -15,7 +15,7 @@ int __init_tp(void *p)
if (r < 0) return -1; if (r < 0) return -1;
if (!r) libc.can_do_threads = 1; if (!r) libc.can_do_threads = 1;
libc.has_thread_pointer = 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; td->locale = &libc.global_locale;
return 0; return 0;
} }
......
...@@ -24,7 +24,7 @@ pid_t fork(void) ...@@ -24,7 +24,7 @@ pid_t fork(void)
#endif #endif
if (libc.has_thread_pointer && !ret) { if (libc.has_thread_pointer && !ret) {
pthread_t self = __pthread_self(); 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); memset(&self->robust_list, 0, sizeof self->robust_list);
libc.threads_minus_1 = 0; libc.threads_minus_1 = 0;
} }
......
...@@ -52,7 +52,7 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx) ...@@ -52,7 +52,7 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx)
__cancel(); __cancel();
} }
__syscall(SYS_tgkill, self->pid, self->tid, SIGCANCEL); __syscall(SYS_tkill, self->tid, SIGCANCEL);
} }
void __testcancel() void __testcancel()
......
...@@ -206,7 +206,6 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp ...@@ -206,7 +206,6 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp
new->map_size = size; new->map_size = size;
new->stack = stack; new->stack = stack;
new->stack_size = stack - stack_limit; new->stack_size = stack - stack_limit;
new->pid = self->pid;
new->start = entry; new->start = entry;
new->start_arg = arg; new->start_arg = arg;
new->self = new; new->self = new;
......
...@@ -4,7 +4,7 @@ int pthread_kill(pthread_t t, int sig) ...@@ -4,7 +4,7 @@ int pthread_kill(pthread_t t, int sig)
{ {
int r; int r;
__lock(t->killlock); __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); __unlock(t->killlock);
return r; return r;
} }
#include "pthread_impl.h" #include "pthread_impl.h"
#include <semaphore.h> #include <semaphore.h>
#include <unistd.h>
static struct chain { static struct chain {
struct chain *next; struct chain *next;
...@@ -13,12 +14,11 @@ static sem_t chainlock, chaindone; ...@@ -13,12 +14,11 @@ static sem_t chainlock, chaindone;
static void handler(int sig, siginfo_t *si, void *ctx) static void handler(int sig, siginfo_t *si, void *ctx)
{ {
struct chain ch; struct chain ch;
pthread_t self = __pthread_self();
int old_errno = errno; int old_errno = errno;
if (chainlen == libc.threads_minus_1) return; 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.sem, 0, 0);
sem_init(&ch.sem2, 0, 0); sem_init(&ch.sem2, 0, 0);
...@@ -39,7 +39,6 @@ static void handler(int sig, siginfo_t *si, void *ctx) ...@@ -39,7 +39,6 @@ static void handler(int sig, siginfo_t *si, void *ctx)
void __synccall(void (*func)(void *), void *ctx) void __synccall(void (*func)(void *), void *ctx)
{ {
pthread_t self;
struct sigaction sa; struct sigaction sa;
struct chain *next; struct chain *next;
sigset_t oldmask; sigset_t oldmask;
...@@ -65,8 +64,7 @@ void __synccall(void (*func)(void *), void *ctx) ...@@ -65,8 +64,7 @@ void __synccall(void (*func)(void *), void *ctx)
sigfillset(&sa.sa_mask); sigfillset(&sa.sa_mask);
__libc_sigaction(SIGSYNCCALL, &sa, 0); __libc_sigaction(SIGSYNCCALL, &sa, 0);
self = __pthread_self(); sigqueue(getpid(), SIGSYNCCALL, (union sigval){0});
sigqueue(self->pid, SIGSYNCCALL, (union sigval){0});
while (sem_wait(&chaindone)); while (sem_wait(&chaindone));
sa.sa_flags = 0; sa.sa_flags = 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册