From 9dfca48522ca3e5e23cf198113e26f9faf79f17c Mon Sep 17 00:00:00 2001 From: marcel Date: Fri, 1 Sep 2006 21:25:22 +0000 Subject: Stylize: o avoid using a global register variable. o redefine struct ia64_tp as a union. We don't have to get to the fields themselves. We just need it to be of the right size with the right alignment. --- lib/libkse/arch/ia64/ia64/pthread_md.c | 4 +- lib/libkse/arch/ia64/include/pthread_md.h | 82 ++++++++++++++++++------------- 2 files changed, 51 insertions(+), 35 deletions(-) (limited to 'lib/libkse/arch/ia64') diff --git a/lib/libkse/arch/ia64/ia64/pthread_md.c b/lib/libkse/arch/ia64/ia64/pthread_md.c index ba215c8..dc59b0e 100644 --- a/lib/libkse/arch/ia64/ia64/pthread_md.c +++ b/lib/libkse/arch/ia64/ia64/pthread_md.c @@ -39,9 +39,10 @@ struct tcb * _tcb_ctor(struct pthread *thread, int initial) { + register char *tp __asm("%r13"); struct tcb *tcb; - tcb = _rtld_allocate_tls((initial) ? _tp : NULL, + tcb = _rtld_allocate_tls((initial) ? tp : NULL, sizeof(struct tcb), 16); if (tcb == NULL) return (NULL); @@ -68,7 +69,6 @@ _kcb_ctor(struct kse *kse) 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 0a68f8c..c5fef18 100644 --- a/lib/libkse/arch/ia64/include/pthread_md.h +++ b/lib/libkse/arch/ia64/include/pthread_md.h @@ -47,16 +47,14 @@ struct pthread; struct tcb; /* - * tp points to one of these. We define the static TLS as an array - * of long double to enforce 16-byte alignment of the TLS memory, - * struct ia64_tp, struct tcb and also struct kcb. Both static and - * dynamic allocation of any of these structures will result in a - * valid, well-aligned thread pointer. + * tp points to one of these. We define the TLS structure as a union + * containing a long double to enforce 16-byte alignment. This makes + * sure that there will not be any padding in struct tcb after the + * TLS structure. */ -struct ia64_tp { - void *tp_dtv; /* dynamic thread vector. */ - uint64_t _reserved_; - long double tp_tls[0]; /* static TLS */ +union ia64_tp { + void *tp_dtv; + long double _align_; }; struct tcb { @@ -64,7 +62,7 @@ struct tcb { struct pthread *tcb_thread; struct kcb *tcb_curkcb; long tcb_isfake; - struct ia64_tp tcb_tp; + union ia64_tp tcb_tp; }; struct kcb { @@ -74,10 +72,21 @@ struct kcb { struct tcb kcb_faketcb; }; -register struct ia64_tp *_tp __asm("r13"); -#define IA64_SET_TP(x) __asm __volatile("mov r13 = %0;;" :: "r"(x)) +static __inline struct tcb * +ia64_get_tcb() +{ + register char *tp __asm("%r13"); -#define _tcb ((struct tcb*)((char*)(_tp) - offsetof(struct tcb, tcb_tp))) + return ((struct tcb *)(tp - offsetof(struct tcb, tcb_tp))); +} + +static __inline void +ia64_set_tcb(struct tcb *tcb) +{ + register char *tp __asm("%r13"); + + __asm __volatile("mov %0 = %1;;" : "=r"(tp) : "r"(&tcb->tcb_tp)); +} /* * The kcb and tcb constructors. @@ -92,7 +101,7 @@ static __inline void _kcb_set(struct kcb *kcb) { /* There is no thread yet; use the fake tcb. */ - IA64_SET_TP(&kcb->kcb_faketcb.tcb_tp); + ia64_set_tcb(&kcb->kcb_faketcb); } /* @@ -104,7 +113,7 @@ _kcb_set(struct kcb *kcb) static __inline struct kcb * _kcb_get(void) { - return (_tcb->tcb_curkcb); + return (ia64_get_tcb()->tcb_curkcb); } /* @@ -115,21 +124,23 @@ _kcb_get(void) static __inline struct kse_thr_mailbox * _kcb_critical_enter(void) { + struct tcb *tcb; struct kse_thr_mailbox *crit; uint32_t flags; - if (_tcb->tcb_isfake != 0) { + tcb = ia64_get_tcb(); + if (tcb->tcb_isfake != 0) { /* * We already are in a critical region since * there is no current thread. */ crit = NULL; } else { - flags = _tcb->tcb_tmbx.tm_flags; - _tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; - crit = _tcb->tcb_curkcb->kcb_kmbx.km_curthread; - _tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL; - _tcb->tcb_tmbx.tm_flags = flags; + flags = tcb->tcb_tmbx.tm_flags; + tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; + crit = tcb->tcb_curkcb->kcb_kmbx.km_curthread; + tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL; + tcb->tcb_tmbx.tm_flags = flags; } return (crit); } @@ -137,28 +148,33 @@ _kcb_critical_enter(void) static __inline void _kcb_critical_leave(struct kse_thr_mailbox *crit) { + struct tcb *tcb; + + tcb = ia64_get_tcb(); /* No need to do anything if this is a fake tcb. */ - if (_tcb->tcb_isfake == 0) - _tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit; + if (tcb->tcb_isfake == 0) + tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit; } static __inline int _kcb_in_critical(void) { + struct tcb *tcb; uint32_t flags; int ret; - if (_tcb->tcb_isfake != 0) { + tcb = ia64_get_tcb(); + if (tcb->tcb_isfake != 0) { /* * We are in a critical region since there is no * current thread. */ ret = 1; } else { - flags = _tcb->tcb_tmbx.tm_flags; - _tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; - ret = (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL); - _tcb->tcb_tmbx.tm_flags = flags; + flags = tcb->tcb_tmbx.tm_flags; + tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; + ret = (tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL); + tcb->tcb_tmbx.tm_flags = flags; } return (ret); } @@ -170,19 +186,19 @@ _tcb_set(struct kcb *kcb, struct tcb *tcb) tcb = &kcb->kcb_faketcb; kcb->kcb_curtcb = tcb; tcb->tcb_curkcb = kcb; - IA64_SET_TP(&tcb->tcb_tp); + ia64_set_tcb(tcb); } static __inline struct tcb * _tcb_get(void) { - return (_tcb); + return (ia64_get_tcb()); } static __inline struct pthread * _get_curthread(void) { - return (_tcb->tcb_thread); + return (ia64_get_tcb()->tcb_thread); } /* @@ -193,7 +209,7 @@ _get_curthread(void) static __inline struct kse * _get_curkse(void) { - return (_tcb->tcb_curkcb->kcb_kse); + return (ia64_get_tcb()->tcb_curkcb->kcb_kse); } void _ia64_break_setcontext(mcontext_t *mc); @@ -208,7 +224,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; - IA64_SET_TP(&kcb->kcb_faketcb.tcb_tp); + ia64_set_tcb(&kcb->kcb_faketcb); _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); -- cgit v1.1