summaryrefslogtreecommitdiffstats
path: root/lib/libkse/arch/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2006-09-01 06:17:16 +0000
committermarcel <marcel@FreeBSD.org>2006-09-01 06:17:16 +0000
commit74d4bf1cd1b717a0749749595c7e627712917b25 (patch)
tree105a39219b21a135e58a6516c92ee11377fa9453 /lib/libkse/arch/ia64
parent1125db32432365e5a7eb9db0a01f04bf7563769c (diff)
downloadFreeBSD-src-74d4bf1cd1b717a0749749595c7e627712917b25.zip
FreeBSD-src-74d4bf1cd1b717a0749749595c7e627712917b25.tar.gz
Implement TLS.
Diffstat (limited to 'lib/libkse/arch/ia64')
-rw-r--r--lib/libkse/arch/ia64/ia64/pthread_md.c33
-rw-r--r--lib/libkse/arch/ia64/include/pthread_md.h20
2 files changed, 29 insertions, 24 deletions
diff --git a/lib/libkse/arch/ia64/ia64/pthread_md.c b/lib/libkse/arch/ia64/ia64/pthread_md.c
index 00e9a40..ba215c8 100644
--- a/lib/libkse/arch/ia64/ia64/pthread_md.c
+++ b/lib/libkse/arch/ia64/ia64/pthread_md.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>
+ * Copyright (c) 2006 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,6 +29,8 @@
#include <stdlib.h>
#include <strings.h>
+
+#include "rtld_tls.h"
#include "pthread_md.h"
/*
@@ -38,19 +41,19 @@ _tcb_ctor(struct pthread *thread, int initial)
{
struct tcb *tcb;
- if ((tcb = malloc(sizeof(struct tcb))) != NULL) {
- bzero(tcb, sizeof(struct tcb));
- tcb->tcb_thread = thread;
- /* Allocate TDV */
- }
+ tcb = _rtld_allocate_tls((initial) ? _tp : NULL,
+ sizeof(struct tcb), 16);
+ if (tcb == NULL)
+ return (NULL);
+ tcb->tcb_thread = thread;
return (tcb);
}
void
_tcb_dtor(struct tcb *tcb)
{
- /* Free TDV */
- free(tcb);
+
+ _rtld_free_tls(tcb, sizeof(struct tcb), 16);
}
struct kcb *
@@ -58,13 +61,15 @@ _kcb_ctor(struct kse *kse)
{
struct kcb *kcb;
- if ((kcb = malloc(sizeof(struct kcb))) != NULL) {
- bzero(kcb, sizeof(struct kcb));
- kcb->kcb_faketcb.tcb_isfake = 1;
- kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL;
- kcb->kcb_curtcb = &kcb->kcb_faketcb;
- kcb->kcb_kse = kse;
- }
+ kcb = malloc(sizeof(struct kcb));
+ if (kcb == NULL)
+ return (NULL);
+ bzero(kcb, sizeof(struct kcb));
+ kcb->kcb_kse = kse;
+ kcb->kcb_faketcb.tcb_isfake = 1;
+ kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL;
+ kcb->kcb_faketcb.tcb_tp.tp_dtv = (void *)-1;
+ kcb->kcb_curtcb = &kcb->kcb_faketcb;
return (kcb);
}
diff --git a/lib/libkse/arch/ia64/include/pthread_md.h b/lib/libkse/arch/ia64/include/pthread_md.h
index 1df5046..0a68f8c 100644
--- a/lib/libkse/arch/ia64/include/pthread_md.h
+++ b/lib/libkse/arch/ia64/include/pthread_md.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2003-2006 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@
#include <ucontext.h>
#define KSE_STACKSIZE 16384
-#define DTV_OFFSET offsetof(struct tcb, tcb_tp.tp_tdv)
+#define DTV_OFFSET offsetof(struct tcb, tcb_tp.tp_dtv)
#define THR_GETCONTEXT(ucp) _ia64_save_context(&(ucp)->uc_mcontext)
#define THR_SETCONTEXT(ucp) PANIC("THR_SETCONTEXT() now in use!\n")
@@ -45,7 +45,6 @@ struct kcb;
struct kse;
struct pthread;
struct tcb;
-struct tdv; /* We don't know what this is yet? */
/*
* tp points to one of these. We define the static TLS as an array
@@ -55,7 +54,7 @@ struct tdv; /* We don't know what this is yet? */
* valid, well-aligned thread pointer.
*/
struct ia64_tp {
- struct tdv *tp_tdv; /* dynamic TLS */
+ void *tp_dtv; /* dynamic thread vector. */
uint64_t _reserved_;
long double tp_tls[0]; /* static TLS */
};
@@ -70,12 +69,13 @@ struct tcb {
struct kcb {
struct kse_mailbox kcb_kmbx;
- struct tcb kcb_faketcb;
- struct tcb *kcb_curtcb;
struct kse *kcb_kse;
+ struct tcb *kcb_curtcb;
+ struct tcb kcb_faketcb;
};
-register struct ia64_tp *_tp __asm("%r13");
+register struct ia64_tp *_tp __asm("r13");
+#define IA64_SET_TP(x) __asm __volatile("mov r13 = %0;;" :: "r"(x))
#define _tcb ((struct tcb*)((char*)(_tp) - offsetof(struct tcb, tcb_tp)))
@@ -92,7 +92,7 @@ static __inline void
_kcb_set(struct kcb *kcb)
{
/* There is no thread yet; use the fake tcb. */
- _tp = &kcb->kcb_faketcb.tcb_tp;
+ IA64_SET_TP(&kcb->kcb_faketcb.tcb_tp);
}
/*
@@ -170,7 +170,7 @@ _tcb_set(struct kcb *kcb, struct tcb *tcb)
tcb = &kcb->kcb_faketcb;
kcb->kcb_curtcb = tcb;
tcb->tcb_curkcb = kcb;
- _tp = &tcb->tcb_tp;
+ IA64_SET_TP(&tcb->tcb_tp);
}
static __inline struct tcb *
@@ -208,7 +208,7 @@ _thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
if (_ia64_save_context(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) {
/* Make the fake tcb the current thread. */
kcb->kcb_curtcb = &kcb->kcb_faketcb;
- _tp = &kcb->kcb_faketcb.tcb_tp;
+ IA64_SET_TP(&kcb->kcb_faketcb.tcb_tp);
_ia64_enter_uts(kcb->kcb_kmbx.km_func, &kcb->kcb_kmbx,
kcb->kcb_kmbx.km_stack.ss_sp,
kcb->kcb_kmbx.km_stack.ss_size);
OpenPOWER on IntegriCloud