summaryrefslogtreecommitdiffstats
path: root/lib/libthr
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2012-02-10 06:53:25 +0000
committergonzo <gonzo@FreeBSD.org>2012-02-10 06:53:25 +0000
commitd9d5ba0dafd572b738441863d5cd89852d23da7a (patch)
tree8b07a4e1594bf787a97927beef89e31bc1c07efa /lib/libthr
parent7a50922fdb47a3ceb8b1a11faf7b34c79f47a320 (diff)
downloadFreeBSD-src-d9d5ba0dafd572b738441863d5cd89852d23da7a.zip
FreeBSD-src-d9d5ba0dafd572b738441863d5cd89852d23da7a.tar.gz
Switch MIPS TLS implementation to Variant I:
Save pointer to the TLS structure taking into account TP_OFFSET and TCB structure size.
Diffstat (limited to 'lib/libthr')
-rw-r--r--lib/libthr/arch/mips/include/pthread_md.h20
-rw-r--r--lib/libthr/arch/mips/mips/pthread_md.c13
2 files changed, 20 insertions, 13 deletions
diff --git a/lib/libthr/arch/mips/include/pthread_md.h b/lib/libthr/arch/mips/include/pthread_md.h
index 24139a3..f7c286a 100644
--- a/lib/libthr/arch/mips/include/pthread_md.h
+++ b/lib/libthr/arch/mips/include/pthread_md.h
@@ -39,15 +39,19 @@
#define CPU_SPINWAIT
#define DTV_OFFSET offsetof(struct tcb, tcb_dtv)
+#ifdef __mips_n64
+#define TP_OFFSET 0x7010
+#else
+#define TP_OFFSET 0x7008
+#endif
/*
- * Variant II tcb, first two members are required by rtld.
+ * Variant I tcb. The structure layout is fixed, don't blindly
+ * change it!
*/
struct tcb {
- struct tcb *tcb_self; /* required by rtld */
- void *tcb_dtv; /* required by rtld */
- struct pthread *tcb_thread; /* our hook */
- void *tcb_spare[1];
+ void *tcb_dtv;
+ struct pthread *tcb_thread;
};
/*
@@ -61,7 +65,7 @@ static __inline void
_tcb_set(struct tcb *tcb)
{
- sysarch(MIPS_SET_TLS, tcb);
+ sysarch(MIPS_SET_TLS, ((uint8_t*)tcb + TP_OFFSET));
}
/*
@@ -70,10 +74,10 @@ _tcb_set(struct tcb *tcb)
static __inline struct tcb *
_tcb_get(void)
{
- void *tcb;
+ uint8_t *tcb;
sysarch(MIPS_GET_TLS, &tcb);
- return tcb;
+ return ((struct tcb *)(tcb - TP_OFFSET));
}
extern struct pthread *_thr_initial;
diff --git a/lib/libthr/arch/mips/mips/pthread_md.c b/lib/libthr/arch/mips/mips/pthread_md.c
index 53ac597..e596edc 100644
--- a/lib/libthr/arch/mips/mips/pthread_md.c
+++ b/lib/libthr/arch/mips/mips/pthread_md.c
@@ -34,6 +34,8 @@ __FBSDID("$FreeBSD$");
#include <rtld_tls.h>
#include <strings.h>
+#include <machine/sysarch.h>
+
#include "pthread_md.h"
struct tcb *
@@ -41,16 +43,17 @@ _tcb_ctor(struct pthread *thread, int initial)
{
struct tcb *tcb;
- tcb = malloc(sizeof(struct tcb));
- if (tcb) {
- bzero(tcb, sizeof(struct tcb));
+ tcb = _rtld_allocate_tls((initial) ? _tcb_get() : NULL,
+ sizeof(struct tcb), 16);
+ if (tcb)
tcb->tcb_thread = thread;
- }
+
return (tcb);
}
void
_tcb_dtor(struct tcb *tcb)
{
- free(tcb);
+
+ _rtld_free_tls(tcb, sizeof(struct tcb), 16);
}
OpenPOWER on IntegriCloud