eliminate use of cached pid from thread structure
authorRich Felker <dalias@aerifal.cx>
Sun, 6 Jul 2014 03:29:55 +0000 (23:29 -0400)
committerRich Felker <dalias@aerifal.cx>
Sun, 6 Jul 2014 03:29:55 +0000 (23:29 -0400)
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.

src/aio/aio_readwrite.c
src/aio/lio_listio.c
src/env/__init_tls.c
src/process/fork.c
src/thread/cancel_impl.c
src/thread/pthread_create.c
src/thread/pthread_kill.c
src/thread/synccall.c

index 0de3d4fb7ec762aaded69a52a8c4da2dfd5620a2..22782265ca65061d97e02ee1068a54753f4dc503 100644 (file)
@@ -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);
index 61d7f20ef06cfab2f932a10b365412b924c216d3..75ed2257fa1dd704857d7a43dd6db1b88900489b 100644 (file)
@@ -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);
index efa072842999c6cbb959cc33a4c3c7587578c821..6cca968505ddc19ae4140126882a48ca76c7f7c2 100644 (file)
@@ -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;
 }
index f8cf21e7ca01d94cd67a2add5bcda4ccaff7af40..43c52bc4c0c8e9d28455611697e686b714ccf23e 100644 (file)
@@ -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;
        }
index 41cf2b8ca34c7d19b39fbe94ac1307744e21d06c..069b27962ac1b56f0e55b693742e7a04d7209690 100644 (file)
@@ -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()
index a7493c1041018e66209818c66ef30b319c89a74a..6415125437a95c8d84312fba45ab10551147dea9 100644 (file)
@@ -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;
index d9a5096a06751781cc3c5d6ac5c923b7cc78d500..acdb1ea6173c27284ed946a63831855908f28f19 100644 (file)
@@ -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;
 }
index a21578dc5745ca8467309755189c6aefb9887aed..c414990445bc65a415db8251118858e50e15f1b9 100644 (file)
@@ -1,5 +1,6 @@
 #include "pthread_impl.h"
 #include <semaphore.h>
+#include <unistd.h>
 
 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;