diff options
Diffstat (limited to 'lib')
20 files changed, 84 insertions, 66 deletions
diff --git a/lib/libkse/arch/amd64/amd64/pthread_md.c b/lib/libkse/arch/amd64/amd64/pthread_md.c index ead259a..67d4943 100644 --- a/lib/libkse/arch/amd64/amd64/pthread_md.c +++ b/lib/libkse/arch/amd64/amd64/pthread_md.c @@ -28,29 +28,37 @@ #include <stdlib.h> #include <strings.h> +#include "rtld_tls.h" #include "pthread_md.h" /* * The constructors. */ struct tcb * -_tcb_ctor(struct pthread *thread) +_tcb_ctor(struct pthread *thread, int initial) { struct tcb *tcb; + void *oldtls; - if ((tcb = malloc(sizeof(struct tcb))) != NULL) { - bzero(tcb, sizeof(struct tcb)); + if (initial) { + __asm __volatile("movq %%fs:0, %0" : "=r" (oldtls)); + } else { + oldtls = NULL; + } + + tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16); + if (tcb) { tcb->tcb_thread = thread; - /* Allocate TDV */ + bzero(&tcb->tcb_tmbx, sizeof(tcb->tcb_tmbx)); } + return (tcb); } void _tcb_dtor(struct tcb *tcb) { - /* Free TDV */ - free(tcb); + _rtld_free_tls(tcb, sizeof(struct tcb), 16); } struct kcb * diff --git a/lib/libkse/arch/amd64/include/pthread_md.h b/lib/libkse/arch/amd64/include/pthread_md.h index 0f19044..86af4af 100644 --- a/lib/libkse/arch/amd64/include/pthread_md.h +++ b/lib/libkse/arch/amd64/include/pthread_md.h @@ -62,8 +62,10 @@ struct kcb { }; struct tcb { - struct tdv *tcb_tdv; + struct tcb *tcb_self; /* required by rtld */ + void *tcb_dtv; /* required by rtld */ struct pthread *tcb_thread; + void *tcb_spare[1]; /* align tcb_tmbx to 16 bytes */ struct kse_thr_mailbox tcb_tmbx; }; @@ -138,7 +140,7 @@ __kcb_readandclear64(volatile u_long *addr) /* * The constructors. */ -struct tcb *_tcb_ctor(struct pthread *); +struct tcb *_tcb_ctor(struct pthread *, int); void _tcb_dtor(struct tcb *tcb); struct kcb *_kcb_ctor(struct kse *); void _kcb_dtor(struct kcb *); diff --git a/lib/libkse/arch/i386/i386/pthread_md.c b/lib/libkse/arch/i386/i386/pthread_md.c index d94cd7f..3d9bd36 100644 --- a/lib/libkse/arch/i386/i386/pthread_md.c +++ b/lib/libkse/arch/i386/i386/pthread_md.c @@ -39,35 +39,35 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <ucontext.h> +#include "rtld_tls.h" #include "pthread_md.h" struct tcb * -_tcb_ctor(struct pthread *thread) +_tcb_ctor(struct pthread *thread, int initial) { struct tcb *tcb; - void *addr; + void *oldtls; - addr = malloc(sizeof(struct tcb) + 15); - if (addr == NULL) - tcb = NULL; - else { - tcb = (struct tcb *)(((uintptr_t)(addr) + 15) & ~15); - bzero(tcb, sizeof(struct tcb)); - tcb->tcb_addr = addr; + if (initial) { + __asm __volatile("movl %%gs:0, %0" : "=r" (oldtls)); + } else { + oldtls = NULL; + } + + tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16); + if (tcb) { tcb->tcb_thread = thread; - /* XXX - Allocate tdv/tls */ + tcb->tcb_spare = 0; + bzero(&tcb->tcb_tmbx, sizeof(tcb->tcb_tmbx)); } + return (tcb); } void _tcb_dtor(struct tcb *tcb) { - void *addr; - - addr = tcb->tcb_addr; - tcb->tcb_addr = NULL; - free(addr); + _rtld_free_tls(tcb, sizeof(struct tcb), 16); } /* diff --git a/lib/libkse/arch/i386/include/pthread_md.h b/lib/libkse/arch/i386/include/pthread_md.h index 28eefc1..2d4b0e0 100644 --- a/lib/libkse/arch/i386/include/pthread_md.h +++ b/lib/libkse/arch/i386/include/pthread_md.h @@ -47,7 +47,6 @@ extern int _thr_getcontext(mcontext_t *); struct kse; struct pthread; -struct tdv; /* * %gs points to a struct kcb. @@ -61,9 +60,9 @@ struct kcb { }; struct tcb { - struct tdv *tcb_tdv; + struct tcb *tcb_self; /* required by rtld */ + void *tcb_dtv; /* required by rtld */ struct pthread *tcb_thread; - void *tcb_addr; /* allocated tcb address */ void *tcb_spare; /* align tcb_tmbx to 16 bytes */ struct kse_thr_mailbox tcb_tmbx; }; @@ -140,7 +139,7 @@ __kcb_readandclear32(volatile u_long *addr) /* * The constructors. */ -struct tcb *_tcb_ctor(struct pthread *); +struct tcb *_tcb_ctor(struct pthread *, int); void _tcb_dtor(struct tcb *tcb); struct kcb *_kcb_ctor(struct kse *); void _kcb_dtor(struct kcb *); diff --git a/lib/libkse/arch/ia64/ia64/pthread_md.c b/lib/libkse/arch/ia64/ia64/pthread_md.c index c761185..00e9a40 100644 --- a/lib/libkse/arch/ia64/ia64/pthread_md.c +++ b/lib/libkse/arch/ia64/ia64/pthread_md.c @@ -34,7 +34,7 @@ * The constructors. */ struct tcb * -_tcb_ctor(struct pthread *thread) +_tcb_ctor(struct pthread *thread, int initial) { struct tcb *tcb; diff --git a/lib/libkse/arch/ia64/include/pthread_md.h b/lib/libkse/arch/ia64/include/pthread_md.h index b37a328..264909c 100644 --- a/lib/libkse/arch/ia64/include/pthread_md.h +++ b/lib/libkse/arch/ia64/include/pthread_md.h @@ -81,7 +81,7 @@ register struct ia64_tp *_tp __asm("%r13"); /* * The kcb and tcb constructors. */ -struct tcb *_tcb_ctor(struct pthread *); +struct tcb *_tcb_ctor(struct pthread *, int); void _tcb_dtor(struct tcb *); struct kcb *_kcb_ctor(struct kse *kse); void _kcb_dtor(struct kcb *); diff --git a/lib/libkse/arch/sparc64/include/pthread_md.h b/lib/libkse/arch/sparc64/include/pthread_md.h index b180e0a..4700d73 100644 --- a/lib/libkse/arch/sparc64/include/pthread_md.h +++ b/lib/libkse/arch/sparc64/include/pthread_md.h @@ -91,7 +91,7 @@ register struct sparc64_tp *_tp __asm("%g6"); /* * The kcb and tcb constructors. */ -struct tcb *_tcb_ctor(struct pthread *); +struct tcb *_tcb_ctor(struct pthread *, int); void _tcb_dtor(struct tcb *); struct kcb *_kcb_ctor(struct kse *kse); void _kcb_dtor(struct kcb *); diff --git a/lib/libkse/arch/sparc64/sparc64/pthread_md.c b/lib/libkse/arch/sparc64/sparc64/pthread_md.c index b012651..d6bf95d 100644 --- a/lib/libkse/arch/sparc64/sparc64/pthread_md.c +++ b/lib/libkse/arch/sparc64/sparc64/pthread_md.c @@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$"); #include "pthread_md.h" struct tcb * -_tcb_ctor(struct pthread *thread) +_tcb_ctor(struct pthread *thread, int initial) { struct tcb *tcb; void *addr; diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c index 926ca4b..ac8bf5a 100644 --- a/lib/libkse/thread/thr_kern.c +++ b/lib/libkse/thread/thr_kern.c @@ -2382,7 +2382,7 @@ _thr_alloc(struct pthread *curthread) if ((thread == NULL) && ((thread = malloc(sizeof(struct pthread))) != NULL)) { bzero(thread, sizeof(struct pthread)); - if ((thread->tcb = _tcb_ctor(thread)) == NULL) { + if ((thread->tcb = _tcb_ctor(thread, curthread == NULL)) == NULL) { free(thread); thread = NULL; } else { diff --git a/lib/libpthread/arch/alpha/alpha/pthread_md.c b/lib/libpthread/arch/alpha/alpha/pthread_md.c index f5ae2e2..c8445b1 100644 --- a/lib/libpthread/arch/alpha/alpha/pthread_md.c +++ b/lib/libpthread/arch/alpha/alpha/pthread_md.c @@ -35,7 +35,7 @@ __FBSDID("$FreeBSD$"); * The constructors. */ struct tcb * -_tcb_ctor(struct pthread *thread) +_tcb_ctor(struct pthread *thread, int initial) { struct tcb *tcb; diff --git a/lib/libpthread/arch/alpha/include/pthread_md.h b/lib/libpthread/arch/alpha/include/pthread_md.h index f4702e0..5266a6d 100644 --- a/lib/libpthread/arch/alpha/include/pthread_md.h +++ b/lib/libpthread/arch/alpha/include/pthread_md.h @@ -80,7 +80,7 @@ struct kcb { /* * The kcb and tcb constructors. */ -struct tcb *_tcb_ctor(struct pthread *); +struct tcb *_tcb_ctor(struct pthread *, int); void _tcb_dtor(struct tcb *); struct kcb *_kcb_ctor(struct kse *kse); void _kcb_dtor(struct kcb *); diff --git a/lib/libpthread/arch/amd64/amd64/pthread_md.c b/lib/libpthread/arch/amd64/amd64/pthread_md.c index ead259a..67d4943 100644 --- a/lib/libpthread/arch/amd64/amd64/pthread_md.c +++ b/lib/libpthread/arch/amd64/amd64/pthread_md.c @@ -28,29 +28,37 @@ #include <stdlib.h> #include <strings.h> +#include "rtld_tls.h" #include "pthread_md.h" /* * The constructors. */ struct tcb * -_tcb_ctor(struct pthread *thread) +_tcb_ctor(struct pthread *thread, int initial) { struct tcb *tcb; + void *oldtls; - if ((tcb = malloc(sizeof(struct tcb))) != NULL) { - bzero(tcb, sizeof(struct tcb)); + if (initial) { + __asm __volatile("movq %%fs:0, %0" : "=r" (oldtls)); + } else { + oldtls = NULL; + } + + tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16); + if (tcb) { tcb->tcb_thread = thread; - /* Allocate TDV */ + bzero(&tcb->tcb_tmbx, sizeof(tcb->tcb_tmbx)); } + return (tcb); } void _tcb_dtor(struct tcb *tcb) { - /* Free TDV */ - free(tcb); + _rtld_free_tls(tcb, sizeof(struct tcb), 16); } struct kcb * diff --git a/lib/libpthread/arch/amd64/include/pthread_md.h b/lib/libpthread/arch/amd64/include/pthread_md.h index 0f19044..86af4af 100644 --- a/lib/libpthread/arch/amd64/include/pthread_md.h +++ b/lib/libpthread/arch/amd64/include/pthread_md.h @@ -62,8 +62,10 @@ struct kcb { }; struct tcb { - struct tdv *tcb_tdv; + struct tcb *tcb_self; /* required by rtld */ + void *tcb_dtv; /* required by rtld */ struct pthread *tcb_thread; + void *tcb_spare[1]; /* align tcb_tmbx to 16 bytes */ struct kse_thr_mailbox tcb_tmbx; }; @@ -138,7 +140,7 @@ __kcb_readandclear64(volatile u_long *addr) /* * The constructors. */ -struct tcb *_tcb_ctor(struct pthread *); +struct tcb *_tcb_ctor(struct pthread *, int); void _tcb_dtor(struct tcb *tcb); struct kcb *_kcb_ctor(struct kse *); void _kcb_dtor(struct kcb *); diff --git a/lib/libpthread/arch/i386/i386/pthread_md.c b/lib/libpthread/arch/i386/i386/pthread_md.c index d94cd7f..3d9bd36 100644 --- a/lib/libpthread/arch/i386/i386/pthread_md.c +++ b/lib/libpthread/arch/i386/i386/pthread_md.c @@ -39,35 +39,35 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <ucontext.h> +#include "rtld_tls.h" #include "pthread_md.h" struct tcb * -_tcb_ctor(struct pthread *thread) +_tcb_ctor(struct pthread *thread, int initial) { struct tcb *tcb; - void *addr; + void *oldtls; - addr = malloc(sizeof(struct tcb) + 15); - if (addr == NULL) - tcb = NULL; - else { - tcb = (struct tcb *)(((uintptr_t)(addr) + 15) & ~15); - bzero(tcb, sizeof(struct tcb)); - tcb->tcb_addr = addr; + if (initial) { + __asm __volatile("movl %%gs:0, %0" : "=r" (oldtls)); + } else { + oldtls = NULL; + } + + tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16); + if (tcb) { tcb->tcb_thread = thread; - /* XXX - Allocate tdv/tls */ + tcb->tcb_spare = 0; + bzero(&tcb->tcb_tmbx, sizeof(tcb->tcb_tmbx)); } + return (tcb); } void _tcb_dtor(struct tcb *tcb) { - void *addr; - - addr = tcb->tcb_addr; - tcb->tcb_addr = NULL; - free(addr); + _rtld_free_tls(tcb, sizeof(struct tcb), 16); } /* diff --git a/lib/libpthread/arch/i386/include/pthread_md.h b/lib/libpthread/arch/i386/include/pthread_md.h index 28eefc1..2d4b0e0 100644 --- a/lib/libpthread/arch/i386/include/pthread_md.h +++ b/lib/libpthread/arch/i386/include/pthread_md.h @@ -47,7 +47,6 @@ extern int _thr_getcontext(mcontext_t *); struct kse; struct pthread; -struct tdv; /* * %gs points to a struct kcb. @@ -61,9 +60,9 @@ struct kcb { }; struct tcb { - struct tdv *tcb_tdv; + struct tcb *tcb_self; /* required by rtld */ + void *tcb_dtv; /* required by rtld */ struct pthread *tcb_thread; - void *tcb_addr; /* allocated tcb address */ void *tcb_spare; /* align tcb_tmbx to 16 bytes */ struct kse_thr_mailbox tcb_tmbx; }; @@ -140,7 +139,7 @@ __kcb_readandclear32(volatile u_long *addr) /* * The constructors. */ -struct tcb *_tcb_ctor(struct pthread *); +struct tcb *_tcb_ctor(struct pthread *, int); void _tcb_dtor(struct tcb *tcb); struct kcb *_kcb_ctor(struct kse *); void _kcb_dtor(struct kcb *); diff --git a/lib/libpthread/arch/ia64/ia64/pthread_md.c b/lib/libpthread/arch/ia64/ia64/pthread_md.c index c761185..00e9a40 100644 --- a/lib/libpthread/arch/ia64/ia64/pthread_md.c +++ b/lib/libpthread/arch/ia64/ia64/pthread_md.c @@ -34,7 +34,7 @@ * The constructors. */ struct tcb * -_tcb_ctor(struct pthread *thread) +_tcb_ctor(struct pthread *thread, int initial) { struct tcb *tcb; diff --git a/lib/libpthread/arch/ia64/include/pthread_md.h b/lib/libpthread/arch/ia64/include/pthread_md.h index b37a328..264909c 100644 --- a/lib/libpthread/arch/ia64/include/pthread_md.h +++ b/lib/libpthread/arch/ia64/include/pthread_md.h @@ -81,7 +81,7 @@ register struct ia64_tp *_tp __asm("%r13"); /* * The kcb and tcb constructors. */ -struct tcb *_tcb_ctor(struct pthread *); +struct tcb *_tcb_ctor(struct pthread *, int); void _tcb_dtor(struct tcb *); struct kcb *_kcb_ctor(struct kse *kse); void _kcb_dtor(struct kcb *); diff --git a/lib/libpthread/arch/sparc64/include/pthread_md.h b/lib/libpthread/arch/sparc64/include/pthread_md.h index b180e0a..4700d73 100644 --- a/lib/libpthread/arch/sparc64/include/pthread_md.h +++ b/lib/libpthread/arch/sparc64/include/pthread_md.h @@ -91,7 +91,7 @@ register struct sparc64_tp *_tp __asm("%g6"); /* * The kcb and tcb constructors. */ -struct tcb *_tcb_ctor(struct pthread *); +struct tcb *_tcb_ctor(struct pthread *, int); void _tcb_dtor(struct tcb *); struct kcb *_kcb_ctor(struct kse *kse); void _kcb_dtor(struct kcb *); diff --git a/lib/libpthread/arch/sparc64/sparc64/pthread_md.c b/lib/libpthread/arch/sparc64/sparc64/pthread_md.c index b012651..d6bf95d 100644 --- a/lib/libpthread/arch/sparc64/sparc64/pthread_md.c +++ b/lib/libpthread/arch/sparc64/sparc64/pthread_md.c @@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$"); #include "pthread_md.h" struct tcb * -_tcb_ctor(struct pthread *thread) +_tcb_ctor(struct pthread *thread, int initial) { struct tcb *tcb; void *addr; diff --git a/lib/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c index 926ca4b..ac8bf5a 100644 --- a/lib/libpthread/thread/thr_kern.c +++ b/lib/libpthread/thread/thr_kern.c @@ -2382,7 +2382,7 @@ _thr_alloc(struct pthread *curthread) if ((thread == NULL) && ((thread = malloc(sizeof(struct pthread))) != NULL)) { bzero(thread, sizeof(struct pthread)); - if ((thread->tcb = _tcb_ctor(thread)) == NULL) { + if ((thread->tcb = _tcb_ctor(thread, curthread == NULL)) == NULL) { free(thread); thread = NULL; } else { |