Add TLS support for i386 and amd64.

This commit is contained in:
dfr 2004-08-15 16:28:05 +00:00
parent fb318ab4c6
commit e082c758ec
20 changed files with 88 additions and 70 deletions

View File

@ -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));
tcb->tcb_thread = thread;
/* Allocate TDV */
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;
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 *

View File

@ -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 *);

View File

@ -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;
tcb->tcb_thread = thread;
/* XXX - Allocate tdv/tls */
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;
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);
}
/*

View File

@ -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 *);

View File

@ -34,7 +34,7 @@
* The constructors.
*/
struct tcb *
_tcb_ctor(struct pthread *thread)
_tcb_ctor(struct pthread *thread, int initial)
{
struct tcb *tcb;

View File

@ -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 *);

View File

@ -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 *);

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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 *);

View File

@ -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));
tcb->tcb_thread = thread;
/* Allocate TDV */
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;
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 *

View File

@ -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 *);

View File

@ -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;
tcb->tcb_thread = thread;
/* XXX - Allocate tdv/tls */
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;
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);
}
/*

View File

@ -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 *);

View File

@ -34,7 +34,7 @@
* The constructors.
*/
struct tcb *
_tcb_ctor(struct pthread *thread)
_tcb_ctor(struct pthread *thread, int initial)
{
struct tcb *tcb;

View File

@ -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 *);

View File

@ -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 *);

View File

@ -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;

View File

@ -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 {