summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Tymoshenko <gonzo@FreeBSD.org>2012-02-10 06:53:25 +0000
committerOleksandr Tymoshenko <gonzo@FreeBSD.org>2012-02-10 06:53:25 +0000
commitdda3ee8770f901ad88f55e91870b2086f2ae18c0 (patch)
tree8b07a4e1594bf787a97927beef89e31bc1c07efa
parentf44d97bd0c010739b30e62580dfb584a25193386 (diff)
Notes
-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 24139a3a71f1..f7c286a322ce 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 53ac5971da1a..e596edc0e2ec 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);
}