ensure that thread dtv pointer is never null to optimize __tls_get_addr
authorRich Felker <dalias@aerifal.cx>
Mon, 3 Jun 2013 20:35:59 +0000 (16:35 -0400)
committerRich Felker <dalias@aerifal.cx>
Mon, 3 Jun 2013 20:35:59 +0000 (16:35 -0400)
src/ldso/dynlink.c
src/thread/pthread_self.c

index dec9511125fcf40e37d71b3e836c8c84c0396a47..ee5ec302bc2acb0d020bfbf7495e56022fe725bf 100644 (file)
@@ -740,13 +740,13 @@ void *__copy_tls(unsigned char *mem)
 void *__tls_get_addr(size_t *v)
 {
        pthread_t self = __pthread_self();
-       if (self->dtv && v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]])
+       if (v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]])
                return (char *)self->dtv[v[0]]+v[1];
 
        /* Block signals to make accessing new TLS async-signal-safe */
        sigset_t set;
        pthread_sigmask(SIG_BLOCK, SIGALL_SET, &set);
-       if (self->dtv && v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]]) {
+       if (v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]]) {
                pthread_sigmask(SIG_SETMASK, &set, 0);
                return (char *)self->dtv[v[0]]+v[1];
        }
@@ -759,10 +759,10 @@ void *__tls_get_addr(size_t *v)
        for (p=head; p->tls_id != v[0]; p=p->next);
 
        /* Get new DTV space from new DSO if needed */
-       if (!self->dtv || v[0] > (size_t)self->dtv[0]) {
+       if (v[0] > (size_t)self->dtv[0]) {
                void **newdtv = p->new_dtv +
                        (v[0]+1)*sizeof(void *)*a_fetch_add(&p->new_dtv_idx,1);
-               if (self->dtv) memcpy(newdtv, self->dtv,
+               memcpy(newdtv, self->dtv,
                        ((size_t)self->dtv[0]+1) * sizeof(void *));
                newdtv[0] = (void *)v[0];
                self->dtv = newdtv;
index c50a2fb5e154947dfae4e728ea3a211fa26e3f9d..aed4b5f1ba1a759394c2913d025df4048c2e2908 100644 (file)
@@ -17,6 +17,8 @@ static int init_main_thread()
        main_thread->self = main_thread;
        main_thread->tid = main_thread->pid =
                __syscall(SYS_set_tid_address, &main_thread->tid);
+       if (!main_thread->dtv)
+               main_thread->dtv = (void *)dummy;
        libc.main_thread = main_thread;
        return 0;
 }