summaryrefslogtreecommitdiffstats
path: root/lib/libkse
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2004-08-15 16:28:05 +0000
committerdfr <dfr@FreeBSD.org>2004-08-15 16:28:05 +0000
commit4dd05c8c572e558551ca8d6bdb39b3eabc191751 (patch)
tree582fc094cd01bd155a2e8f0db27faf9fded5d15c /lib/libkse
parenteebd52f2bba016b347822a238d57326feab23fc1 (diff)
downloadFreeBSD-src-4dd05c8c572e558551ca8d6bdb39b3eabc191751.zip
FreeBSD-src-4dd05c8c572e558551ca8d6bdb39b3eabc191751.tar.gz
Add TLS support for i386 and amd64.
Diffstat (limited to 'lib/libkse')
-rw-r--r--lib/libkse/arch/amd64/amd64/pthread_md.c20
-rw-r--r--lib/libkse/arch/amd64/include/pthread_md.h6
-rw-r--r--lib/libkse/arch/i386/i386/pthread_md.c30
-rw-r--r--lib/libkse/arch/i386/include/pthread_md.h7
-rw-r--r--lib/libkse/arch/ia64/ia64/pthread_md.c2
-rw-r--r--lib/libkse/arch/ia64/include/pthread_md.h2
-rw-r--r--lib/libkse/arch/sparc64/include/pthread_md.h2
-rw-r--r--lib/libkse/arch/sparc64/sparc64/pthread_md.c2
-rw-r--r--lib/libkse/thread/thr_kern.c2
9 files changed, 41 insertions, 32 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 {
OpenPOWER on IntegriCloud